diff --git a/.gitignore b/.gitignore index 4450b38..8569091 100644 --- a/.gitignore +++ b/.gitignore @@ -61,5 +61,6 @@ htmlcov/ skill-seekers-configs/ .claude/skills .mcp.json +!distribution/claude-plugin/.mcp.json settings.json USER_GUIDE.md diff --git a/=0.24.0 b/=0.24.0 deleted file mode 100644 index 83a1f95..0000000 --- a/=0.24.0 +++ /dev/null @@ -1,18 +0,0 @@ -error: externally-managed-environment - -× This environment is externally managed -╰─> To install Python packages system-wide, try 'pacman -S - python-xyz', where xyz is the package you are trying to - install. - - If you wish to install a non-Arch-packaged Python package, - create a virtual environment using 'python -m venv path/to/venv'. - Then use path/to/venv/bin/python and path/to/venv/bin/pip. - - If you wish to install a non-Arch packaged Python application, - it may be easiest to use 'pipx install xyz', which will manage a - virtual environment for you. Make sure you have python-pipx - installed via pacman. - -note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages. -hint: See PEP 668 for the detailed specification. diff --git a/AGENTS.md b/AGENTS.md index d26c952..9f69468 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,18 +1,20 @@ # AGENTS.md - Skill Seekers -Concise reference for AI coding agents. Skill Seekers is a Python CLI tool (v3.2.0) that converts documentation sites, GitHub repos, PDFs, videos, notebooks, wikis, and more into AI-ready skills for 16+ LLM platforms and RAG pipelines. +Concise reference for AI coding agents. Skill Seekers is a Python CLI tool (v3.3.0) that converts documentation sites, GitHub repos, PDFs, videos, notebooks, wikis, and more into AI-ready skills for 16+ LLM platforms and RAG pipelines. ## Setup ```bash -# REQUIRED before running tests (src/ layout — tests fail without this) +# REQUIRED before running tests (src/ layout — tests hard-exit if package not installed) pip install -e . -# With dev tools +# With dev tools (pytest, ruff, mypy, coverage) pip install -e ".[dev]" # With all optional deps pip install -e ".[all]" ``` +Note: `tests/conftest.py` checks that `skill_seekers` is importable and calls `sys.exit(1)` if not. Always install in editable mode first. + ## Build / Test / Lint Commands ```bash @@ -46,8 +48,10 @@ ruff format src/ tests/ mypy src/skill_seekers --show-error-codes --pretty ``` -**Test markers:** `slow`, `integration`, `e2e`, `venv`, `bootstrap`, `benchmark` -**Async tests:** use `@pytest.mark.asyncio`; asyncio_mode is `auto`. +**Pytest config** (from pyproject.toml): `addopts = "-v --tb=short --strict-markers"`, `asyncio_mode = "auto"`, `asyncio_default_fixture_loop_scope = "function"`. +**Test markers:** `slow`, `integration`, `e2e`, `venv`, `bootstrap`, `benchmark`, `asyncio`. +**Async tests:** use `@pytest.mark.asyncio`; asyncio_mode is `auto` so the decorator is often implicit. +**Test count:** 123 test files (107 in `tests/`, 16 in `tests/test_adaptors/`). ## Code Style @@ -61,61 +65,49 @@ mypy src/skill_seekers --show-error-codes --pretty - Sort with isort (via ruff); `skill_seekers` is first-party - Standard library → third-party → first-party, separated by blank lines - Use `from __future__ import annotations` only if needed for forward refs -- Guard optional imports with try/except ImportError (see `adaptors/__init__.py` pattern) +- Guard optional imports with try/except ImportError (see `adaptors/__init__.py` pattern): + ```python + try: + from .claude import ClaudeAdaptor + from .minimax import MiniMaxAdaptor + except ImportError: + ClaudeAdaptor = None + MiniMaxAdaptor = None + ``` ### Naming Conventions -- **Files:** `snake_case.py` -- **Classes:** `PascalCase` (e.g., `SkillAdaptor`, `ClaudeAdaptor`) -- **Functions/methods:** `snake_case` -- **Constants:** `UPPER_CASE` (e.g., `ADAPTORS`, `DEFAULT_CHUNK_TOKENS`) -- **Private:** prefix with `_` +- **Files:** `snake_case.py` (e.g., `source_detector.py`, `config_validator.py`) +- **Classes:** `PascalCase` (e.g., `SkillAdaptor`, `ClaudeAdaptor`, `SourceDetector`) +- **Functions/methods:** `snake_case` (e.g., `get_adaptor()`, `detect_language()`) +- **Constants:** `UPPER_CASE` (e.g., `ADAPTORS`, `DEFAULT_CHUNK_TOKENS`, `VALID_SOURCE_TYPES`) +- **Private:** prefix with `_` (e.g., `_read_existing_content()`, `_validate_unified()`) ### Type Hints - Gradual typing — add hints where practical, not enforced everywhere - Use modern syntax: `str | None` not `Optional[str]`, `list[str]` not `List[str]` - MyPy config: `disallow_untyped_defs = false`, `check_untyped_defs = true`, `ignore_missing_imports = true` +- Tests are excluded from strict type checking (`disallow_untyped_defs = false`, `check_untyped_defs = false` for `tests.*`) ### Docstrings - Module-level docstring on every file (triple-quoted, describes purpose) -- Google-style or standard docstrings for public functions/classes +- Google-style docstrings for public functions/classes - Include `Args:`, `Returns:`, `Raises:` sections where useful ### Error Handling - Use specific exceptions, never bare `except:` -- Provide helpful error messages with context (see `get_adaptor()` in `adaptors/__init__.py`) +- Provide helpful error messages with context - Use `raise ValueError(...)` for invalid arguments, `raise RuntimeError(...)` for state errors - Guard optional dependency imports with try/except and give clear install instructions on failure +- Chain exceptions with `raise ... from e` when wrapping ### Suppressing Lint Warnings - Use inline `# noqa: XXXX` comments (e.g., `# noqa: F401` for re-exports, `# noqa: ARG001` for required but unused params) -## Supported Source Types (17) - -| Type | CLI Command | Config Type | Detection | -|------|------------|-------------|-----------| -| Documentation (web) | `scrape` / `create ` | `documentation` | HTTP/HTTPS URLs | -| GitHub repo | `github` / `create owner/repo` | `github` | `owner/repo` or github.com URLs | -| PDF | `pdf` / `create file.pdf` | `pdf` | `.pdf` extension | -| Word (.docx) | `word` / `create file.docx` | `word` | `.docx` extension | -| EPUB | `epub` / `create file.epub` | `epub` | `.epub` extension | -| Video | `video` / `create ` | `video` | YouTube/Vimeo URLs, video extensions | -| Local codebase | `analyze` / `create ./path` | `local` | Directory paths | -| Jupyter Notebook | `jupyter` / `create file.ipynb` | `jupyter` | `.ipynb` extension | -| Local HTML | `html` / `create file.html` | `html` | `.html`/`.htm` extensions | -| OpenAPI/Swagger | `openapi` / `create spec.yaml` | `openapi` | `.yaml`/`.yml` with OpenAPI content | -| AsciiDoc | `asciidoc` / `create file.adoc` | `asciidoc` | `.adoc`/`.asciidoc` extensions | -| PowerPoint | `pptx` / `create file.pptx` | `pptx` | `.pptx` extension | -| RSS/Atom | `rss` / `create feed.rss` | `rss` | `.rss`/`.atom` extensions | -| Man pages | `manpage` / `create cmd.1` | `manpage` | `.1`-`.8`/`.man` extensions | -| Confluence | `confluence` | `confluence` | API or export directory | -| Notion | `notion` | `notion` | API or export directory | -| Slack/Discord | `chat` | `chat` | Export directory or API | - ## Project Layout ``` src/skill_seekers/ # Main package (src/ layout) - cli/ # CLI commands and entry points + cli/ # CLI commands and entry points (96 files) adaptors/ # Platform adaptors (Strategy pattern, inherit SkillAdaptor) arguments/ # CLI argument definitions (one per source type) parsers/ # Subcommand parsers (one per source type) @@ -127,15 +119,15 @@ src/skill_seekers/ # Main package (src/ layout) unified_scraper.py # Multi-source orchestrator (scraped_data + dispatch) unified_skill_builder.py # Pairwise synthesis + generic merge mcp/ # MCP server (FastMCP + legacy) - tools/ # MCP tool implementations by category + tools/ # MCP tool implementations by category (10 files) sync/ # Sync monitoring (Pydantic models) benchmark/ # Benchmarking framework embedding/ # FastAPI embedding server - workflows/ # 67 YAML workflow presets (includes complex-merge.yaml) + workflows/ # 67 YAML workflow presets _version.py # Reads version from pyproject.toml -tests/ # 115+ test files (pytest) +tests/ # 120 test files (pytest) configs/ # Preset JSON scraping configs -docs/ # 80+ markdown doc files +docs/ # Documentation (guides, integrations, architecture) ``` ## Key Patterns @@ -150,6 +142,8 @@ docs/ # 80+ markdown doc files **CLI subcommands** — git-style in `cli/main.py`. Each delegates to a module's `main()` function. +**Supported source types (17):** documentation (web), github, pdf, word, epub, video, local codebase, jupyter, html, openapi, asciidoc, pptx, rss, manpage, confluence, notion, chat (slack/discord). Each detected automatically by `source_detector.py`. + ## Git Workflow - **`main`** — production, protected @@ -168,4 +162,11 @@ Never commit API keys. Use env vars: `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, `OPE ## CI -GitHub Actions (`.github/workflows/tests.yml`): ruff + mypy lint job, then pytest matrix (Ubuntu + macOS, Python 3.10-3.12) with Codecov upload. +GitHub Actions (7 workflows in `.github/workflows/`): +- **tests.yml** — ruff + mypy lint job, then pytest matrix (Ubuntu + macOS, Python 3.10-3.12) with Codecov upload +- **release.yml** — tag-triggered: tests → version verification → PyPI publish via `uv build` +- **test-vector-dbs.yml** — tests vector DB adaptors (weaviate, chroma, faiss, qdrant) +- **docker-publish.yml** — multi-platform Docker builds (amd64, arm64) for CLI + MCP images +- **quality-metrics.yml** — quality analysis with configurable threshold +- **scheduled-updates.yml** — weekly skill updates for popular frameworks +- **vector-db-export.yml** — weekly vector DB exports diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc7dbe..e6d5fe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [3.4.0] - 2026-03-21 + +### Added +- **OpenCode adaptor** (`--target opencode`) - Directory-based packaging with dual-format YAML frontmatter +- **OpenAI-compatible base class** - Shared base for all OpenAI-compatible LLM platforms +- **6 new LLM platform adaptors**: Kimi (`--target kimi`), DeepSeek (`--target deepseek`), Qwen (`--target qwen`), OpenRouter (`--target openrouter`), Together AI (`--target together`), Fireworks AI (`--target fireworks`) +- **7 new CLI agent install paths**: roo, cline, aider, bolt, kilo, continue, kimi-code (total: 18 agents) +- **OpenCode skill splitter** - Auto-split large docs into focused sub-skills with router +- **Bi-directional skill converter** - Import/export between OpenCode and any platform format +- **Distribution files** for Smithery (`smithery.yaml`), GitHub Actions (`templates/github-actions/update-skills.yml`), and Claude Code Plugin +- **Full UML architecture documentation** — 14 class diagrams synced from source code via StarUML +- **StarUML HTML API reference** documentation export +- **Ecosystem section** in README linking all Skill Seekers repos (PyPI, website, plugin, GitHub Action) + +### Fixed +- **`sanitize_url()` crashes on Python 3.14** due to strict `urlparse` rejecting bracket-containing URLs (#284) +- **Blindly appending `/index.html.md` to non-.md URLs** — now only appends for URLs that should have it (#277) +- **Unified scraper temp config** uses unified format for `doc_scraper` instead of raw args (#317) +- **Unicode arrows in CLI help text** replaced with ASCII for Windows cp1252 compatibility +- **CLI flags in plugin slash commands** corrected (`create` uses `--preset`, `package` uses `--target`) +- **MiniMax adaptor** improvements from PR #318 review (#319) +- **Misleading "Scraped N pages" count** reported visited URLs instead of saved pages — now shows `(N saved, M skipped)` (#320) +- **"No scraped data found" after successful scrape** on JavaScript SPA sites — now warns that site requires JS rendering (#320, #321) + +### Changed +- Refactored MiniMax adaptor to inherit from shared OpenAI-compatible base class +- Platform count: 5 → 12 LLM targets +- Agent count: 11 → 18 install paths +- Consolidated `Docs/` into `docs/` (single documentation directory) +- Removed stale root-level test scripts and junk files +- Removed stale `UNIFIED_PARSERS.md` superseded by UML architecture +- Added architecture references to README.md and CONTRIBUTING.md +- Fixed pre-existing ruff format issues in 5 files + ## [3.3.0] - 2026-03-16 **Theme:** 10 new source types (17 total), EPUB unified integration, sync-config command, performance optimizations, 12 README translations, and 19 bug fixes. 117 files changed, +41,588 lines since v3.2.0. diff --git a/CLAUDE.md b/CLAUDE.md index 3615cf0..b0c1cdf 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,2389 +2,233 @@ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. -## 🎯 Project Overview +## Project Overview -**Skill Seekers** is the **universal documentation preprocessor** for AI systems. It transforms documentation websites, GitHub repositories, PDFs, and EPUBs into production-ready formats for **16+ platforms**: RAG pipelines (LangChain, LlamaIndex, Haystack), vector databases (Pinecone, Chroma, Weaviate, FAISS, Qdrant), AI coding assistants (Cursor, Windsurf, Cline, Continue.dev), and LLM platforms (Claude, Gemini, OpenAI). +**Skill Seekers** converts documentation from 17 source types into production-ready formats for 24+ AI platforms (LLM platforms, RAG frameworks, vector databases, AI coding assistants). Published on PyPI as `skill-seekers`. -**Current Version:** v3.1.3 -**Python Version:** 3.10+ required -**Status:** Production-ready, published on PyPI -**Website:** https://skillseekersweb.com/ - Browse configs, share, and access documentation +**Version:** 3.3.0 | **Python:** 3.10+ | **Website:** https://skillseekersweb.com/ -## 📚 Table of Contents +**Architecture:** See `docs/UML_ARCHITECTURE.md` for UML diagrams and module overview. StarUML project at `docs/UML/skill_seekers.mdj`. -- [First Time Here?](#-first-time-here) - Start here! -- [Quick Commands](#-quick-command-reference-most-used) - Common workflows -- [Architecture](#️-architecture) - How it works -- [Development](#️-development-commands) - Building & testing -- [Testing](#-testing-guidelines) - Test strategy -- [Debugging](#-debugging-tips) - Troubleshooting -- [Contributing](#-where-to-make-changes) - How to add features - -## 👋 First Time Here? - -**Complete this 3-minute setup to start contributing:** +## Essential Commands ```bash -# 1. Install package in editable mode (REQUIRED for development) +# REQUIRED before running tests or CLI (src/ layout) pip install -e . -# 2. Verify installation -python -c "import skill_seekers; print(skill_seekers.__version__)" # Should print: 3.1.0-dev +# Run all tests (NEVER skip - all must pass before commits) +pytest tests/ -v -# 3. Run a quick test -pytest tests/test_scraper_features.py::test_detect_language -v +# Fast iteration (skip slow MCP tests ~20min) +pytest tests/ --ignore=tests/test_mcp_fastmcp.py --ignore=tests/test_mcp_server.py --ignore=tests/test_install_skill_e2e.py -q -# 4. You're ready! Pick a task from the roadmap: -# https://github.com/users/yusufkaraaslan/projects/2 +# Single test +pytest tests/test_scraper_features.py::test_detect_language -vv -s + +# Code quality (must pass before push - matches CI) +uvx ruff check src/ tests/ +uvx ruff format --check src/ tests/ +mypy src/skill_seekers # continue-on-error in CI + +# Auto-fix lint/format issues +uvx ruff check --fix --unsafe-fixes src/ tests/ +uvx ruff format src/ tests/ + +# Build & publish +uv build +uv publish ``` -**Quick Navigation:** -- Building/Testing → [Development Commands](#️-development-commands) -- Architecture → [Core Design Pattern](#️-architecture) -- Common Issues → [Common Pitfalls](#-common-pitfalls--solutions) -- Contributing → See `CONTRIBUTING.md` +## CI Matrix -## ⚡ Quick Command Reference (Most Used) +Runs on push/PR to `main` or `development`. Lint job (Python 3.12, Ubuntu) + Test job (Ubuntu + macOS, Python 3.10/3.11/3.12, excludes macOS+3.10). Both must pass for merge. -**First time setup:** -```bash -pip install -e . # REQUIRED before running tests or CLI +## Git Workflow + +- **Main branch:** `main` (requires tests + 1 review) +- **Development branch:** `development` (default PR target, requires tests) +- **Feature branches:** `feature/{task-id}-{description}` from `development` +- PRs always target `development`, never `main` directly + +## Architecture + +### CLI: Git-style dispatcher + +Entry point `src/skill_seekers/cli/main.py` maps subcommands to modules. The `create` command auto-detects source type and is the recommended entry point for users. + +``` +skill-seekers create # Auto-detect: URL, owner/repo, ./path, file.pdf, etc. +skill-seekers [options] # Direct: scrape, github, pdf, word, epub, video, jupyter, html, openapi, asciidoc, pptx, rss, manpage, confluence, notion, chat +skill-seekers analyze # Analyze local codebase (C3.x pipeline) +skill-seekers package # Package for platform (--target claude/gemini/openai/markdown/minimax/opencode/kimi/deepseek/qwen/openrouter/together/fireworks, --format langchain/llama-index/haystack/chroma/faiss/weaviate/qdrant/pinecone) ``` -**Running tests (NEVER skip - user requirement):** -```bash -pytest tests/ -v # All tests -pytest tests/test_scraper_features.py -v # Single file -pytest tests/ --cov=src/skill_seekers --cov-report=html # With coverage -``` +### Data Flow (5 phases) -**Code quality checks (matches CI):** -```bash -ruff check src/ tests/ # Lint -ruff format src/ tests/ # Format -mypy src/skill_seekers # Type check -``` +1. **Scrape** - Source-specific scraper extracts content to `output/{name}_data/pages/*.json` +2. **Build** - `build_skill()` categorizes pages, extracts patterns, generates `output/{name}/SKILL.md` +3. **Enhance** (optional) - LLM rewrites SKILL.md (`--enhance-level 0-3`, auto-detects API vs LOCAL mode) +4. **Package** - Platform adaptor formats output (`.zip`, `.tar.gz`, JSON, vector index) +5. **Upload** (optional) - Platform API upload -**Common workflows:** -```bash -# NEW unified create command (auto-detects source type) -skill-seekers create https://docs.react.dev/ -p quick -skill-seekers create facebook/react -p standard -skill-seekers create ./my-project -p comprehensive -skill-seekers create tutorial.pdf +### Platform Adaptor Pattern (Strategy + Factory) -# Legacy commands (still supported) -skill-seekers scrape --config configs/react.json -skill-seekers github --repo facebook/react -skill-seekers analyze --directory . --comprehensive - -# Package for LLM platforms -skill-seekers package output/react/ --target claude -skill-seekers package output/react/ --target gemini -``` - -**RAG Pipeline workflows:** -```bash -# LangChain Documents -skill-seekers package output/react/ --format langchain - -# LlamaIndex TextNodes -skill-seekers package output/react/ --format llama-index - -# Haystack Documents -skill-seekers package output/react/ --format haystack - -# ChromaDB direct upload -skill-seekers package output/react/ --format chroma --upload - -# FAISS export -skill-seekers package output/react/ --format faiss - -# Weaviate/Qdrant upload (requires API keys) -skill-seekers package output/react/ --format weaviate --upload -skill-seekers package output/react/ --format qdrant --upload -``` - -**AI Coding Assistant workflows:** -```bash -# Cursor IDE -skill-seekers package output/react/ --target claude -cp output/react-claude/SKILL.md .cursorrules - -# Windsurf -cp output/react-claude/SKILL.md .windsurf/rules/react.md - -# Cline (VS Code) -cp output/react-claude/SKILL.md .clinerules - -# Continue.dev (universal IDE) -python examples/continue-dev-universal/context_server.py -# Configure in ~/.continue/config.json -``` - -**Cloud Storage:** -```bash -# Upload to S3 -skill-seekers cloud upload --provider s3 --bucket my-skills output/react.zip - -# Upload to GCS -skill-seekers cloud upload --provider gcs --bucket my-skills output/react.zip - -# Upload to Azure -skill-seekers cloud upload --provider azure --container my-skills output/react.zip -``` - -## 🏗️ Architecture - -### Core Design Pattern: Platform Adaptors - -The codebase uses the **Strategy Pattern** with a factory method to support **16 platforms** across 4 categories: +Factory: `get_adaptor(platform, config)` in `adaptors/__init__.py` returns a `SkillAdaptor` instance. Base class `SkillAdaptor` + `SkillMetadata` in `adaptors/base.py`. ``` src/skill_seekers/cli/adaptors/ -├── __init__.py # Factory: get_adaptor(target/format) -├── base.py # Abstract base class -# LLM Platforms (3) -├── claude.py # Claude AI (ZIP + YAML) -├── gemini.py # Google Gemini (tar.gz) -├── openai.py # OpenAI ChatGPT (ZIP + Vector Store) -# RAG Frameworks (3) -├── langchain.py # LangChain Documents -├── llama_index.py # LlamaIndex TextNodes -├── haystack.py # Haystack Documents -# Vector Databases (5) -├── chroma.py # ChromaDB -├── faiss_helpers.py # FAISS -├── qdrant.py # Qdrant -├── weaviate.py # Weaviate -# AI Coding Assistants (4 - via Claude format + config files) -# - Cursor, Windsurf, Cline, Continue.dev -# Generic (1) -├── markdown.py # Generic Markdown (ZIP) -└── streaming_adaptor.py # Streaming data ingest +├── __init__.py # Factory: get_adaptor(platform, config), ADAPTORS registry +├── base.py # Abstract base: SkillAdaptor, SkillMetadata +├── openai_compatible.py # Shared base for OpenAI-compatible platforms +├── claude.py # --target claude +├── gemini.py # --target gemini +├── openai.py # --target openai +├── markdown.py # --target markdown +├── minimax.py # --target minimax +├── opencode.py # --target opencode +├── kimi.py # --target kimi +├── deepseek.py # --target deepseek +├── qwen.py # --target qwen +├── openrouter.py # --target openrouter +├── together.py # --target together +├── fireworks.py # --target fireworks +├── langchain.py # --format langchain +├── llama_index.py # --format llama-index +├── haystack.py # --format haystack +├── chroma.py # --format chroma +├── faiss_helpers.py # --format faiss +├── qdrant.py # --format qdrant +├── weaviate.py # --format weaviate +├── pinecone_adaptor.py # --format pinecone +└── streaming_adaptor.py # --format streaming ``` -**Key Methods:** -- `package(skill_dir, output_path)` - Platform-specific packaging -- `upload(package_path, api_key)` - Platform-specific upload (where applicable) -- `enhance(skill_dir, mode)` - AI enhancement with platform-specific models -- `export(skill_dir, format)` - Export to RAG/vector DB formats +`--target` = LLM platforms, `--format` = RAG/vector DBs. All adaptors are imported with `try/except ImportError` so missing optional deps don't break the registry. -### Data Flow (5 Phases) +### 17 Source Type Scrapers -1. **Scrape Phase** (`doc_scraper.py:scrape_all()`) - - BFS traversal from base_url - - Output: `output/{name}_data/pages/*.json` +Each in `src/skill_seekers/cli/{type}_scraper.py` with a `main()` entry point. The `create_command.py` uses `source_detector.py` to auto-route. New scrapers added in v3.2.0+: jupyter, html, openapi, asciidoc, pptx, rss, manpage, confluence, notion, chat. -2. **Build Phase** (`doc_scraper.py:build_skill()`) - - Load pages → Categorize → Extract patterns - - Output: `output/{name}/SKILL.md` + `references/*.md` - -3. **Enhancement Phase** (optional, `enhance_skill_local.py`) - - LLM analyzes references → Rewrites SKILL.md - - Platform-specific models (Sonnet 4, Gemini 2.0, GPT-4o) - -4. **Package Phase** (`package_skill.py` → adaptor) - - Platform adaptor packages in appropriate format - - Output: `.zip` or `.tar.gz` - -5. **Upload Phase** (optional, `upload_skill.py` → adaptor) - - Upload via platform API - -### File Structure (src/ layout) - Key Files Only +### CLI Argument System ``` -src/skill_seekers/ -├── cli/ # All CLI commands -│ ├── main.py # ⭐ Git-style CLI dispatcher -│ ├── doc_scraper.py # ⭐ Main scraper (~790 lines) -│ │ ├── scrape_all() # BFS traversal engine -│ │ ├── smart_categorize() # Category detection -│ │ └── build_skill() # SKILL.md generation -│ ├── github_scraper.py # GitHub repo analysis -│ ├── codebase_scraper.py # ⭐ Local analysis (C2.x+C3.x) -│ ├── package_skill.py # Platform packaging -│ ├── unified_scraper.py # Multi-source scraping -│ ├── unified_codebase_analyzer.py # Three-stream GitHub+local analyzer -│ ├── enhance_skill_local.py # AI enhancement (LOCAL mode) -│ ├── enhance_status.py # Enhancement status monitoring -│ ├── upload_skill.py # Upload to platforms -│ ├── install_skill.py # Complete workflow automation -│ ├── install_agent.py # Install to AI agent directories -│ ├── pattern_recognizer.py # C3.1 Design pattern detection -│ ├── test_example_extractor.py # C3.2 Test example extraction -│ ├── how_to_guide_builder.py # C3.3 How-to guide generation -│ ├── config_extractor.py # C3.4 Configuration extraction -│ ├── generate_router.py # C3.5 Router skill generation -│ ├── code_analyzer.py # Multi-language code analysis -│ ├── api_reference_builder.py # API documentation builder -│ ├── dependency_analyzer.py # Dependency graph analysis -│ ├── signal_flow_analyzer.py # C3.10 Signal flow analysis (Godot) -│ ├── pdf_scraper.py # PDF extraction -│ ├── epub_scraper.py # EPUB extraction -│ └── adaptors/ # ⭐ Platform adaptor pattern -│ ├── __init__.py # Factory: get_adaptor() -│ ├── base_adaptor.py # Abstract base -│ ├── claude_adaptor.py # Claude AI -│ ├── gemini_adaptor.py # Google Gemini -│ ├── openai_adaptor.py # OpenAI ChatGPT -│ ├── markdown_adaptor.py # Generic Markdown -│ ├── langchain.py # LangChain RAG -│ ├── llama_index.py # LlamaIndex RAG -│ ├── haystack.py # Haystack RAG -│ ├── chroma.py # ChromaDB -│ ├── faiss_helpers.py # FAISS -│ ├── qdrant.py # Qdrant -│ ├── weaviate.py # Weaviate -│ └── streaming_adaptor.py # Streaming data ingest -└── mcp/ # MCP server (26 tools) - ├── server_fastmcp.py # FastMCP server - └── tools/ # Tool implementations +src/skill_seekers/cli/ +├── parsers/ # Subcommand parser registration +│ └── create_parser.py # Progressive help disclosure (--help-web, --help-github, etc.) +├── arguments/ # Argument definitions +│ ├── common.py # add_all_standard_arguments() - shared across all scrapers +│ └── create.py # UNIVERSAL_ARGUMENTS, WEB_ARGUMENTS, GITHUB_ARGUMENTS, etc. +└── source_detector.py # Auto-detect source type from input string ``` -**Most Modified Files (when contributing):** -- Platform adaptors: `src/skill_seekers/cli/adaptors/{platform}.py` -- Tests: `tests/test_{feature}.py` -- Configs: `configs/{framework}.json` +### C3.x Codebase Analysis Pipeline -## 🛠️ Development Commands +Local codebase analysis features, all opt-out (`--skip-*` flags): +- C3.1 `pattern_recognizer.py` - Design pattern detection (10 GoF patterns, 9 languages) +- C3.2 `test_example_extractor.py` - Usage examples from tests +- C3.3 `how_to_guide_builder.py` - AI-enhanced educational guides +- C3.4 `config_extractor.py` - Configuration pattern extraction +- C3.5 `generate_router.py` - Architecture overview generation +- C3.10 `signal_flow_analyzer.py` - Godot signal flow analysis -### Setup +### MCP Server + +`src/skill_seekers/mcp/server_fastmcp.py` - 26+ tools via FastMCP. Transport: stdio (Claude Code) or HTTP (Cursor/Windsurf). Optional dependency: `pip install -e ".[mcp]"` + +### Enhancement Modes + +- **API mode** (if `ANTHROPIC_API_KEY` set): Direct Claude API calls +- **LOCAL mode** (fallback): Uses Claude Code CLI (free with Max plan) +- Control: `--enhance-level 0` (off) / `1` (SKILL.md only) / `2` (default, balanced) / `3` (full) + +## Key Implementation Details + +### Smart Categorization (`doc_scraper.py:smart_categorize()`) + +Scores pages against category keywords: 3 points for URL match, 2 for title, 1 for content. Threshold of 2+ required. Falls back to "other". + +### Content Extraction (`doc_scraper.py`) + +`FALLBACK_MAIN_SELECTORS` constant + `_find_main_content()` helper handle CSS selector fallback. Links are extracted from the full page before early return (not just main content). `body` is deliberately excluded from fallbacks. + +### Three-Stream GitHub Architecture (`unified_codebase_analyzer.py`) + +Stream 1: Code Analysis (AST, patterns, tests, guides). Stream 2: Documentation (README, docs/, wiki). Stream 3: Community (issues, PRs, metadata). Depth control: `basic` (1-2 min) or `c3x` (20-60 min). + +## Testing + +### Test markers (pytest.ini) ```bash -# Install in editable mode (required before tests due to src/ layout) -pip install -e . - -# Install with all platform dependencies -pip install -e ".[all-llms]" - -# Install specific platforms -pip install -e ".[gemini]" # Google Gemini -pip install -e ".[openai]" # OpenAI ChatGPT +pytest tests/ -v # Default: fast tests only +pytest tests/ -v -m slow # Include slow tests (>5s) +pytest tests/ -v -m integration # External services required +pytest tests/ -v -m e2e # Resource-intensive +pytest tests/ -v -m "not slow and not integration" # Fastest subset ``` -### Running Tests +### Known legitimate skips (~11) -**CRITICAL: Never skip tests** - User requires all tests to pass before commits. +- 2: chromadb incompatible with Python 3.14 (pydantic v1) +- 2: weaviate-client not installed +- 2: Qdrant not running (requires docker) +- 2: langchain/llama_index not installed +- 3: GITHUB_TOKEN not set + +### sys.modules gotcha + +`test_swift_detection.py` deletes `skill_seekers.cli` modules from `sys.modules`. It must save and restore both `sys.modules` entries AND parent package attributes (`setattr`). See the test file for the pattern. + +## Dependencies + +Core deps include `langchain`, `llama-index`, `anthropic`, `httpx`, `PyMuPDF`, `pydantic`. Platform-specific deps are optional: ```bash -# All tests (must run pip install -e . first!) -pytest tests/ -v - -# Specific test file -pytest tests/test_scraper_features.py -v - -# Multi-platform tests -pytest tests/test_install_multiplatform.py -v - -# With coverage -pytest tests/ --cov=src/skill_seekers --cov-report=term --cov-report=html - -# Single test -pytest tests/test_scraper_features.py::test_detect_language -v - -# MCP server tests -pytest tests/test_mcp_fastmcp.py -v +pip install -e ".[mcp]" # MCP server +pip install -e ".[gemini]" # Google Gemini +pip install -e ".[openai]" # OpenAI +pip install -e ".[docx]" # Word documents +pip install -e ".[epub]" # EPUB books +pip install -e ".[video]" # Video (lightweight) +pip install -e ".[video-full]"# Video (Whisper + visual) +pip install -e ".[jupyter]" # Jupyter notebooks +pip install -e ".[pptx]" # PowerPoint +pip install -e ".[rss]" # RSS/Atom feeds +pip install -e ".[confluence]"# Confluence wiki +pip install -e ".[notion]" # Notion pages +pip install -e ".[chroma]" # ChromaDB +pip install -e ".[all]" # Everything (except video-full) ``` -**Test Architecture:** -- 46 test files covering all features -- CI Matrix: Ubuntu + macOS, Python 3.10-3.13 -- **2,540 tests passing** (current), up from 700+ in v2.x -- Must run `pip install -e .` before tests (src/ layout requirement) -- Tests include create command integration tests, CLI refactor E2E tests +Dev dependencies use PEP 735 `[dependency-groups]` in pyproject.toml. -### Building & Publishing +## Environment Variables ```bash -# Build package (using uv - recommended) -uv build - -# Or using build -python -m build - -# Publish to PyPI -uv publish - -# Or using twine -python -m twine upload dist/* +ANTHROPIC_API_KEY=sk-ant-... # Claude AI (or compatible endpoint) +ANTHROPIC_BASE_URL=https://... # Optional: Claude-compatible API endpoint +GOOGLE_API_KEY=AIza... # Google Gemini (optional) +OPENAI_API_KEY=sk-... # OpenAI (optional) +GITHUB_TOKEN=ghp_... # Higher GitHub rate limits ``` -### Testing CLI Commands - -```bash -# Test configuration wizard (NEW: v2.7.0) -skill-seekers config --show # Show current configuration -skill-seekers config --github # GitHub token setup -skill-seekers config --test # Test connections - -# Test resume functionality (NEW: v2.7.0) -skill-seekers resume --list # List resumable jobs -skill-seekers resume --clean # Clean up old jobs - -# Test GitHub scraping with profiles (NEW: v2.7.0) -skill-seekers github --repo facebook/react --profile personal # Use specific profile -skill-seekers github --repo owner/repo --non-interactive # CI/CD mode - -# Test scraping (dry run) -skill-seekers scrape --config configs/react.json --dry-run - -# Test codebase analysis (C2.x features) -skill-seekers analyze --directory . --output output/codebase/ - -# Test pattern detection (C3.1) -skill-seekers patterns --file src/skill_seekers/cli/code_analyzer.py - -# Test how-to guide generation (C3.3) -skill-seekers how-to-guides output/test_examples.json --output output/guides/ - -# Test enhancement status monitoring -skill-seekers enhance-status output/react/ --watch - -# Video setup (auto-detect GPU and install deps) -skill-seekers video --setup - -# Test multi-platform packaging -skill-seekers package output/react/ --target gemini --dry-run - -# Test MCP server (stdio mode) -python -m skill_seekers.mcp.server_fastmcp - -# Test MCP server (HTTP mode) -python -m skill_seekers.mcp.server_fastmcp --transport http --port 8765 -``` - -### New v3.0.0 CLI Commands - -```bash -# Setup wizard (interactive configuration) -skill-seekers-setup - -# Cloud storage operations -skill-seekers cloud upload --provider s3 --bucket my-bucket output/react.zip -skill-seekers cloud download --provider gcs --bucket my-bucket react.zip -skill-seekers cloud list --provider azure --container my-container - -# Embedding server (for RAG pipelines) -skill-seekers embed --port 8080 --model sentence-transformers - -# Sync & incremental updates -skill-seekers sync --source https://docs.react.dev/ --target output/react/ -skill-seekers update --skill output/react/ --check-changes - -# Quality metrics & benchmarking -skill-seekers quality --skill output/react/ --report -skill-seekers benchmark --config configs/react.json --compare-versions - -# Multilingual support -skill-seekers multilang --detect output/react/ -skill-seekers multilang --translate output/react/ --target zh-CN - -# Streaming data ingest -skill-seekers stream --source docs/ --target output/streaming/ -``` - -## 🔧 Key Implementation Details - -### CLI Architecture (Git-style) - -**Entry point:** `src/skill_seekers/cli/main.py` - -The unified CLI modifies `sys.argv` and calls existing `main()` functions to maintain backward compatibility: - -```python -# Example: skill-seekers scrape --config react.json -# Transforms to: doc_scraper.main() with modified sys.argv -``` - -**Subcommands:** create, scrape, github, pdf, epub, unified, codebase, enhance, enhance-status, package, upload, estimate, install, install-agent, patterns, how-to-guides - -### NEW: Unified `create` Command - -**The recommended way to create skills** - Auto-detects source type and provides progressive help disclosure: - -```bash -# Auto-detection examples -skill-seekers create https://docs.react.dev/ # → Web scraping -skill-seekers create facebook/react # → GitHub analysis -skill-seekers create ./my-project # → Local codebase -skill-seekers create tutorial.pdf # → PDF extraction -skill-seekers create book.epub # → EPUB extraction -skill-seekers create configs/react.json # → Multi-source - -# Progressive help system -skill-seekers create --help # Shows universal args only (13 flags) -skill-seekers create --help-web # Shows web-specific options -skill-seekers create --help-github # Shows GitHub-specific options -skill-seekers create --help-local # Shows local analysis options -skill-seekers create --help-pdf # Shows PDF extraction options -skill-seekers create --help-epub # Shows EPUB extraction options -skill-seekers create --help-advanced # Shows advanced/rare options -skill-seekers create --help-all # Shows all 120+ flags - -# Universal flags work for ALL sources -skill-seekers create -p quick # Preset (-p shortcut) -skill-seekers create --enhance-level 2 # AI enhancement (0-3) -skill-seekers create --chunk-for-rag # RAG chunking -skill-seekers create --dry-run # Preview -``` - -**Key improvements:** -- **Single command** replaces scrape/github/analyze for most use cases -- **Smart detection** - No need to specify source type -- **Progressive disclosure** - Default help shows 13 flags, detailed help available -- **-p shortcut** - Quick preset selection (`-p quick|standard|comprehensive`) -- **Universal features** - RAG chunking, dry-run, presets work everywhere - -**Recent Additions:** -- `create` - **NEW:** Unified command with auto-detection and progressive help -- `codebase` - Local codebase analysis without GitHub API (C2.x + C3.x features) -- `enhance-status` - Monitor background/daemon enhancement processes -- `patterns` - Detect design patterns in code (C3.1) -- `how-to-guides` - Generate educational guides from tests (C3.3) - -### Platform Adaptor Usage - -```python -from skill_seekers.cli.adaptors import get_adaptor - -# Get platform-specific adaptor -adaptor = get_adaptor('gemini') # or 'claude', 'openai', 'markdown' - -# Package skill -adaptor.package(skill_dir='output/react/', output_path='output/') - -# Upload to platform -adaptor.upload( - package_path='output/react-gemini.tar.gz', - api_key=os.getenv('GOOGLE_API_KEY') -) - -# AI enhancement -adaptor.enhance(skill_dir='output/react/', mode='api') -``` - -### C3.x Codebase Analysis Features - -The project has comprehensive codebase analysis capabilities (C3.1-C3.8): - -**C3.1 Design Pattern Detection** (`pattern_recognizer.py`): -- Detects 10 common patterns: Singleton, Factory, Observer, Strategy, Decorator, Builder, Adapter, Command, Template Method, Chain of Responsibility -- Supports 9 languages: Python, JavaScript, TypeScript, C++, C, C#, Go, Rust, Java -- Three detection levels: surface (fast), deep (balanced), full (thorough) -- 87% precision, 80% recall on real-world projects - -**C3.2 Test Example Extraction** (`test_example_extractor.py`): -- Extracts real usage examples from test files -- Categories: instantiation, method_call, config, setup, workflow -- AST-based for Python, regex-based for 8 other languages -- Quality filtering with confidence scoring - -**C3.3 How-To Guide Generation** (`how_to_guide_builder.py`): -- Transforms test workflows into educational guides -- 5 AI enhancements: step descriptions, troubleshooting, prerequisites, next steps, use cases -- Dual-mode AI: API (fast) or LOCAL (free with Claude Code Max) -- 4 grouping strategies: AI tutorial group, file path, test name, complexity - -**C3.4 Configuration Pattern Extraction** (`config_extractor.py`): -- Extracts configuration patterns from codebases -- Identifies config files, env vars, CLI arguments -- AI enhancement for better organization - -**C3.5 Architectural Overview** (`generate_router.py`): -- Generates comprehensive ARCHITECTURE.md files -- Router skill generation for large documentation -- Quality improvements: 6.5/10 → 8.5/10 (+31%) -- Integrates GitHub metadata, issues, labels - -**C3.6 AI Enhancement** (Claude API integration): -- Enhances C3.1-C3.5 with AI-powered insights -- Pattern explanations and improvement suggestions -- Test example context and best practices -- Guide enhancement with troubleshooting and prerequisites - -**C3.7 Architectural Pattern Detection** (`architectural_pattern_detector.py`): -- Detects 8 architectural patterns (MVC, MVVM, MVP, Repository, etc.) -- Framework detection (Django, Flask, Spring, React, Angular, etc.) -- Multi-file analysis with directory structure patterns -- Evidence-based detection with confidence scoring - -**C3.8 Standalone Codebase Scraper** (`codebase_scraper.py`): -```bash -# Quick analysis (1-2 min, basic features only) -skill-seekers analyze --directory /path/to/repo --quick - -# Comprehensive analysis (20-60 min, all features + AI) -skill-seekers analyze --directory . --comprehensive - -# With AI enhancement (auto-detects API or LOCAL) -skill-seekers analyze --directory . --enhance - -# Granular AI enhancement control (NEW) -skill-seekers analyze --directory . --enhance-level 1 # SKILL.md only -skill-seekers analyze --directory . --enhance-level 2 # + Architecture + Config + Docs -skill-seekers analyze --directory . --enhance-level 3 # Full enhancement (all features) - -# Disable specific features -skill-seekers analyze --directory . --skip-patterns --skip-how-to-guides -``` - -- Generates 300+ line standalone SKILL.md files from codebases -- All C3.x features integrated (patterns, tests, guides, config, architecture, docs) -- Complete codebase analysis without documentation scraping -- **NEW**: Granular AI enhancement control with `--enhance-level` (0-3) - -**C3.9 Project Documentation Extraction** (`codebase_scraper.py`): -- Extracts and categorizes all markdown files from the project -- Auto-detects categories: overview, architecture, guides, workflows, features, etc. -- Integrates documentation into SKILL.md with summaries -- AI enhancement (level 2+) adds topic extraction and cross-references -- Controlled by depth: surface=raw copy, deep=parse+summarize, full=AI-enhanced -- Default ON, use `--skip-docs` to disable - -**C3.10 Signal Flow Analysis for Godot Projects** (`signal_flow_analyzer.py`): -- Complete signal flow analysis system for event-driven Godot architectures -- Signal declaration extraction (detects `signal` keyword declarations) -- Connection mapping (tracks `.connect()` calls with targets and methods) -- Emission tracking (finds `.emit()` and `emit_signal()` calls) -- Real-world metrics: 208 signals, 634 connections, 298 emissions in test project -- Signal density metrics (signals per file) -- Event chain detection (signals triggering other signals) -- Signal pattern detection: - - **EventBus Pattern** (0.90 confidence): Centralized signal hub in autoload - - **Observer Pattern** (0.85 confidence): Multi-observer signals (3+ listeners) - - **Event Chains** (0.80 confidence): Cascading signal propagation -- Signal-based how-to guides (C3.10.1): - - AI-generated step-by-step usage guides (Connect → Emit → Handle) - - Real code examples from project - - Common usage locations - - Parameter documentation -- Outputs: `signal_flow.json`, `signal_flow.mmd` (Mermaid diagram), `signal_reference.md`, `signal_how_to_guides.md` -- Comprehensive Godot 4.x support: - - GDScript (.gd), Scene files (.tscn), Resources (.tres), Shaders (.gdshader) - - GDScript test extraction (GUT, gdUnit4, WAT frameworks) - - 396 test cases extracted in test project - - Framework detection (Unity, Unreal, Godot) - -**Key Architecture Decision (BREAKING in v2.5.2):** -- Changed from opt-in (`--build-*`) to opt-out (`--skip-*`) flags -- All analysis features now ON by default for maximum value -- Backward compatibility warnings for deprecated flags - -### Smart Categorization Algorithm - -Located in `doc_scraper.py:smart_categorize()`: -- Scores pages against category keywords -- 3 points for URL match, 2 for title, 1 for content -- Threshold of 2+ for categorization -- Auto-infers categories from URL segments if none provided -- Falls back to "other" category - -### Language Detection - -Located in `doc_scraper.py:detect_language()`: -1. CSS class attributes (`language-*`, `lang-*`) -2. Heuristics (keywords like `def`, `const`, `func`) - -### Configuration File Structure - -Configs (`configs/*.json`) define scraping behavior: - -```json -{ - "name": "framework-name", - "description": "When to use this skill", - "base_url": "https://docs.example.com/", - "selectors": { - "main_content": "article", // CSS selector - "title": "h1", - "code_blocks": "pre code" - }, - "url_patterns": { - "include": ["/docs"], - "exclude": ["/blog"] - }, - "categories": { - "getting_started": ["intro", "quickstart"], - "api": ["api", "reference"] - }, - "rate_limit": 0.5, - "max_pages": 500 -} -``` - -## 🧪 Testing Guidelines - -### Test Coverage Requirements - -- Core features: 100% coverage required -- Platform adaptors: Each platform has dedicated tests -- MCP tools: All 18 tools must be tested -- Integration tests: End-to-end workflows - -### Test Markers (from pytest.ini_options) - -The project uses pytest markers to categorize tests: - -```bash -# Run only fast unit tests (default) -pytest tests/ -v - -# Include slow tests (>5 seconds) -pytest tests/ -v -m slow - -# Run integration tests (requires external services) -pytest tests/ -v -m integration - -# Run end-to-end tests (resource-intensive, creates files) -pytest tests/ -v -m e2e - -# Run tests requiring virtual environment setup -pytest tests/ -v -m venv - -# Run bootstrap feature tests -pytest tests/ -v -m bootstrap - -# Skip slow and integration tests (fastest) -pytest tests/ -v -m "not slow and not integration" -``` - -### Test Execution Strategy - -**By default, only fast tests run**. Use markers to control test execution: - -```bash -# Default: Only fast tests (skip slow/integration/e2e) -pytest tests/ -v - -# Include slow tests (>5 seconds) -pytest tests/ -v -m slow - -# Include integration tests (requires external services) -pytest tests/ -v -m integration - -# Include resource-intensive e2e tests (creates files) -pytest tests/ -v -m e2e - -# Run ONLY fast tests (explicit) -pytest tests/ -v -m "not slow and not integration and not e2e" - -# Run everything (CI does this) -pytest tests/ -v -m "" -``` - -**When to use which:** -- **Local development:** Default (fast tests only) - `pytest tests/ -v` -- **Pre-commit:** Fast tests - `pytest tests/ -v` -- **Before PR:** Include slow + integration - `pytest tests/ -v -m "not e2e"` -- **CI validation:** All tests run automatically - -### Key Test Files - -- `test_scraper_features.py` - Core scraping functionality -- `test_mcp_server.py` - MCP integration (18 tools) -- `test_mcp_fastmcp.py` - FastMCP framework -- `test_unified.py` - Multi-source scraping -- `test_github_scraper.py` - GitHub analysis -- `test_pdf_scraper.py` - PDF extraction -- `test_epub_scraper.py` - EPUB extraction -- `test_install_multiplatform.py` - Multi-platform packaging -- `test_integration.py` - End-to-end workflows -- `test_install_skill.py` - One-command install -- `test_install_agent.py` - AI agent installation -- `conftest.py` - Test configuration (checks package installation) - -## 🌐 Environment Variables - -```bash -# Claude AI / Compatible APIs -# Option 1: Official Anthropic API (default) -export ANTHROPIC_API_KEY=sk-ant-... - -# Option 2: GLM-4.7 Claude-compatible API (or any compatible endpoint) -export ANTHROPIC_API_KEY=your-api-key -export ANTHROPIC_BASE_URL=https://glm-4-7-endpoint.com/v1 - -# Google Gemini (optional) -export GOOGLE_API_KEY=AIza... - -# OpenAI ChatGPT (optional) -export OPENAI_API_KEY=sk-... - -# GitHub (for higher rate limits) -export GITHUB_TOKEN=ghp_... - -# Private config repositories (optional) -export GITLAB_TOKEN=glpat-... -export GITEA_TOKEN=... -export BITBUCKET_TOKEN=... -``` - -**All AI enhancement features respect these settings**: -- `enhance_skill.py` - API mode SKILL.md enhancement -- `ai_enhancer.py` - C3.1/C3.2 pattern and test example enhancement -- `guide_enhancer.py` - C3.3 guide enhancement -- `config_enhancer.py` - C3.4 configuration enhancement -- `adaptors/claude.py` - Claude platform adaptor enhancement - -**Note**: Setting `ANTHROPIC_BASE_URL` allows you to use any Claude-compatible API endpoint, such as GLM-4.7 (智谱 AI). - -## 📦 Package Structure (pyproject.toml) - -### Entry Points - -```toml -[project.scripts] -# Main unified CLI -skill-seekers = "skill_seekers.cli.main:main" - -# Individual tool entry points (Core) -skill-seekers-config = "skill_seekers.cli.config_command:main" # v2.7.0 Configuration wizard -skill-seekers-resume = "skill_seekers.cli.resume_command:main" # v2.7.0 Resume interrupted jobs -skill-seekers-scrape = "skill_seekers.cli.doc_scraper:main" -skill-seekers-github = "skill_seekers.cli.github_scraper:main" -skill-seekers-pdf = "skill_seekers.cli.pdf_scraper:main" -skill-seekers-epub = "skill_seekers.cli.epub_scraper:main" -skill-seekers-unified = "skill_seekers.cli.unified_scraper:main" -skill-seekers-codebase = "skill_seekers.cli.codebase_scraper:main" # C2.x Local codebase analysis -skill-seekers-enhance = "skill_seekers.cli.enhance_skill_local:main" -skill-seekers-enhance-status = "skill_seekers.cli.enhance_status:main" # Status monitoring -skill-seekers-package = "skill_seekers.cli.package_skill:main" -skill-seekers-upload = "skill_seekers.cli.upload_skill:main" -skill-seekers-estimate = "skill_seekers.cli.estimate_pages:main" -skill-seekers-install = "skill_seekers.cli.install_skill:main" -skill-seekers-install-agent = "skill_seekers.cli.install_agent:main" -skill-seekers-patterns = "skill_seekers.cli.pattern_recognizer:main" # C3.1 Pattern detection -skill-seekers-how-to-guides = "skill_seekers.cli.how_to_guide_builder:main" # C3.3 Guide generation -skill-seekers-workflows = "skill_seekers.cli.workflows_command:main" # NEW: Workflow preset management -skill-seekers-video = "skill_seekers.cli.video_scraper:main" # Video scraping pipeline (use --setup to install deps) - -# New v3.0.0 Entry Points -skill-seekers-setup = "skill_seekers.cli.setup_wizard:main" # NEW: v3.0.0 Setup wizard -skill-seekers-cloud = "skill_seekers.cli.cloud_storage_cli:main" # NEW: v3.0.0 Cloud storage -skill-seekers-embed = "skill_seekers.embedding.server:main" # NEW: v3.0.0 Embedding server -skill-seekers-sync = "skill_seekers.cli.sync_cli:main" # NEW: v3.0.0 Sync & monitoring -skill-seekers-benchmark = "skill_seekers.cli.benchmark_cli:main" # NEW: v3.0.0 Benchmarking -skill-seekers-stream = "skill_seekers.cli.streaming_ingest:main" # NEW: v3.0.0 Streaming ingest -skill-seekers-update = "skill_seekers.cli.incremental_updater:main" # NEW: v3.0.0 Incremental updates -skill-seekers-multilang = "skill_seekers.cli.multilang_support:main" # NEW: v3.0.0 Multilingual -skill-seekers-quality = "skill_seekers.cli.quality_metrics:main" # NEW: v3.0.0 Quality metrics -``` - -### Optional Dependencies - -**Project uses PEP 735 `[dependency-groups]` (Python 3.13+)**: -- Replaces deprecated `tool.uv.dev-dependencies` -- Dev dependencies: `[dependency-groups] dev = [...]` in pyproject.toml -- Install with: `pip install -e .` (installs only core deps) -- Install dev deps: See CI workflow or manually install pytest, ruff, mypy - -**Note on video dependencies:** `easyocr` and GPU-specific PyTorch builds are **not** included in the `video-full` optional dependency group. They are installed at runtime by `skill-seekers video --setup`, which auto-detects the GPU (CUDA/ROCm/MPS/CPU) and installs the correct builds. - -```toml -[project.optional-dependencies] -gemini = ["google-generativeai>=0.8.0"] -openai = ["openai>=1.0.0"] -all-llms = ["google-generativeai>=0.8.0", "openai>=1.0.0"] - -[dependency-groups] # PEP 735 (replaces tool.uv.dev-dependencies) -dev = [ - "pytest>=8.4.2", - "pytest-asyncio>=0.24.0", - "pytest-cov>=7.0.0", - "coverage>=7.11.0", -] -``` - -## 🚨 Critical Development Notes - -### Must Run Before Tests - -```bash -# REQUIRED: Install package before running tests -pip install -e . - -# Why: src/ layout requires package installation -# Without this, imports will fail -``` - -### Never Skip Tests - -Per user instructions in `~/.claude/CLAUDE.md`: -- "never skip any test. always make sure all test pass" -- All 2,540 tests must pass before commits -- Run full test suite: `pytest tests/ -v` -- New tests added for create command and CLI refactor work - -### Platform-Specific Dependencies - -Platform dependencies are optional (install only what you need): - -```bash -# Install specific platform support -pip install -e ".[gemini]" # Google Gemini -pip install -e ".[openai]" # OpenAI ChatGPT -pip install -e ".[chroma]" # ChromaDB -pip install -e ".[weaviate]" # Weaviate -pip install -e ".[s3]" # AWS S3 -pip install -e ".[gcs]" # Google Cloud Storage -pip install -e ".[azure]" # Azure Blob Storage -pip install -e ".[mcp]" # MCP integration -pip install -e ".[all]" # Everything (16 platforms + cloud + embedding) - -# Or install from PyPI: -pip install skill-seekers[gemini] # Google Gemini support -pip install skill-seekers[openai] # OpenAI ChatGPT support -pip install skill-seekers[all-llms] # All LLM platforms -pip install skill-seekers[chroma] # ChromaDB support -pip install skill-seekers[weaviate] # Weaviate support -pip install skill-seekers[s3] # AWS S3 support -pip install skill-seekers[all] # All optional dependencies -``` - -### AI Enhancement Modes - -AI enhancement transforms basic skills (2-3/10) into production-ready skills (8-9/10). Two modes available: - -**API Mode** (default if ANTHROPIC_API_KEY is set): -- Direct Claude API calls (fast, efficient) -- Cost: ~$0.15-$0.30 per skill -- Perfect for CI/CD automation -- Requires: `export ANTHROPIC_API_KEY=sk-ant-...` - -**LOCAL Mode** (fallback if no API key): -- Uses Claude Code CLI (your existing Max plan) -- Free! No API charges -- 4 execution modes: - - Headless (default): Foreground, waits for completion - - Background (`--background`): Returns immediately - - Daemon (`--daemon`): Fully detached with nohup - - Terminal (`--interactive-enhancement`): Opens new terminal (macOS) -- Status monitoring: `skill-seekers enhance-status output/react/ --watch` -- Timeout configuration: `--timeout 300` (seconds) - -### Enhancement Flag Consolidation (Phase 1) - -**IMPORTANT CHANGE:** Three enhancement flags have been unified into a single granular control: - -**Old flags (deprecated):** -- `--enhance` - Enable AI enhancement -- `--enhance-local` - Use LOCAL mode (Claude Code) -- `--api-key KEY` - Anthropic API key - -**New unified flag:** -- `--enhance-level LEVEL` - Granular AI enhancement control (0-3, default: 2) - - `0` - Disabled, no AI enhancement - - `1` - SKILL.md only (core documentation) - - `2` - + Architecture + Config + Docs (default, balanced) - - `3` - Full enhancement (all features, comprehensive) - -**Auto-detection:** Mode (API vs LOCAL) is auto-detected: -- If `ANTHROPIC_API_KEY` is set → API mode -- Otherwise → LOCAL mode (Claude Code Max) - -**Examples:** -```bash -# Auto-detect mode, default enhancement level (2) -skill-seekers create https://docs.react.dev/ - -# Disable enhancement -skill-seekers create facebook/react --enhance-level 0 - -# SKILL.md only (fast) -skill-seekers create ./my-project --enhance-level 1 - -# Full enhancement (comprehensive) -skill-seekers create tutorial.pdf --enhance-level 3 - -# Force LOCAL mode with specific level -skill-seekers enhance output/react/ --mode LOCAL --enhance-level 2 - -# Background with status monitoring -skill-seekers enhance output/react/ --background -skill-seekers enhance-status output/react/ --watch -``` - -**Migration:** Old flags still work with deprecation warnings, will be removed in v4.0.0. - -See `docs/ENHANCEMENT_MODES.md` for detailed documentation. - -### Git Workflow - -**Git Workflow Notes:** -- Main branch: `main` -- Development branch: `development` -- Always create feature branches from `development` -- Branch naming: `feature/{task-id}-{description}` or `feature/{category}` - -**To see current status:** `git status` - -### CI/CD Pipeline - -The project has GitHub Actions workflows in `.github/workflows/`: - -**tests.yml** - Runs on every push and PR to `main` or `development`: - -1. **Lint Job** (Python 3.12, Ubuntu): - - `ruff check src/ tests/` - Code linting with GitHub annotations - - `ruff format --check src/ tests/` - Format validation - - `mypy src/skill_seekers` - Type checking (continue-on-error) - -2. **Test Job** (Matrix): - - **OS:** Ubuntu + macOS - - **Python:** 3.10, 3.11, 3.12 - - **Exclusions:** macOS + Python 3.10 (speed optimization) - - **Steps:** - - Install dependencies + `pip install -e .` - - Run CLI tests (scraper, config, integration) - - Run MCP server tests - - Generate coverage report → Upload to Codecov - -3. **Summary Job** - Single status check for branch protection - - Ensures both lint and test jobs succeed - - Provides single "All Checks Complete" status - -**release.yml** - Triggers on version tags (e.g., `v2.9.0`): -- Builds package with `uv build` -- Publishes to PyPI with `uv publish` -- Creates GitHub release - -**Local Pre-Commit Validation** - -Run the same checks as CI before pushing: - -```bash -# 1. Code quality (matches lint job) - WITH AUTO-FIX -uvx ruff check --fix --unsafe-fixes src/ tests/ # Auto-fix issues -uvx ruff format src/ tests/ # Auto-format -uvx ruff check src/ tests/ # Verify clean -uvx ruff format --check src/ tests/ # Verify formatted -mypy src/skill_seekers - -# 2. Tests (matches test job) -pip install -e . -pytest tests/ -v --cov=src/skill_seekers --cov-report=term - -# 3. If all pass, you're good to push! -git add -A # Stage any auto-fixes -git commit --amend --no-edit # Add fixes to commit (or new commit) -git push origin feature/my-feature -``` - -**Branch Protection Rules:** -- **main:** Requires tests + 1 review, only maintainers merge -- **development:** Requires tests to pass, default target for PRs - -**Common CI Failure Patterns and Fixes** - -If CI fails after your changes, follow this debugging checklist: - -```bash -# 1. Fix linting errors automatically -uvx ruff check --fix --unsafe-fixes src/ tests/ - -# 2. Fix formatting issues -uvx ruff format src/ tests/ - -# 3. Check for remaining issues -uvx ruff check src/ tests/ -uvx ruff format --check src/ tests/ - -# 4. Verify tests pass locally -pip install -e . -pytest tests/ -v - -# 5. Push fixes -git add -A -git commit -m "fix: resolve CI linting/formatting issues" -git push -``` - -**Critical dependency patterns to check:** -- **MCP version mismatch**: Ensure `requirements.txt` and `pyproject.toml` have matching MCP versions -- **Missing module-level imports**: If a tool file imports a module at top level (e.g., `import yaml`), that module MUST be in core dependencies -- **Try/except ImportError**: Silent failures in try/except blocks can hide missing dependencies - -**Timing-sensitive tests:** -- Benchmark tests may fail on slower CI runners (macOS) -- If a test times out or exceeds threshold only in CI, consider relaxing the threshold -- Local passing doesn't guarantee CI passing for performance tests - -## 🚨 Common Pitfalls & Solutions - -### 1. Import Errors -**Problem:** `ModuleNotFoundError: No module named 'skill_seekers'` - -**Solution:** Must install package first due to src/ layout -```bash -pip install -e . -``` - -**Why:** The src/ layout prevents imports from repo root. Package must be installed. - -### 2. Tests Fail with "No module named..." -**Problem:** Package not installed in test environment - -**Solution:** CI runs `pip install -e .` before tests - do the same locally -```bash -pip install -e . -pytest tests/ -v -``` - -### 3. Platform-Specific Dependencies Not Found -**Problem:** `ModuleNotFoundError: No module named 'google.generativeai'` - -**Solution:** Install platform-specific dependencies -```bash -pip install -e ".[gemini]" # For Gemini -pip install -e ".[openai]" # For OpenAI -pip install -e ".[all-llms]" # For all platforms -``` - -### 4. Git Branch Confusion -**Problem:** PR targets `main` instead of `development` - -**Solution:** Always create PRs targeting `development` branch -```bash -git checkout development -git pull upstream development -git checkout -b feature/my-feature -# ... make changes ... -git push origin feature/my-feature -# Create PR: feature/my-feature → development -``` - -**Important:** See `CONTRIBUTING.md` for complete branch workflow. - -### 5. Tests Pass Locally But Fail in CI -**Problem:** Different Python version or missing dependency - -**Solution:** Test with multiple Python versions locally -```bash -# CI tests: Python 3.10, 3.11, 3.12 on Ubuntu + macOS -# Use pyenv or docker to test locally: -pyenv install 3.10.13 3.11.7 3.12.1 - -pyenv local 3.10.13 -pip install -e . && pytest tests/ -v - -pyenv local 3.11.7 -pip install -e . && pytest tests/ -v - -pyenv local 3.12.1 -pip install -e . && pytest tests/ -v -``` - -### 6. Enhancement Not Working -**Problem:** AI enhancement fails or hangs - -**Solutions:** -```bash -# Check if API key is set -echo $ANTHROPIC_API_KEY - -# Try LOCAL mode instead (uses Claude Code Max, no API key needed) -skill-seekers enhance output/react/ --mode LOCAL - -# Monitor enhancement status for background jobs -skill-seekers enhance-status output/react/ --watch -``` - -### 7. Rate Limit Errors from GitHub -**Problem:** `403 Forbidden` from GitHub API - -**Solutions:** -```bash -# Check current rate limit -curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/rate_limit - -# Configure multiple GitHub profiles (recommended) -skill-seekers config --github - -# Use specific profile -skill-seekers github --repo owner/repo --profile work - -# Test all configured tokens -skill-seekers config --test -``` - -### 8. Confused About Command Options -**Problem:** "Too many flags!" or "Which flags work with which sources?" - -**Solution:** Use the progressive disclosure help system in the `create` command: -```bash -# Start with universal options (13 flags) -skill-seekers create --help - -# Need web scraping options? -skill-seekers create --help-web - -# GitHub-specific flags? -skill-seekers create --help-github - -# See ALL options (120+ flags)? -skill-seekers create --help-all - -# Quick preset shortcut -skill-seekers create -p quick -skill-seekers create -p standard -skill-seekers create -p comprehensive -``` - -**Why:** The create command shows only relevant flags by default to reduce cognitive load. - -**Legacy commands** (scrape, github, analyze) show all flags in one help screen - use them if you prefer that style. - -### 9. CI Passes Locally But Fails in GitHub Actions -**Problem:** Ruff check/format or tests pass locally but fail in CI - -**Common causes:** -1. **Dependency version mismatch** - `requirements.txt` vs `pyproject.toml` conflicts - ```bash - # Check both files have matching versions for core deps - grep "mcp" requirements.txt pyproject.toml - grep "PyYAML" requirements.txt pyproject.toml - ``` - -2. **Module imported but not declared** - File imports module at top level but it's not in dependencies - ```bash - # Search for imports that might not be in dependencies - grep -r "^import yaml" src/ - grep -r "^from yaml" src/ - # Ensure PyYAML is in pyproject.toml core dependencies - ``` - -3. **Ruff version differences** - Local ruff vs CI ruff may have different rules - ```bash - # Use uvx to match CI's ruff version - uvx ruff check src/ tests/ - uvx ruff format src/ tests/ - ``` - -**Solution:** -```bash -# Run CI validation commands exactly as CI does -pip install -e . # Fresh install -uvx ruff check src/ tests/ # Use uvx, not local ruff -uvx ruff format --check src/ tests/ -pytest tests/ -v -``` - -## 🔌 MCP Integration - -### MCP Server (26 Tools) - -**Transport modes:** -- stdio: Claude Code, VS Code + Cline -- HTTP: Cursor, Windsurf, IntelliJ IDEA - -**Core Tools (9):** -1. `list_configs` - List preset configurations -2. `generate_config` - Generate config from docs URL -3. `validate_config` - Validate config structure -4. `estimate_pages` - Estimate page count -5. `scrape_docs` - Scrape documentation -6. `package_skill` - Package to format (supports `--format` and `--target`) -7. `upload_skill` - Upload to platform (supports `--target`) -8. `enhance_skill` - AI enhancement with platform support -9. `install_skill` - Complete workflow automation - -**Extended Tools (10):** -10. `scrape_github` - GitHub repository analysis -11. `scrape_pdf` - PDF extraction -12. `unified_scrape` - Multi-source scraping -13. `merge_sources` - Merge docs + code -14. `detect_conflicts` - Find discrepancies -15. `add_config_source` - Register git repos -16. `fetch_config` - Fetch configs from git -17. `list_config_sources` - List registered sources -18. `remove_config_source` - Remove config source -19. `split_config` - Split large configs - -**NEW Vector DB Tools (4):** -20. `export_to_chroma` - Export to ChromaDB -21. `export_to_weaviate` - Export to Weaviate -22. `export_to_faiss` - Export to FAISS -23. `export_to_qdrant` - Export to Qdrant - -**NEW Cloud Tools (3):** -24. `cloud_upload` - Upload to S3/GCS/Azure -25. `cloud_download` - Download from cloud storage -26. `cloud_list` - List files in cloud storage - -### Starting MCP Server - -```bash -# stdio mode (Claude Code, VS Code + Cline) -python -m skill_seekers.mcp.server_fastmcp - -# HTTP mode (Cursor, Windsurf, IntelliJ) -python -m skill_seekers.mcp.server_fastmcp --transport http --port 8765 -``` - -## 🤖 RAG Framework & Vector Database Integrations (**NEW - v3.0.0**) - -Skill Seekers is now the **universal preprocessor for RAG pipelines**. Export documentation to any RAG framework or vector database with a single command. - -### RAG Frameworks - -**LangChain Documents:** -```bash -# Export to LangChain Document format -skill-seekers package output/django --format langchain - -# Output: output/django-langchain.json -# Format: Array of LangChain Document objects -# - page_content: Full text content -# - metadata: {source, category, type, url} - -# Use in LangChain: -from langchain.document_loaders import JSONLoader -loader = JSONLoader("output/django-langchain.json") -documents = loader.load() -``` - -**LlamaIndex TextNodes:** -```bash -# Export to LlamaIndex TextNode format -skill-seekers package output/django --format llama-index - -# Output: output/django-llama-index.json -# Format: Array of LlamaIndex TextNode objects -# - text: Content -# - id_: Unique identifier -# - metadata: {source, category, type} -# - relationships: Document relationships - -# Use in LlamaIndex: -from llama_index import StorageContext, load_index_from_storage -from llama_index.schema import TextNode -nodes = [TextNode.from_dict(n) for n in json.load(open("output/django-llama-index.json"))] -``` - -**Haystack Documents:** -```bash -# Export to Haystack Document format -skill-seekers package output/django --format haystack - -# Output: output/django-haystack.json -# Format: Haystack Document objects for pipelines -# Perfect for: Question answering, search, RAG pipelines -``` - -### Vector Databases - -**ChromaDB (Direct Integration):** -```bash -# Export and optionally upload to ChromaDB -skill-seekers package output/django --format chroma - -# Output: output/django-chroma/ (ChromaDB collection) -# With direct upload (requires chromadb running): -skill-seekers package output/django --format chroma --upload - -# Configuration via environment: -export CHROMA_HOST=localhost -export CHROMA_PORT=8000 -``` - -**FAISS (Facebook AI Similarity Search):** -```bash -# Export to FAISS index format -skill-seekers package output/django --format faiss - -# Output: -# - output/django-faiss.index (FAISS index) -# - output/django-faiss-metadata.json (Document metadata) - -# Use with FAISS: -import faiss -index = faiss.read_index("output/django-faiss.index") -``` - -**Weaviate:** -```bash -# Export and upload to Weaviate -skill-seekers package output/django --format weaviate --upload - -# Requires environment variables: -export WEAVIATE_URL=http://localhost:8080 -export WEAVIATE_API_KEY=your-api-key - -# Creates class "DjangoDoc" with schema -``` - -**Qdrant:** -```bash -# Export and upload to Qdrant -skill-seekers package output/django --format qdrant --upload - -# Requires environment variables: -export QDRANT_URL=http://localhost:6333 -export QDRANT_API_KEY=your-api-key - -# Creates collection "django_docs" -``` - -**Pinecone (via Markdown):** -```bash -# Pinecone uses the markdown format -skill-seekers package output/django --target markdown - -# Then use Pinecone's Python client for upsert -# See: docs/integrations/PINECONE.md -``` - -### Complete RAG Pipeline Example - -```bash -# 1. Scrape documentation -skill-seekers scrape --config configs/django.json - -# 2. Export to your RAG stack -skill-seekers package output/django --format langchain # For LangChain -skill-seekers package output/django --format llama-index # For LlamaIndex -skill-seekers package output/django --format chroma --upload # Direct to ChromaDB - -# 3. Use in your application -# See examples/: -# - examples/langchain-rag-pipeline/ -# - examples/llama-index-query-engine/ -# - examples/pinecone-upsert/ -``` - -**Integration Hub:** [docs/integrations/RAG_PIPELINES.md](docs/integrations/RAG_PIPELINES.md) - -## 🛠️ AI Coding Assistant Integrations (**NEW - v3.0.0**) - -Transform any framework documentation into persistent expert context for 4+ AI coding assistants. Your IDE's AI now "knows" your frameworks without manual prompting. - -### Cursor IDE - -**Setup:** -```bash -# 1. Generate skill -skill-seekers scrape --config configs/react.json -skill-seekers package output/react/ --target claude - -# 2. Install to Cursor -cp output/react-claude/SKILL.md .cursorrules - -# 3. Restart Cursor -# AI now has React expertise! -``` - -**Benefits:** -- ✅ AI suggests React-specific patterns -- ✅ No manual "use React hooks" prompts needed -- ✅ Consistent team patterns -- ✅ Works for ANY framework - -**Guide:** [docs/integrations/CURSOR.md](docs/integrations/CURSOR.md) -**Example:** [examples/cursor-react-skill/](examples/cursor-react-skill/) - -### Windsurf - -**Setup:** -```bash -# 1. Generate skill -skill-seekers scrape --config configs/django.json -skill-seekers package output/django/ --target claude - -# 2. Install to Windsurf -mkdir -p .windsurf/rules -cp output/django-claude/SKILL.md .windsurf/rules/django.md - -# 3. Restart Windsurf -# AI now knows Django patterns! -``` - -**Benefits:** -- ✅ Flow-based coding with framework knowledge -- ✅ IDE-native AI assistance -- ✅ Persistent context across sessions - -**Guide:** [docs/integrations/WINDSURF.md](docs/integrations/WINDSURF.md) -**Example:** [examples/windsurf-fastapi-context/](examples/windsurf-fastapi-context/) - -### Cline (VS Code Extension) - -**Setup:** -```bash -# 1. Generate skill -skill-seekers scrape --config configs/fastapi.json -skill-seekers package output/fastapi/ --target claude - -# 2. Install to Cline -cp output/fastapi-claude/SKILL.md .clinerules - -# 3. Reload VS Code -# Cline now has FastAPI expertise! -``` - -**Benefits:** -- ✅ Agentic code generation in VS Code -- ✅ Cursor Composer equivalent for VS Code -- ✅ System prompts + MCP integration - -**Guide:** [docs/integrations/CLINE.md](docs/integrations/CLINE.md) -**Example:** [examples/cline-django-assistant/](examples/cline-django-assistant/) - -### Continue.dev (Universal IDE) - -**Setup:** -```bash -# 1. Generate skill -skill-seekers scrape --config configs/react.json -skill-seekers package output/react/ --target claude - -# 2. Start context server -cd examples/continue-dev-universal/ -python context_server.py --port 8765 - -# 3. Configure in ~/.continue/config.json -{ - "contextProviders": [ - { - "name": "http", - "params": { - "url": "http://localhost:8765/context", - "title": "React Documentation" - } - } - ] -} - -# 4. Works in ALL IDEs! -# VS Code, JetBrains, Vim, Emacs... -``` - -**Benefits:** -- ✅ IDE-agnostic (works in VS Code, IntelliJ, Vim, Emacs) -- ✅ Custom LLM providers supported -- ✅ HTTP-based context serving -- ✅ Team consistency across mixed IDE environments - -**Guide:** [docs/integrations/CONTINUE_DEV.md](docs/integrations/CONTINUE_DEV.md) -**Example:** [examples/continue-dev-universal/](examples/continue-dev-universal/) - -### Multi-IDE Team Setup - -For teams using different IDEs (VS Code, IntelliJ, Vim): - -```bash -# Use Continue.dev as universal context provider -skill-seekers scrape --config configs/react.json -python context_server.py --host 0.0.0.0 --port 8765 - -# ALL team members configure Continue.dev -# Result: Identical AI suggestions across all IDEs! -``` - -**Integration Hub:** [docs/integrations/INTEGRATIONS.md](docs/integrations/INTEGRATIONS.md) - -## ☁️ Cloud Storage Integration (**NEW - v3.0.0**) - -Upload skills directly to cloud storage for team sharing and CI/CD pipelines. - -### Supported Providers - -**AWS S3:** -```bash -# Upload skill -skill-seekers cloud upload --provider s3 --bucket my-skills output/react.zip - -# Download skill -skill-seekers cloud download --provider s3 --bucket my-skills react.zip - -# List skills -skill-seekers cloud list --provider s3 --bucket my-skills - -# Environment variables: -export AWS_ACCESS_KEY_ID=your-key -export AWS_SECRET_ACCESS_KEY=your-secret -export AWS_REGION=us-east-1 -``` - -**Google Cloud Storage:** -```bash -# Upload skill -skill-seekers cloud upload --provider gcs --bucket my-skills output/react.zip - -# Download skill -skill-seekers cloud download --provider gcs --bucket my-skills react.zip - -# List skills -skill-seekers cloud list --provider gcs --bucket my-skills - -# Environment variables: -export GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json -``` - -**Azure Blob Storage:** -```bash -# Upload skill -skill-seekers cloud upload --provider azure --container my-skills output/react.zip - -# Download skill -skill-seekers cloud download --provider azure --container my-skills react.zip - -# List skills -skill-seekers cloud list --provider azure --container my-skills - -# Environment variables: -export AZURE_STORAGE_CONNECTION_STRING=your-connection-string -``` - -### CI/CD Integration - -```yaml -# GitHub Actions example -- name: Upload skill to S3 - run: | - skill-seekers scrape --config configs/react.json - skill-seekers package output/react/ - skill-seekers cloud upload --provider s3 --bucket ci-skills output/react.zip - env: - AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} -``` - -**Guide:** [docs/integrations/CLOUD_STORAGE.md](docs/integrations/CLOUD_STORAGE.md) - -## 📋 Common Workflows - -### Adding a New Platform - -1. Create adaptor in `src/skill_seekers/cli/adaptors/{platform}_adaptor.py` -2. Inherit from `BaseAdaptor` -3. Implement `package()`, `upload()`, `enhance()` methods -4. Add to factory in `adaptors/__init__.py` -5. Add optional dependency to `pyproject.toml` -6. Add tests in `tests/test_install_multiplatform.py` - -### Adding a New Feature - -1. Implement in appropriate CLI module -2. Add entry point to `pyproject.toml` if needed -3. Add tests in `tests/test_{feature}.py` -4. Run full test suite: `pytest tests/ -v` -5. Update CHANGELOG.md -6. Commit only when all tests pass - -### Debugging Common Issues - -**Import Errors:** -```bash -# Always ensure package is installed first -pip install -e . - -# Verify installation -python -c "import skill_seekers; print(skill_seekers.__version__)" -``` - -**Rate Limit Issues:** -```bash -# Check current GitHub rate limit status -curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/rate_limit - -# Configure multiple GitHub profiles -skill-seekers config --github - -# Test your tokens -skill-seekers config --test -``` - -**Enhancement Not Working:** -```bash -# Check if API key is set -echo $ANTHROPIC_API_KEY - -# Try LOCAL mode instead (uses Claude Code Max) -skill-seekers enhance output/react/ --mode LOCAL - -# Monitor enhancement status -skill-seekers enhance-status output/react/ --watch -``` - -**Test Failures:** -```bash -# Run specific failing test with verbose output -pytest tests/test_file.py::test_name -vv - -# Run with print statements visible -pytest tests/test_file.py -s - -# Run with coverage to see what's not tested -pytest tests/test_file.py --cov=src/skill_seekers --cov-report=term-missing - -# Run only unit tests (skip slow integration tests) -pytest tests/ -v -m "not slow and not integration" -``` - -**Config Issues:** -```bash -# Validate config structure -skill-seekers-validate configs/myconfig.json - -# Show current configuration -skill-seekers config --show - -# Estimate pages before scraping -skill-seekers estimate configs/myconfig.json -``` - -## 🎯 Where to Make Changes - -This section helps you quickly locate the right files when implementing common changes. - -### Adding a New CLI Command - -**Files to modify:** -1. **Create command file:** `src/skill_seekers/cli/my_command.py` - ```python - def main(): - """Entry point for my-command.""" - # Implementation - ``` - -2. **Add entry point:** `pyproject.toml` - ```toml - [project.scripts] - skill-seekers-my-command = "skill_seekers.cli.my_command:main" - ``` - -3. **Update unified CLI:** `src/skill_seekers/cli/main.py` - - Add subcommand handler to dispatcher - -4. **Add tests:** `tests/test_my_command.py` - - Test main functionality - - Test CLI argument parsing - - Test error cases - -5. **Update docs:** `CHANGELOG.md` + `README.md` (if user-facing) - -### Adding a New Platform Adaptor - -**Files to modify:** -1. **Create adaptor:** `src/skill_seekers/cli/adaptors/my_platform_adaptor.py` - ```python - from .base import BaseAdaptor - - class MyPlatformAdaptor(BaseAdaptor): - def package(self, skill_dir, output_path, **kwargs): - # Platform-specific packaging - pass - - def upload(self, package_path, api_key=None, **kwargs): - # Platform-specific upload (optional for some platforms) - pass - - def export(self, skill_dir, format, **kwargs): - # For RAG/vector DB adaptors: export to specific format - pass - ``` - -2. **Register in factory:** `src/skill_seekers/cli/adaptors/__init__.py` - ```python - def get_adaptor(target=None, format=None): - # For LLM platforms (--target flag) - target_adaptors = { - 'claude': ClaudeAdaptor, - 'gemini': GeminiAdaptor, - 'openai': OpenAIAdaptor, - 'markdown': MarkdownAdaptor, - 'myplatform': MyPlatformAdaptor, # ADD THIS - } - - # For RAG/vector DBs (--format flag) - format_adaptors = { - 'langchain': LangChainAdaptor, - 'llama-index': LlamaIndexAdaptor, - 'chroma': ChromaAdaptor, - # ... etc - } - ``` - -3. **Add optional dependency:** `pyproject.toml` - ```toml - [project.optional-dependencies] - myplatform = ["myplatform-sdk>=1.0.0"] - ``` - -4. **Add tests:** `tests/test_adaptors/test_my_platform_adaptor.py` - - Test export format - - Test upload (if applicable) - - Test with real data - -5. **Update documentation:** - - README.md - Platform comparison table - - docs/integrations/MY_PLATFORM.md - Integration guide - - examples/my-platform-example/ - Working example - -### Adding a New Config Preset - -**Files to modify:** -1. **Create config:** `configs/my_framework.json` - ```json - { - "name": "my_framework", - "base_url": "https://docs.myframework.com/", - "selectors": {...}, - "categories": {...} - } - ``` - -2. **Test locally:** - ```bash - # Estimate first - skill-seekers estimate configs/my_framework.json - - # Test scrape (small sample) - skill-seekers scrape --config configs/my_framework.json --max-pages 50 - ``` - -3. **Add to README:** Update presets table in `README.md` - -4. **Submit to website:** (Optional) Submit to SkillSeekersWeb.com - -### Modifying Core Scraping Logic - -**Key files by feature:** - -| Feature | File | Size | Notes | -|---------|------|------|-------| -| Doc scraping | `src/skill_seekers/cli/doc_scraper.py` | ~90KB | Main scraper, BFS traversal | -| GitHub scraping | `src/skill_seekers/cli/github_scraper.py` | ~56KB | Repo analysis + metadata | -| GitHub API | `src/skill_seekers/cli/github_fetcher.py` | ~17KB | Rate limit handling | -| PDF extraction | `src/skill_seekers/cli/pdf_scraper.py` | Medium | PyMuPDF + OCR | -| EPUB extraction | `src/skill_seekers/cli/epub_scraper.py` | Medium | ebooklib + BeautifulSoup | -| Code analysis | `src/skill_seekers/cli/code_analyzer.py` | ~65KB | Multi-language AST parsing | -| Pattern detection | `src/skill_seekers/cli/pattern_recognizer.py` | Medium | C3.1 - 10 GoF patterns | -| Test extraction | `src/skill_seekers/cli/test_example_extractor.py` | Medium | C3.2 - 5 categories | -| Guide generation | `src/skill_seekers/cli/how_to_guide_builder.py` | ~45KB | C3.3 - AI-enhanced guides | -| Config extraction | `src/skill_seekers/cli/config_extractor.py` | ~32KB | C3.4 - 9 formats | -| Router generation | `src/skill_seekers/cli/generate_router.py` | ~43KB | C3.5 - Architecture docs | -| Signal flow | `src/skill_seekers/cli/signal_flow_analyzer.py` | Medium | C3.10 - Godot-specific | - -**Always add tests when modifying core logic!** - -### Modifying the Unified Create Command - -**The create command uses a modular argument system:** - -**Files involved:** -1. **Parser:** `src/skill_seekers/cli/parsers/create_parser.py` - - Defines help text and formatter - - Registers help mode flags (`--help-web`, `--help-github`, etc.) - - Uses custom `NoWrapFormatter` for better help display - -2. **Arguments:** `src/skill_seekers/cli/arguments/create.py` - - Three tiers of arguments: - - `UNIVERSAL_ARGUMENTS` (13 flags) - Work for all sources - - Source-specific dicts (`WEB_ARGUMENTS`, `GITHUB_ARGUMENTS`, `EPUB_ARGUMENTS`, etc.) - - `ADVANCED_ARGUMENTS` - Rare/advanced options - - `add_create_arguments(parser, mode)` - Multi-mode argument addition - -3. **Source Detection:** `src/skill_seekers/cli/source_detector.py` (if implemented) - - Auto-detect source type from input - - Pattern matching (URLs, GitHub repos, file extensions) - -4. **Main Logic:** `src/skill_seekers/cli/create_command.py` (if implemented) - - Route to appropriate scraper based on detected type - - Argument validation and compatibility checking - -**When adding new arguments:** -- Universal args → `UNIVERSAL_ARGUMENTS` in `arguments/create.py` -- Source-specific → Appropriate dict (`WEB_ARGUMENTS`, etc.) -- Always update help text and add tests - -**Example: Adding a new universal flag:** -```python -# In arguments/create.py -UNIVERSAL_ARGUMENTS = { - # ... existing args ... - "my_flag": { - "flags": ("--my-flag", "-m"), - "kwargs": { - "action": "store_true", - "help": "Description of my flag", - }, - }, -} -``` - -### Adding MCP Tools - -**Files to modify:** -1. **Add tool function:** `src/skill_seekers/mcp/tools/{category}_tools.py` - -2. **Register tool:** `src/skill_seekers/mcp/server.py` - ```python - @mcp.tool() - def my_new_tool(param: str) -> str: - """Tool description.""" - # Implementation - ``` - -3. **Add tests:** `tests/test_mcp_fastmcp.py` - -4. **Update count:** README.md (currently 18 tools) - -## 📍 Key Files Quick Reference - -| Task | File(s) | What to Modify | -|------|---------|----------------| -| Add new CLI command | `src/skill_seekers/cli/my_cmd.py`
`pyproject.toml` | Create `main()` function
Add entry point | -| Add platform adaptor | `src/skill_seekers/cli/adaptors/my_platform.py`
`adaptors/__init__.py` | Inherit `BaseAdaptor`
Register in factory | -| Fix scraping logic | `src/skill_seekers/cli/doc_scraper.py` | `scrape_all()`, `extract_content()` | -| Add MCP tool | `src/skill_seekers/mcp/server_fastmcp.py` | Add `@mcp.tool()` function | -| Fix tests | `tests/test_{feature}.py` | Add/modify test functions | -| Add config preset | `configs/{framework}.json` | Create JSON config | -| Update CI | `.github/workflows/tests.yml` | Modify workflow steps | - -## 📚 Key Code Locations - -**Documentation Scraper** (`src/skill_seekers/cli/doc_scraper.py`): -- `FALLBACK_MAIN_SELECTORS` - Shared fallback CSS selectors for finding main content (no `body`) -- `_find_main_content()` - Centralized selector fallback: config selector → fallback list -- `is_valid_url()` - URL validation -- `extract_content()` - Content extraction (links extracted from full page before early return) -- `detect_language()` - Code language detection -- `extract_patterns()` - Pattern extraction -- `smart_categorize()` - Smart categorization -- `infer_categories()` - Category inference -- `generate_quick_reference()` - Quick reference generation -- `create_enhanced_skill_md()` - SKILL.md generation -- `scrape_all()` - Main scraping loop (dry-run extracts links from full page) -- `main()` - Entry point - -**Codebase Analysis** (`src/skill_seekers/cli/`): -- `codebase_scraper.py` - Main CLI for local codebase analysis -- `code_analyzer.py` - Multi-language AST parsing (9 languages) -- `api_reference_builder.py` - API documentation generation -- `dependency_analyzer.py` - NetworkX-based dependency graphs -- `pattern_recognizer.py` - C3.1 design pattern detection -- `test_example_extractor.py` - C3.2 test example extraction -- `how_to_guide_builder.py` - C3.3 guide generation -- `config_extractor.py` - C3.4 configuration extraction -- `generate_router.py` - C3.5 router skill generation -- `signal_flow_analyzer.py` - C3.10 signal flow analysis (Godot projects) -- `unified_codebase_analyzer.py` - Three-stream GitHub+local analyzer - -**AI Enhancement** (`src/skill_seekers/cli/`): -- `enhance_skill_local.py` - LOCAL mode enhancement (4 execution modes) -- `enhance_skill.py` - API mode enhancement -- `enhance_status.py` - Status monitoring for background processes -- `ai_enhancer.py` - Shared AI enhancement logic -- `guide_enhancer.py` - C3.3 guide AI enhancement -- `config_enhancer.py` - C3.4 config AI enhancement - -**Platform Adaptors** (`src/skill_seekers/cli/adaptors/`): -- `__init__.py` - Factory function -- `base_adaptor.py` - Abstract base class -- `claude_adaptor.py` - Claude AI implementation -- `gemini_adaptor.py` - Google Gemini implementation -- `openai_adaptor.py` - OpenAI ChatGPT implementation -- `markdown_adaptor.py` - Generic Markdown implementation - -**MCP Server** (`src/skill_seekers/mcp/`): -- `server.py` - FastMCP-based server -- `tools/` - 18 MCP tool implementations - -**Configuration & Rate Limit Management** (NEW: v2.7.0 - `src/skill_seekers/cli/`): -- `config_manager.py` - Multi-token configuration system (~490 lines) - - `ConfigManager` class - Singleton pattern for global config access - - `add_github_profile()` - Add GitHub profile with token and strategy - - `get_github_token()` - Smart fallback chain (CLI → Env → Config → Prompt) - - `get_next_profile()` - Profile switching for rate limit handling - - `save_progress()` / `load_progress()` - Job resumption support - - `cleanup_old_progress()` - Auto-cleanup of old jobs (7 days default) -- `config_command.py` - Interactive configuration wizard (~400 lines) - - `main_menu()` - 7-option main menu with navigation - - `github_token_menu()` - GitHub profile management - - `add_github_profile()` - Guided token setup with browser integration - - `api_keys_menu()` - API key configuration for Claude/Gemini/OpenAI - - `test_connections()` - Connection testing for tokens and API keys -- `rate_limit_handler.py` - Smart rate limit detection and handling (~450 lines) - - `RateLimitHandler` class - Strategy pattern for rate limit handling - - `check_upfront()` - Upfront rate limit check before starting - - `check_response()` - Real-time detection from API responses - - `handle_rate_limit()` - Execute strategy (prompt/wait/switch/fail) - - `try_switch_profile()` - Automatic profile switching - - `wait_for_reset()` - Countdown timer with live progress - - `show_countdown_timer()` - Live terminal countdown display -- `resume_command.py` - Resume interrupted scraping jobs (~150 lines) - - `list_resumable_jobs()` - Display all jobs with progress details - - `resume_job()` - Resume from saved checkpoint - - `clean_old_jobs()` - Cleanup old progress files - -**GitHub Integration** (Modified for v2.7.0 - `src/skill_seekers/cli/`): -- `github_fetcher.py` - Integrated rate limit handler - - Constructor now accepts `interactive` and `profile_name` parameters - - `fetch()` - Added upfront rate limit check - - All API calls check responses for rate limits - - Raises `RateLimitError` when rate limit cannot be handled -- `github_scraper.py` - Added CLI flags - - `--non-interactive` flag for CI/CD mode (fail fast) - - `--profile` flag to select GitHub profile from config - - Config supports `interactive` and `github_profile` keys - -**RAG & Vector Database Adaptors** (NEW: v3.0.0 - `src/skill_seekers/cli/adaptors/`): -- `langchain.py` - LangChain Documents export (~250 lines) - - Exports to LangChain Document format - - Preserves metadata (source, category, type, url) - - Smart chunking with overlap -- `llama_index.py` - LlamaIndex TextNodes export (~280 lines) - - Exports to TextNode format with unique IDs - - Relationship mapping between documents - - Metadata preservation -- `haystack.py` - Haystack Documents export (~230 lines) - - Pipeline-ready document format - - Supports embeddings and filters -- `chroma.py` - ChromaDB integration (~350 lines) - - Direct collection creation - - Batch upsert with embeddings - - Query interface -- `weaviate.py` - Weaviate vector search (~320 lines) - - Schema creation with auto-detection - - Batch import with error handling -- `faiss_helpers.py` - FAISS index generation (~280 lines) - - Index building with metadata - - Search utilities -- `qdrant.py` - Qdrant vector database (~300 lines) - - Collection management - - Payload indexing -- `streaming_adaptor.py` - Streaming data ingest (~200 lines) - - Real-time data processing - - Incremental updates - -**Cloud Storage & Infrastructure** (NEW: v3.0.0 - `src/skill_seekers/cli/`): -- `cloud_storage_cli.py` - S3/GCS/Azure upload/download (~450 lines) - - Multi-provider abstraction - - Parallel uploads for large files - - Retry logic with exponential backoff -- `embedding_pipeline.py` - Embedding generation for vectors (~320 lines) - - Sentence-transformers integration - - Batch processing - - Multiple embedding models -- `sync_cli.py` - Continuous sync & monitoring (~380 lines) - - File watching for changes - - Automatic re-scraping - - Smart diff detection -- `incremental_updater.py` - Smart incremental updates (~350 lines) - - Change detection algorithms - - Partial skill updates - - Version tracking -- `streaming_ingest.py` - Real-time data streaming (~290 lines) - - Stream processing pipelines - - WebSocket support -- `benchmark_cli.py` - Performance benchmarking (~280 lines) - - Scraping performance tests - - Comparison reports - - CI/CD integration -- `quality_metrics.py` - Quality analysis & reporting (~340 lines) - - Completeness scoring - - Link checking - - Content quality metrics -- `multilang_support.py` - Internationalization support (~260 lines) - - Language detection - - Translation integration - - Multi-locale skills -- `setup_wizard.py` - Interactive setup wizard (~220 lines) - - Configuration management - - Profile creation - - First-time setup - -**Video Scraper** (`src/skill_seekers/cli/`): -- `video_scraper.py` - Main video scraping pipeline CLI -- `video_setup.py` - GPU auto-detection, PyTorch installation, visual dependency setup (~835 lines) - - Detects CUDA/ROCm/MPS/CPU and installs matching PyTorch build - - Installs `easyocr` and other visual processing deps at runtime via `--setup` - - Run `skill-seekers video --setup` before first use - -## 🎯 Project-Specific Best Practices - -1. **Prefer the unified `create` command** - Use `skill-seekers create ` over legacy commands for consistency -2. **Always use platform adaptors** - Never hardcode platform-specific logic -3. **Test all platforms** - Changes must work for all 16 platforms (was 4 in v2.x) -4. **Maintain backward compatibility** - Legacy commands (scrape, github, analyze) must still work -5. **Document API changes** - Update CHANGELOG.md for every release -6. **Keep dependencies optional** - Platform-specific deps are optional (RAG, cloud, etc.) -7. **Use src/ layout** - Proper package structure with `pip install -e .` -8. **Run tests before commits** - Per user instructions, never skip tests (1,765+ tests must pass) -9. **RAG-first mindset** - v3.0.0 is the universal preprocessor for AI systems -10. **Export format clarity** - Use `--format` for RAG/vector DBs, `--target` for LLM platforms -11. **Test with real integrations** - Verify exports work with actual LangChain, ChromaDB, etc. -12. **Progressive disclosure** - When adding flags, categorize as universal/source-specific/advanced - -## 🐛 Debugging Tips - -### Enable Verbose Logging - -```bash -# Set environment variable for debug output -export SKILL_SEEKERS_DEBUG=1 -skill-seekers scrape --config configs/react.json -``` - -### Test Single Function/Module - -Run Python modules directly for debugging: -```bash -# Run modules with --help to see options -python -m skill_seekers.cli.doc_scraper --help -python -m skill_seekers.cli.github_scraper --repo facebook/react --dry-run -python -m skill_seekers.cli.package_skill --help - -# Test MCP server directly -python -m skill_seekers.mcp.server_fastmcp -``` - -### Use pytest with Debugging - -```bash -# Drop into debugger on failure -pytest tests/test_scraper_features.py --pdb - -# Show print statements (normally suppressed) -pytest tests/test_scraper_features.py -s - -# Verbose test output (shows full diff, more details) -pytest tests/test_scraper_features.py -vv - -# Run only failed tests from last run -pytest tests/ --lf - -# Run until first failure (stop immediately) -pytest tests/ -x - -# Show local variables on failure -pytest tests/ -l -``` - -### Debug Specific Test - -```bash -# Run single test with full output -pytest tests/test_scraper_features.py::test_detect_language -vv -s - -# With debugger -pytest tests/test_scraper_features.py::test_detect_language --pdb -``` - -### Check Package Installation - -```bash -# Verify package is installed -pip list | grep skill-seekers - -# Check installation mode (should show editable location) -pip show skill-seekers - -# Verify imports work -python -c "import skill_seekers; print(skill_seekers.__version__)" - -# Check CLI entry points -which skill-seekers -skill-seekers --version -``` - -### Common Error Messages & Solutions - -**"ModuleNotFoundError: No module named 'skill_seekers'"** -→ **Solution:** `pip install -e .` -→ **Why:** src/ layout requires package installation - -**"403 Forbidden" from GitHub API** -→ **Solution:** Rate limit hit, set `GITHUB_TOKEN` or use `skill-seekers config --github` -→ **Check limit:** `curl -H "Authorization: token $GITHUB_TOKEN" https://api.github.com/rate_limit` - -**"SKILL.md enhancement failed"** -→ **Solution:** Check if `ANTHROPIC_API_KEY` is set, or use `--mode LOCAL` -→ **Monitor:** `skill-seekers enhance-status output/react/ --watch` - -**"No such file or directory: 'configs/myconfig.json'"** -→ **Solution:** Config path resolution order: - 1. Exact path as provided - 2. `./configs/` (current directory) - 3. `~/.config/skill-seekers/configs/` (user config) - 4. SkillSeekersWeb.com API (presets) - -**"pytest: command not found"** -→ **Solution:** Install dev dependencies -```bash -pip install pytest pytest-asyncio pytest-cov coverage -# Or: pip install -e ".[dev]" (if available) -``` - -**"ruff: command not found"** -→ **Solution:** Install ruff -```bash -pip install ruff -# Or use uvx: uvx ruff check src/ -``` - -### Debugging Scraping Issues - -**No content extracted?** -```python -# Test selectors in Python -from bs4 import BeautifulSoup -import requests - -url = "https://docs.example.com/page" -soup = BeautifulSoup(requests.get(url).content, 'html.parser') - -# Try different selectors -print(soup.select_one('article')) -print(soup.select_one('main')) -print(soup.select_one('div[role="main"]')) -print(soup.select_one('.documentation-content')) -``` - -**Categories not working?** -- Check `categories` in config has correct keywords -- Run with `--dry-run` to see categorization without scraping -- Enable debug mode: `export SKILL_SEEKERS_DEBUG=1` - -### Profiling Performance - -```bash -# Profile scraping performance -python -m cProfile -o profile.stats -m skill_seekers.cli.doc_scraper --config configs/react.json --max-pages 10 - -# Analyze profile -python -m pstats profile.stats -# In pstats shell: -# > sort cumtime -# > stats 20 -``` - -## 📖 Additional Documentation - -**Official Website:** -- [SkillSeekersWeb.com](https://skillseekersweb.com/) - Browse 24+ preset configs, share configs, complete documentation - -**For Users:** -- [README.md](README.md) - Complete user documentation -- [BULLETPROOF_QUICKSTART.md](BULLETPROOF_QUICKSTART.md) - Beginner guide -- [TROUBLESHOOTING.md](TROUBLESHOOTING.md) - Common issues - -**For Developers:** -- [CHANGELOG.md](CHANGELOG.md) - Release history -- [ROADMAP.md](ROADMAP.md) - 136 tasks across 10 categories -- [docs/UNIFIED_SCRAPING.md](docs/UNIFIED_SCRAPING.md) - Multi-source scraping -- [docs/MCP_SETUP.md](docs/MCP_SETUP.md) - MCP server setup -- [docs/ENHANCEMENT_MODES.md](docs/ENHANCEMENT_MODES.md) - AI enhancement modes -- [docs/PATTERN_DETECTION.md](docs/PATTERN_DETECTION.md) - C3.1 pattern detection -- [docs/THREE_STREAM_STATUS_REPORT.md](docs/THREE_STREAM_STATUS_REPORT.md) - Three-stream architecture -- [docs/MULTI_LLM_SUPPORT.md](docs/MULTI_LLM_SUPPORT.md) - Multi-platform support - -## 🎓 Understanding the Codebase - -### Why src/ Layout? - -Modern Python best practice (PEP 517/518): -- Prevents accidental imports from repo root -- Forces proper package installation -- Better isolation between package and tests -- Required: `pip install -e .` before running tests - -### Why Platform Adaptors? - -Strategy pattern benefits: -- Single codebase supports 4 platforms -- Platform-specific optimizations (format, APIs, models) -- Easy to add new platforms (implement BaseAdaptor) -- Clean separation of concerns -- Testable in isolation - -### Why Git-style CLI? - -User experience benefits: -- Familiar to developers (like `git`) -- Single entry point: `skill-seekers` -- Backward compatible: individual tools still work -- Cleaner than multiple separate commands -- Easier to document and teach - -### Three-Stream GitHub Architecture - -The `unified_codebase_analyzer.py` splits GitHub repositories into three independent streams: - -**Stream 1: Code Analysis** (C3.x features) -- Deep AST parsing (9 languages) -- Design pattern detection (C3.1) -- Test example extraction (C3.2) -- How-to guide generation (C3.3) -- Configuration extraction (C3.4) -- Architectural overview (C3.5) -- API reference + dependency graphs - -**Stream 2: Documentation** -- README, CONTRIBUTING, LICENSE -- docs/ directory markdown files -- Wiki pages (if available) -- CHANGELOG and version history - -**Stream 3: Community Insights** -- GitHub metadata (stars, forks, watchers) -- Issue analysis (top problems and solutions) -- PR trends and contributor stats -- Release history -- Label-based topic detection - -**Key Benefits:** -- Unified interface for GitHub URLs and local paths -- Analysis depth control: 'basic' (1-2 min) or 'c3x' (20-60 min) -- Enhanced router generation with GitHub context -- Smart keyword extraction weighted by GitHub labels (2x weight) -- 81 E2E tests passing (0.44 seconds) - -## 🔧 Helper Scripts - -The `scripts/` directory contains utility scripts: - -```bash -# Bootstrap skill generation - self-hosting skill-seekers as a Claude skill -./scripts/bootstrap_skill.sh - -# Start MCP server for HTTP transport -./scripts/start_mcp_server.sh - -# Script templates are in scripts/skill_header.md -``` - -**Bootstrap Skill Workflow:** -1. Analyzes skill-seekers codebase itself (dogfooding) -2. Combines handcrafted header with auto-generated analysis -3. Validates SKILL.md structure -4. Outputs ready-to-use skill for Claude Code - -## 🔍 Performance Characteristics - -| Operation | Time | Notes | -|-----------|------|-------| -| Scraping (sync) | 15-45 min | First time, thread-based | -| Scraping (async) | 5-15 min | 2-3x faster with `--async` | -| Building | 1-3 min | Fast rebuild from cache | -| Re-building | <1 min | With `--skip-scrape` | -| Enhancement (LOCAL) | 30-60 sec | Uses Claude Code Max | -| Enhancement (API) | 20-40 sec | Requires API key | -| Packaging | 5-10 sec | Final .zip creation | - -## 🎉 Recent Achievements - -**v3.1.4 (Unreleased) - "Selector Fallback & Dry-Run Fix":** -- 🐛 **Issue #300: `create https://reactflow.dev/` only found 1 page** — Now finds 20+ pages -- 🔧 **Centralized selector fallback** — `FALLBACK_MAIN_SELECTORS` constant + `_find_main_content()` helper replace 3 duplicated fallback loops -- 🔗 **Link extraction before early return** — `extract_content()` now discovers links even when no content selector matches -- 🔍 **Dry-run full-page link discovery** — Both sync and async dry-run paths extract links from the full page (was main-content-only or missing entirely) -- 🛣️ **Smart `create --config` routing** — Peeks at JSON to route `base_url` configs to doc_scraper and `sources` configs to unified_scraper -- 🧹 **Removed `body` fallback** — `body` matched everything, hiding real selector failures -- ✅ **Pre-existing test fixes** — `test_auto_fetch_enabled` (react.json exists locally) and `test_mcp_validate_legacy_config` (react.json is now unified format) - -**v3.1.3 (Released) - "Unified Argument Interface":** -- 🔧 **Unified Scraper Arguments** - All scrapers (scrape, github, analyze, pdf) now share a common argument contract via `add_all_standard_arguments(parser)` in `arguments/common.py` -- 🐛 **Fix `create` Argument Forwarding** - `create --dry-run`, `create owner/repo --dry-run`, `create ./path --dry-run` all work now (previously crashed) -- 🏗️ **Argument Deduplication** - Removed duplicated arg definitions from github.py, scrape.py, analyze.py, pdf.py; all import shared args -- ➕ **New Flags** - GitHub and PDF scrapers gain `--dry-run`, `--verbose`, `--quiet`; analyze gains `--name`, `--description`, `--quiet` -- 🔀 **Route-Specific Forwarding** - `create` command's `_add_common_args()` now only forwards universal flags; route-specific flags moved to their respective methods - -**v3.1.0 - "Unified CLI & Developer Experience":** -- 🎯 **Unified `create` Command** - Auto-detects source type (web/GitHub/local/PDF/config) -- 📋 **Progressive Disclosure Help** - Default shows 13 universal flags, detailed help available per source -- ⚡ **-p Shortcut** - Quick preset selection (`-p quick|standard|comprehensive`) -- 🔧 **Enhancement Flag Consolidation** - `--enhance-level` (0-3) replaces 3 separate flags -- 🎨 **Smart Source Detection** - No need to specify whether input is URL, repo, or directory -- 🔄 **Enhancement Workflow Presets** - YAML-based presets; `skill-seekers workflows list/show/copy/add/remove/validate`; bundled presets: `default`, `minimal`, `security-focus`, `architecture-comprehensive`, `api-documentation` -- 🔀 **Multiple Workflows from CLI** - `--enhance-workflow wf-a --enhance-workflow wf-b` chains presets in a single command; `workflows copy/add/remove` all accept multiple names/files at once -- 🐛 **Bug Fix** - `create` command now correctly forwards multiple `--enhance-workflow` flags to sub-scrapers -- ✅ **2,121 Tests Passing** - All CLI refactor + workflow preset work verified -- 📚 **Improved Documentation** - CLAUDE.md, README, QUICK_REFERENCE updated with workflow preset details - -**v3.1.0 CI Stability (February 20, 2026):** -- 🔧 **Dependency Alignment** - Fixed MCP version mismatch between requirements.txt (was 1.18.0) and pyproject.toml (>=1.25) -- 📦 **PyYAML Core Dependency** - Added PyYAML>=6.0 to core dependencies (required by workflow_tools.py module-level import) -- ⚡ **Benchmark Stability** - Relaxed timing-sensitive test thresholds for CI environment variability -- ✅ **2,121 Tests Passing** - All CI matrix jobs passing (ubuntu 3.10/3.11/3.12, macos 3.11/3.12) - -**v3.0.0 (February 10, 2026) - "Universal Intelligence Platform":** -- 🚀 **16 Platform Adaptors** - RAG frameworks (LangChain, LlamaIndex, Haystack), vector DBs (Chroma, FAISS, Weaviate, Qdrant), AI coding assistants (Cursor, Windsurf, Cline, Continue.dev), LLM platforms (Claude, Gemini, OpenAI) -- 🛠️ **26 MCP Tools** (up from 18) - Complete automation for any AI system -- ✅ **1,852 Tests Passing** (up from 700+) - Production-grade reliability -- ☁️ **Cloud Storage** - S3, GCS, Azure Blob Storage integration -- 🎯 **AI Coding Assistants** - Persistent context for Cursor, Windsurf, Cline, Continue.dev -- 📊 **Quality Metrics** - Automated completeness scoring and content analysis -- 🌐 **Multilingual Support** - Language detection and translation -- 🔄 **Streaming Ingest** - Real-time data processing pipelines -- 📈 **Benchmarking Tools** - Performance comparison and CI/CD integration -- 🔧 **Setup Wizard** - Interactive first-time configuration -- 📦 **12 Example Projects** - Complete working examples for every integration -- 📚 **18 Integration Guides** - Comprehensive documentation for all platforms - -**v2.9.0 (February 3, 2026):** -- **C3.10: Signal Flow Analysis** - Complete signal flow analysis for Godot projects -- Comprehensive Godot 4.x support (GDScript, .tscn, .tres, .gdshader files) -- GDScript test extraction (GUT, gdUnit4, WAT frameworks) -- Signal pattern detection (EventBus, Observer, Event Chains) -- Signal-based how-to guides generation - -**v2.8.0 (February 1, 2026):** -- C3.9: Project Documentation Extraction -- Granular AI enhancement control with `--enhance-level` (0-3) - -**v2.7.1 (January 18, 2026 - Hotfix):** -- 🚨 **Critical Bug Fix:** Config download 404 errors resolved -- Fixed manual URL construction bug - now uses `download_url` from API response -- All 15 source tools tests + 8 fetch_config tests passing - -**v2.7.0 (January 18, 2026):** -- 🔐 **Smart Rate Limit Management** - Multi-token GitHub configuration system -- 🧙 **Interactive Configuration Wizard** - Beautiful terminal UI (`skill-seekers config`) -- 🚦 **Intelligent Rate Limit Handler** - Four strategies (prompt/wait/switch/fail) -- 📥 **Resume Capability** - Continue interrupted jobs with progress tracking -- 🔧 **CI/CD Support** - Non-interactive mode for automation -- 🎯 **Bootstrap Skill** - Self-hosting skill-seekers as Claude Code skill - -**v2.6.0 (January 14, 2026):** -- **C3.x Codebase Analysis Suite Complete** (C3.1-C3.8) -- Multi-platform support with platform adaptor architecture (4 platforms) -- 18 MCP tools fully functional -- 700+ tests passing -- Unified multi-source scraping maturity - -**C3.x Series (Complete - Code Analysis Features):** -- **C3.1:** Design pattern detection (10 GoF patterns, 9 languages, 87% precision) -- **C3.2:** Test example extraction (5 categories, AST-based for Python) -- **C3.3:** How-to guide generation with AI enhancement (5 improvements) -- **C3.4:** Configuration pattern extraction (env vars, config files, CLI args) -- **C3.5:** Architectural overview & router skill generation -- **C3.6:** AI enhancement for patterns and test examples (Claude API integration) -- **C3.7:** Architectural pattern detection (8 patterns, framework-aware) -- **C3.8:** Standalone codebase scraper (300+ line SKILL.md from code alone) -- **C3.9:** Project documentation extraction (markdown categorization, AI enhancement) -- **C3.10:** Signal flow analysis (Godot event-driven architecture, pattern detection) - -**v2.5.2:** -- UX Improvement: Analysis features now default ON with --skip-* flags (BREAKING) -- Router quality improvements: 6.5/10 → 8.5/10 (+31%) -- All 107 codebase analysis tests passing - -**v2.5.0:** -- Multi-platform support (Claude, Gemini, OpenAI, Markdown) -- Platform adaptor architecture -- 18 MCP tools (up from 9) -- Complete feature parity across platforms - -**v2.1.0:** -- Unified multi-source scraping (docs + GitHub + PDF) -- Conflict detection between sources -- 427 tests passing - -**v1.0.0:** -- Production release with MCP integration -- Documentation scraping with smart categorization -- 12 preset configurations +## Adding New Features + +### New platform adaptor +1. Create `src/skill_seekers/cli/adaptors/{platform}.py` inheriting `SkillAdaptor` from `base.py` +2. Register in `adaptors/__init__.py` (add try/except import + add to `ADAPTORS` dict) +3. Add optional dep to `pyproject.toml` +4. Add tests in `tests/` + +### New source type scraper +1. Create `src/skill_seekers/cli/{type}_scraper.py` with `main()` +2. Add to `COMMAND_MODULES` in `cli/main.py` +3. Add entry point in `pyproject.toml` `[project.scripts]` +4. Add auto-detection in `source_detector.py` +5. Add optional dep if needed +6. Add tests + +### New CLI argument +- Universal: `UNIVERSAL_ARGUMENTS` in `arguments/create.py` +- Source-specific: appropriate dict (`WEB_ARGUMENTS`, `GITHUB_ARGUMENTS`, etc.) +- Shared across scrapers: `add_all_standard_arguments()` in `arguments/common.py` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8902d36..826298e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -76,6 +76,21 @@ git push origin my-feature --- +## Related Repositories + +Skill Seekers spans multiple repositories. Make sure you're contributing to the right one: + +| What you want to work on | Repository | +|--------------------------|-----------| +| Core CLI, scrapers, MCP tools, adaptors | [Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers) (this repo) | +| Website, docs, UI/UX | [skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb) | +| Preset configs, community configs | [skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs) | +| GitHub Action integration | [skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action) | +| Claude Code plugin | [skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin) | +| Homebrew formula | [homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers) | + +--- + ## Code of Conduct This project and everyone participating in it is governed by our commitment to fostering an open and welcoming environment. Please be respectful and constructive in all interactions. @@ -481,6 +496,24 @@ Skill_Seekers/ **Scraper pattern (17 source types):** Each source type has `cli/_scraper.py` (with `ToSkillConverter` class + `main()`), `arguments/.py`, and `parsers/_parser.py`. Register new types in: `parsers/__init__.py` PARSERS list, `main.py` COMMAND_MODULES dict, `config_validator.py` VALID_SOURCE_TYPES set. +### UML Architecture + +Full UML class diagrams are maintained in StarUML and synced from source code: + +- **[docs/UML_ARCHITECTURE.md](docs/UML_ARCHITECTURE.md)** - Overview with embedded PNG diagrams +- **[docs/UML/skill_seekers.mdj](docs/UML/skill_seekers.mdj)** - StarUML project (open with [StarUML](https://staruml.io/)) +- **[docs/UML/exports/](docs/UML/exports/)** - 14 PNG exports (package overview + 13 class diagrams) +- **[docs/UML/html/](docs/UML/html/index.html/index.html)** - HTML API reference + +**Key design patterns documented in UML:** +- Strategy + Factory in Adaptors (SkillAdaptor ABC + 20+ implementations) +- Strategy + Factory in Storage (BaseStorageAdaptor + S3/GCS/Azure) +- Template Method in Parsers (SubcommandParser + 28 subclasses) +- Template Method in Analysis (BasePatternDetector + 10 GoF detectors) +- Command pattern in CLI (CLIDispatcher + COMMAND_MODULES lazy dispatch) + +When adding new classes or modules, please update the corresponding UML diagram to keep architecture docs in sync. + --- ## Release Process diff --git a/Dockerfile.mcp b/Dockerfile.mcp index 6e7cc3e..7baba55 100644 --- a/Dockerfile.mcp +++ b/Dockerfile.mcp @@ -4,8 +4,8 @@ FROM python:3.12-slim LABEL maintainer="Skill Seekers " -LABEL description="Skill Seekers MCP Server - 25 tools for AI skills generation" -LABEL version="2.9.0" +LABEL description="Skill Seekers MCP Server - 35 tools for AI skills generation" +LABEL version="3.3.0" WORKDIR /app @@ -48,9 +48,10 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \ # Volumes VOLUME ["/data", "/configs", "/output"] -# Expose MCP server port -EXPOSE 8765 +# Expose MCP server port (default 8765, overridden by $PORT on cloud platforms) +EXPOSE ${MCP_PORT:-8765} # Start MCP server in HTTP mode by default -# Use --transport stdio for stdio mode -CMD ["python", "-m", "skill_seekers.mcp.server_fastmcp", "--transport", "http", "--port", "8765"] +# Uses shell form so $PORT/$MCP_PORT env vars are expanded at runtime +# Cloud platforms (Render, Railway, etc.) set $PORT automatically +CMD python -m skill_seekers.mcp.server_fastmcp --http --host 0.0.0.0 --port ${PORT:-${MCP_PORT:-8765}} diff --git a/README.ar.md b/README.ar.md index ba3b175..c8c04c2 100644 --- a/README.ar.md +++ b/README.ar.md @@ -29,6 +29,21 @@ > 📋 **[عرض خارطة الطريق والمهام](https://github.com/users/yusufkaraaslan/projects/2)** - 134 مهمة عبر 10 فئات، اختر أيًا منها للمساهمة! +## 🌐 المنظومة + +Skill Seekers هو مشروع متعدد المستودعات. إليك أين يوجد كل شيء: + +| المستودع | الوصف | الروابط | +|----------|-------|---------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | CLI الأساسي وخادم MCP (هذا المستودع) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | الموقع والتوثيق | [الموقع](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | مستودع إعدادات المجتمع | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action لـ CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | إضافة Claude Code | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap لـ macOS | | + +> **تريد المساهمة؟** مستودعات الموقع والإعدادات هي نقاط بداية رائعة للمساهمين الجدد! + ## 🧠 طبقة البيانات لأنظمة الذكاء الاصطناعي **Skill Seekers هو طبقة المعالجة المسبقة العامة** التي تقع بين التوثيق الخام وجميع أنظمة الذكاء الاصطناعي التي تستهلكه. سواء كنت تبني مهارات Claude أو خط أنابيب RAG باستخدام LangChain أو ملف `.cursorrules` لـ Cursor — فإن تحضير البيانات متطابق. تقوم بذلك مرة واحدة وتصدّر إلى جميع المنصات المستهدفة. @@ -192,7 +207,7 @@ Skill Seekers هو **طبقة البيانات لأنظمة الذكاء الا - ✅ **التوافق مع الإصدارات السابقة** - إعدادات المصدر الواحد القديمة تعمل بشكل طبيعي ### 🤖 دعم منصات LLM المتعددة -- ✅ **4 منصات LLM** - Claude AI وGoogle Gemini وOpenAI ChatGPT وMarkdown العام +- ✅ **12 منصة LLM** - Claude AI وGoogle Gemini وOpenAI ChatGPT وMiniMax AI وMarkdown العام وOpenCode وKimi وDeepSeek وQwen وOpenRouter وTogether AI وFireworks AI - ✅ **استخراج عام** - نفس التوثيق يعمل لجميع المنصات - ✅ **تعبئة خاصة بكل منصة** - تنسيقات محسّنة لكل نموذج لغوي - ✅ **تصدير بأمر واحد** - علامة `--target` لاختيار المنصة @@ -579,9 +594,9 @@ skill-seekers install --config react --dry-run ## 📊 مصفوفة الميزات -يدعم Skill Seekers **4 منصات LLM** و**17 نوعًا من المصادر** مع تكافؤ كامل في الميزات عبر جميع الأهداف. +يدعم Skill Seekers **12 منصة LLM** و**17 نوعًا من المصادر** مع تكافؤ كامل في الميزات عبر جميع الأهداف. -**المنصات:** Claude AI وGoogle Gemini وOpenAI ChatGPT وMarkdown العام +**المنصات:** Claude AI وGoogle Gemini وOpenAI ChatGPT وMiniMax AI وMarkdown العام وOpenCode وKimi وDeepSeek وQwen وOpenRouter وTogether AI وFireworks AI **أنواع المصادر:** مواقع التوثيق ومستودعات GitHub وPDF وWord (.docx) وEPUB والفيديو وقواعد الكود المحلية ودفاتر Jupyter وHTML المحلي وOpenAPI/Swagger وAsciiDoc وPowerPoint (.pptx) وخلاصات RSS/Atom وصفحات Man وويكي Confluence وصفحات Notion ومحادثات Slack/Discord انظر [مصفوفة الميزات الكاملة](docs/FEATURE_MATRIX.md) لدعم المنصات والميزات بالتفصيل. @@ -817,7 +832,7 @@ skill-seekers package output/react/ ## 🤖 التثبيت في وكلاء الذكاء الاصطناعي -يمكن لـ Skill Seekers تثبيت المهارات تلقائيًا في أكثر من 10 وكلاء برمجة بالذكاء الاصطناعي. +يمكن لـ Skill Seekers تثبيت المهارات تلقائيًا في 18 وكيل برمجة بالذكاء الاصطناعي. ```bash # التثبيت في وكيل محدد @@ -841,6 +856,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | عام | | **OpenCode** | `~/.opencode/skills/` | عام | | **Windsurf** | `~/.windsurf/skills/` | عام | +| **Roo Code** | `.roo/skills/` | مشروع | +| **Cline** | `.cline/skills/` | مشروع | +| **Aider** | `~/.aider/skills/` | عام | +| **Bolt** | `.bolt/skills/` | مشروع | +| **Kilo Code** | `.kilo/skills/` | مشروع | +| **Continue** | `~/.continue/skills/` | عام | +| **Kimi Code** | `~/.kimi/skills/` | عام | --- diff --git a/README.de.md b/README.de.md index f575353..8251323 100644 --- a/README.de.md +++ b/README.de.md @@ -31,6 +31,21 @@ > **[Entwicklungsroadmap und Aufgaben ansehen](https://github.com/users/yusufkaraaslan/projects/2)** - 134 Aufgaben in 10 Kategorien — wählen Sie eine beliebige zum Mitwirken! +## 🌐 Ökosystem + +Skill Seekers ist ein Multi-Repository-Projekt. Hier finden Sie alles: + +| Repository | Beschreibung | Links | +|-----------|-------------|-------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | Kern-CLI & MCP-Server (dieses Repo) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Website & Dokumentation | [Web](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Community-Konfigurationsrepository | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action für CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code Plugin | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew Tap für macOS | | + +> **Möchten Sie beitragen?** Die Website- und Konfigurations-Repos sind ideale Einstiegspunkte für neue Mitwirkende! + ## Die Datenschicht für KI-Systeme **Skill Seekers ist die universelle Vorverarbeitungsschicht**, die zwischen Rohdokumentation und jedem KI-System steht, das diese konsumiert. Ob Sie Claude-Skills, eine LangChain-RAG-Pipeline oder eine Cursor-`.cursorrules`-Datei erstellen — die Datenaufbereitung ist identisch. Sie führen sie einmal durch und exportieren für alle Zielplattformen. @@ -194,7 +209,7 @@ Anstatt tagelange manuelle Vorverarbeitung durchzuführen, erledigt Skill Seeker - **Abwärtskompatibel** - Bestehende Einzelquellen-Konfigurationen funktionieren weiterhin ### Multi-LLM-Plattformunterstützung -- **4 LLM-Plattformen** - Claude AI, Google Gemini, OpenAI ChatGPT, Generisches Markdown +- **12 LLM-Plattformen** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Generisches Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - **Universelles Scraping** - Dieselbe Dokumentation funktioniert für alle Plattformen - **Plattformspezifische Paketierung** - Optimierte Formate für jedes LLM - **Ein-Befehl-Export** - `--target`-Flag wählt die Plattform @@ -581,9 +596,9 @@ Phase 5: Zu Claude hochladen (optional, erfordert API Key) ## Funktionsmatrix -Skill Seekers unterstützt **4 LLM-Plattformen**, **17 Quelltypen** und vollständige Funktionsparität für alle Ziele. +Skill Seekers unterstützt **12 LLM-Plattformen**, **17 Quelltypen** und vollständige Funktionsparität für alle Ziele. -**Plattformen:** Claude AI, Google Gemini, OpenAI ChatGPT, Generisches Markdown +**Plattformen:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Generisches Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Quelltypen:** Dokumentationswebsites, GitHub-Repos, PDFs, Word (.docx), EPUB, Video, lokale Codebasen, Jupyter-Notebooks, lokales HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS-/Atom-Feeds, Man-Pages, Confluence-Wikis, Notion-Seiten, Slack-/Discord-Chatexporte Vollständige Informationen finden Sie in der [vollständigen Funktionsmatrix](docs/FEATURE_MATRIX.md). @@ -819,7 +834,7 @@ In Claude Code einfach fragen: ## Installation für KI-Agenten -Skill Seekers kann Skills automatisch für über 10 KI-Programmieragenten installieren. +Skill Seekers kann Skills automatisch für 18 KI-Programmieragenten installieren. ```bash # Für einen bestimmten Agenten installieren @@ -843,6 +858,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Projekt | +| **Cline** | `.cline/skills/` | Projekt | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Projekt | +| **Kilo Code** | `.kilo/skills/` | Projekt | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- diff --git a/README.es.md b/README.es.md index 6547b95..7d8b7dc 100644 --- a/README.es.md +++ b/README.es.md @@ -31,6 +31,21 @@ > 📋 **[Ver hoja de ruta y tareas de desarrollo](https://github.com/users/yusufkaraaslan/projects/2)** - ¡134 tareas en 10 categorías, elige cualquiera para contribuir! +## 🌐 Ecosistema + +Skill Seekers es un proyecto multi-repositorio. Aquí es donde vive todo: + +| Repositorio | Descripción | Enlaces | +|------------|-------------|---------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | CLI principal y servidor MCP (este repo) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Sitio web y documentación | [Web](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Repositorio de configuraciones comunitarias | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action para CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Plugin para Claude Code | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap para macOS | | + +> **¿Quieres contribuir?** ¡Los repos del sitio web y configuraciones son excelentes puntos de partida para nuevos colaboradores! + ## 🧠 La capa de datos para sistemas de IA **Skill Seekers es la capa universal de preprocesamiento** que se ubica entre la documentación sin procesar y cada sistema de IA que la consume. Ya sea que estés construyendo Claude Skills, un pipeline RAG con LangChain o un archivo `.cursorrules` para Cursor, la preparación de datos es idéntica. Lo haces una vez y exportas a todos los destinos. @@ -239,7 +254,7 @@ En lugar de pasar días en preprocesamiento manual, Skill Seekers: - ✅ **Compatible con versiones anteriores** - Las configuraciones de fuente única legacy siguen funcionando ### 🤖 Soporte para múltiples plataformas LLM -- ✅ **4 plataformas LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, Markdown genérico +- ✅ **12 plataformas LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown genérico, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **Extracción universal** - La misma documentación funciona para todas las plataformas - ✅ **Empaquetado específico por plataforma** - Formatos optimizados para cada LLM - ✅ **Exportación con un solo comando** - El flag `--target` selecciona la plataforma @@ -689,9 +704,9 @@ skill-seekers install --config react --dry-run ## 📊 Matriz de funcionalidades -Skill Seekers soporta **4 plataformas LLM**, **17 tipos de fuentes** y paridad total de funcionalidades en todos los destinos. +Skill Seekers soporta **12 plataformas LLM**, **17 tipos de fuentes** y paridad total de funcionalidades en todos los destinos. -**Plataformas:** Claude AI, Google Gemini, OpenAI ChatGPT, Markdown genérico +**Plataformas:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown genérico, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Tipos de fuentes:** Sitios web de documentación, repos de GitHub, PDFs, Word (.docx), EPUB, Video, Bases de código locales, Jupyter Notebooks, HTML local, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), feeds RSS/Atom, páginas de manual, wikis de Confluence, páginas de Notion, exportaciones de chat de Slack/Discord Consulta la [Matriz completa de funcionalidades](docs/FEATURE_MATRIX.md) para información detallada de soporte por plataforma y funcionalidad. @@ -929,7 +944,7 @@ En Claude Code, simplemente pide: ## 🤖 Instalación en agentes de IA -Skill Seekers puede instalar automáticamente skills en más de 10 agentes de programación con IA. +Skill Seekers puede instalar automáticamente skills en 18 agentes de programación con IA. ```bash # Instalar en un agente específico @@ -953,6 +968,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Proyecto | +| **Cline** | `.cline/skills/` | Proyecto | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Proyecto | +| **Kilo Code** | `.kilo/skills/` | Proyecto | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- diff --git a/README.fr.md b/README.fr.md index 1d8a129..0e55c54 100644 --- a/README.fr.md +++ b/README.fr.md @@ -31,6 +31,21 @@ > 📋 **[Consultez la feuille de route et les tâches](https://github.com/users/yusufkaraaslan/projects/2)** - 134 tâches réparties en 10 catégories, choisissez-en une pour contribuer ! +## 🌐 Écosystème + +Skill Seekers est un projet multi-dépôts. Voici où se trouve chaque partie : + +| Dépôt | Description | Liens | +|-------|-------------|-------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | CLI principal et serveur MCP (ce dépôt) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Site web et documentation | [Site](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Dépôt de configurations communautaires | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action pour CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Plugin Claude Code | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap pour macOS | | + +> **Vous voulez contribuer ?** Les dépôts du site web et des configurations sont d'excellents points de départ pour les nouveaux contributeurs ! + ## 🧠 La couche de données pour les systèmes d'IA **Skill Seekers est la couche de prétraitement universelle** qui se situe entre la documentation brute et tous les systèmes d'IA qui la consomment. Que vous construisiez des compétences Claude, un pipeline RAG LangChain ou un fichier `.cursorrules` pour Cursor — la préparation des données est identique. Vous le faites une seule fois, et exportez vers toutes les cibles. @@ -254,7 +269,7 @@ Au lieu de passer des jours en prétraitement manuel, Skill Seekers : - ✅ **Rétrocompatibilité** - Les configurations à source unique héritées fonctionnent toujours ### 🤖 Support multi-plateformes LLM -- ✅ **4 plateformes LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, Markdown générique +- ✅ **12 plateformes LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown générique, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **Scraping universel** - La même documentation fonctionne pour toutes les plateformes - ✅ **Empaquetage spécifique** - Formats optimisés pour chaque LLM - ✅ **Export en une commande** - Le flag `--target` sélectionne la plateforme @@ -704,9 +719,9 @@ skill-seekers install --config react --dry-run ## 📊 Matrice de fonctionnalités -Skill Seekers prend en charge **4 plateformes LLM**, **17 types de sources** et une parité fonctionnelle complète sur toutes les cibles. +Skill Seekers prend en charge **12 plateformes LLM**, **17 types de sources** et une parité fonctionnelle complète sur toutes les cibles. -**Plateformes :** Claude AI, Google Gemini, OpenAI ChatGPT, Markdown générique +**Plateformes :** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown générique, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Types de sources :** Sites de documentation, dépôts GitHub, PDF, Word (.docx), EPUB, Vidéo, Bases de code locales, Notebooks Jupyter, HTML local, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), Flux RSS/Atom, Pages de manuel, Wikis Confluence, Pages Notion, Exports chat Slack/Discord Consultez la [matrice complète des fonctionnalités](docs/FEATURE_MATRIX.md) pour le support détaillé par plateforme et fonctionnalité. @@ -944,7 +959,7 @@ Dans Claude Code, demandez simplement : ## 🤖 Installation dans les agents IA -Skill Seekers peut installer automatiquement des compétences dans plus de 10 agents de codage IA. +Skill Seekers peut installer automatiquement des compétences dans 18 agents de codage IA. ```bash # Installer dans un agent spécifique @@ -968,6 +983,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Projet | +| **Cline** | `.cline/skills/` | Projet | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Projet | +| **Kilo Code** | `.kilo/skills/` | Projet | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- diff --git a/README.hi.md b/README.hi.md index 375a163..3e8fc21 100644 --- a/README.hi.md +++ b/README.hi.md @@ -31,6 +31,21 @@ > 📋 **[विकास रोडमैप और कार्य देखें](https://github.com/users/yusufkaraaslan/projects/2)** - 10 श्रेणियों में 134 कार्य, किसी भी में योगदान करें! +## 🌐 इकोसिस्टम + +Skill Seekers एक मल्टी-रिपॉजिटरी प्रोजेक्ट है। यहां सब कुछ मौजूद है: + +| रिपॉजिटरी | विवरण | लिंक | +|-----------|--------|------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | कोर CLI और MCP सर्वर (यह रिपो) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | वेबसाइट और डॉक्यूमेंटेशन | [साइट](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | सामुदायिक कॉन्फिग रिपॉजिटरी | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code प्लगइन | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | macOS के लिए Homebrew tap | | + +> **योगदान करना चाहते हैं?** वेबसाइट और कॉन्फिग रिपॉजिटरी नए योगदानकर्ताओं के लिए बेहतरीन शुरुआती बिंदु हैं! + ## 🧠 AI सिस्टम के लिए डेटा लेयर **Skill Seekers एक सार्वभौमिक प्रीप्रोसेसिंग लेयर है** जो कच्चे दस्तावेज़ों और उनका उपयोग करने वाले सभी AI सिस्टम के बीच स्थित है। चाहे आप Claude कौशल, LangChain RAG पाइपलाइन, या Cursor `.cursorrules` फ़ाइल बना रहे हों—डेटा तैयारी पूरी तरह समान है। बस एक बार करें, और सभी लक्ष्यों पर निर्यात करें। @@ -254,7 +269,7 @@ Skill Seekers **AI सिस्टम के लिए डेटा लेयर - ✅ **पश्चगामी संगत** - पुराने एकल-स्रोत कॉन्फ़िग अभी भी काम करते हैं ### 🤖 बहु-LLM प्लेटफ़ॉर्म समर्थन -- ✅ **4 LLM प्लेटफ़ॉर्म** - Claude AI, Google Gemini, OpenAI ChatGPT, जेनेरिक Markdown +- ✅ **12 LLM प्लेटफ़ॉर्म** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, जेनेरिक Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **सार्वभौमिक स्क्रैपिंग** - समान दस्तावेज़ सभी प्लेटफ़ॉर्म के लिए काम करते हैं - ✅ **प्लेटफ़ॉर्म-विशिष्ट पैकेजिंग** - प्रत्येक LLM के लिए अनुकूलित प्रारूप - ✅ **एक-कमांड निर्यात** - `--target` फ़्लैग प्लेटफ़ॉर्म चुनता है @@ -699,9 +714,9 @@ skill-seekers install --config react --dry-run ## 📊 फ़ीचर मैट्रिक्स -Skill Seekers **4 LLM प्लेटफ़ॉर्म**, **17 स्रोत प्रकार** और सभी लक्ष्यों पर पूर्ण फ़ीचर समानता का समर्थन करता है। +Skill Seekers **12 LLM प्लेटफ़ॉर्म**, **17 स्रोत प्रकार** और सभी लक्ष्यों पर पूर्ण फ़ीचर समानता का समर्थन करता है। -**प्लेटफ़ॉर्म:** Claude AI, Google Gemini, OpenAI ChatGPT, जेनेरिक Markdown +**प्लेटफ़ॉर्म:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, जेनेरिक Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **स्रोत प्रकार:** डॉक्यूमेंटेशन वेबसाइट, GitHub रिपो, PDF, Word (.docx), EPUB, वीडियो, स्थानीय कोडबेस, Jupyter Notebook, स्थानीय HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS/Atom फ़ीड, Man पेज, Confluence विकी, Notion पेज, Slack/Discord चैट एक्सपोर्ट विस्तृत प्लेटफ़ॉर्म और फ़ीचर समर्थन के लिए [पूर्ण फ़ीचर मैट्रिक्स](docs/FEATURE_MATRIX.md) देखें। @@ -939,7 +954,7 @@ Claude Code में, बस पूछें: ## 🤖 AI एजेंट में इंस्टॉल करना -Skill Seekers स्वचालित रूप से 10+ AI कोडिंग एजेंट में कौशल इंस्टॉल कर सकता है। +Skill Seekers स्वचालित रूप से 18 AI कोडिंग एजेंट में कौशल इंस्टॉल कर सकता है। ```bash # विशिष्ट एजेंट में इंस्टॉल करें @@ -963,6 +978,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | वैश्विक | | **OpenCode** | `~/.opencode/skills/` | वैश्विक | | **Windsurf** | `~/.windsurf/skills/` | वैश्विक | +| **Roo Code** | `.roo/skills/` | प्रोजेक्ट | +| **Cline** | `.cline/skills/` | प्रोजेक्ट | +| **Aider** | `~/.aider/skills/` | वैश्विक | +| **Bolt** | `.bolt/skills/` | प्रोजेक्ट | +| **Kilo Code** | `.kilo/skills/` | प्रोजेक्ट | +| **Continue** | `~/.continue/skills/` | वैश्विक | +| **Kimi Code** | `~/.kimi/skills/` | वैश्विक | --- diff --git a/README.ja.md b/README.ja.md index ab76ae8..62c29e4 100644 --- a/README.ja.md +++ b/README.ja.md @@ -29,6 +29,21 @@ > 📋 **[開発ロードマップとタスクを確認](https://github.com/users/yusufkaraaslan/projects/2)** - 10 カテゴリで 134 タスク、好きなものを選んで貢献できます! +## 🌐 エコシステム + +Skill Seekers はマルチリポジトリプロジェクトです。各リポジトリの役割: + +| リポジトリ | 説明 | リンク | +|-----------|------|-------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | コア CLI & MCP サーバー(このリポジトリ) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | ウェブサイト&ドキュメント | [サイト](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | コミュニティ設定リポジトリ | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code プラグイン | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | macOS Homebrew tap | | + +> **貢献したいですか?** ウェブサイトと設定リポジトリは新しい貢献者に最適です! + ## 🧠 AI システムのデータレイヤー **Skill Seekers は汎用的な前処理レイヤー**であり、生のドキュメントとそれを利用するすべての AI システムの間に位置します。Claude スキル、LangChain RAG パイプライン、Cursor の `.cursorrules` ファイルのいずれを構築する場合でも、データの準備作業は同じです。一度実行すれば、すべてのターゲットにエクスポートできます。 @@ -192,7 +207,7 @@ Skill Seekers は以下のステップで数日の手動前処理作業を代替 - ✅ **後方互換性** - レガシーの単一ソース設定は引き続き動作 ### 🤖 マルチ LLM プラットフォームサポート -- ✅ **4 つの LLM プラットフォーム** - Claude AI、Google Gemini、OpenAI ChatGPT、汎用 Markdown +- ✅ **12 の LLM プラットフォーム** - Claude AI、Google Gemini、OpenAI ChatGPT、MiniMax AI、汎用 Markdown、OpenCode、Kimi、DeepSeek、Qwen、OpenRouter、Together AI、Fireworks AI - ✅ **汎用スクレイピング** - 同じドキュメントがすべてのプラットフォームで使用可能 - ✅ **プラットフォーム固有のパッケージング** - 各 LLM に最適化されたフォーマット - ✅ **ワンコマンドエクスポート** - `--target` フラグでプラットフォームを選択 @@ -576,9 +591,9 @@ skill-seekers install --config react --dry-run ## 📊 機能マトリックス -Skill Seekers は **4 つの LLM プラットフォーム**、**17 種類のソースタイプ**、**5 つのスキルモード**をサポートし、機能は完全に同等です。 +Skill Seekers は **12 の LLM プラットフォーム**、**17 種類のソースタイプ**、**5 つのスキルモード**をサポートし、機能は完全に同等です。 -**プラットフォーム:** Claude AI、Google Gemini、OpenAI ChatGPT、汎用 Markdown +**プラットフォーム:** Claude AI、Google Gemini、OpenAI ChatGPT、MiniMax AI、汎用 Markdown、OpenCode、Kimi、DeepSeek、Qwen、OpenRouter、Together AI、Fireworks AI **ソースタイプ:** ドキュメントサイト、GitHub リポジトリ、PDF、Word、EPUB、動画、ローカルコードベース、Jupyter Notebook、ローカル HTML、OpenAPI/Swagger 仕様、AsciiDoc ドキュメント、PowerPoint プレゼンテーション、RSS/Atom フィード、Man ページ、Confluence Wiki、Notion ページ、Slack/Discord チャットエクスポート **スキルモード:** ドキュメント、GitHub、PDF、統合マルチソース、ローカルリポジトリ @@ -815,7 +830,7 @@ Claude Code で直接聞くだけ: ## 🤖 AI エージェントへのインストール -Skill Seekers は 10 以上の AI コーディングエージェントにスキルを自動インストールできます。 +Skill Seekers は 18 の AI コーディングエージェントにスキルを自動インストールできます。 ```bash # 特定のエージェントにインストール @@ -839,6 +854,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | グローバル | | **OpenCode** | `~/.opencode/skills/` | グローバル | | **Windsurf** | `~/.windsurf/skills/` | グローバル | +| **Roo Code** | `.roo/skills/` | プロジェクト | +| **Cline** | `.cline/skills/` | プロジェクト | +| **Aider** | `~/.aider/skills/` | グローバル | +| **Bolt** | `.bolt/skills/` | プロジェクト | +| **Kilo Code** | `.kilo/skills/` | プロジェクト | +| **Continue** | `~/.continue/skills/` | グローバル | +| **Kimi Code** | `~/.kimi/skills/` | グローバル | --- diff --git a/README.ko.md b/README.ko.md index ff523dd..f9bcdc6 100644 --- a/README.ko.md +++ b/README.ko.md @@ -31,6 +31,21 @@ > 📋 **[개발 로드맵 및 작업 보기](https://github.com/users/yusufkaraaslan/projects/2)** - 10개 카테고리에 걸친 134개 작업, 원하는 것을 선택하여 기여하세요! +## 🌐 에코시스템 + +Skill Seekers는 다중 저장소 프로젝트입니다. 각 저장소의 역할: + +| 저장소 | 설명 | 링크 | +|--------|------|------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | 핵심 CLI & MCP 서버 (이 저장소) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | 웹사이트 & 문서 | [사이트](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | 커뮤니티 설정 저장소 | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code 플러그인 | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | macOS Homebrew tap | | + +> **기여하고 싶으신가요?** 웹사이트와 설정 저장소는 새 기여자에게 좋은 시작점입니다! + ## 🧠 AI 시스템을 위한 데이터 레이어 **Skill Seekers는 범용 전처리 레이어**로, 원시 문서와 이를 활용하는 모든 AI 시스템 사이에 위치합니다. Claude 스킬을 구축하든, LangChain RAG 파이프라인을 만들든, Cursor `.cursorrules` 파일을 작성하든 — 데이터 준비 작업은 동일합니다. 한 번만 수행하면 모든 대상 플랫폼으로 내보낼 수 있습니다. @@ -194,7 +209,7 @@ Skill Seekers는 수일간의 수동 전처리 작업을 대체합니다: - ✅ **하위 호환** - 레거시 단일 소스 설정 계속 작동 ### 🤖 다중 LLM 플랫폼 지원 -- ✅ **4개 LLM 플랫폼** - Claude AI, Google Gemini, OpenAI ChatGPT, 범용 Markdown +- ✅ **12개 LLM 플랫폼** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, 범용 Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **범용 스크래핑** - 동일한 문서가 모든 플랫폼에 적용 - ✅ **플랫폼별 패키징** - 각 LLM에 최적화된 형식 - ✅ **원커맨드 내보내기** - `--target` 플래그로 플랫폼 선택 @@ -581,9 +596,9 @@ skill-seekers install --config react --dry-run ## 📊 기능 매트릭스 -Skill Seekers는 **4개 LLM 플랫폼**, **17가지 소스 유형**을 지원하며 모든 대상에서 완전한 기능 동등성을 제공합니다. +Skill Seekers는 **12개 LLM 플랫폼**, **17가지 소스 유형**을 지원하며 모든 대상에서 완전한 기능 동등성을 제공합니다. -**플랫폼:** Claude AI, Google Gemini, OpenAI ChatGPT, 범용 Markdown +**플랫폼:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, 범용 Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **소스 유형:** 문서 사이트, GitHub 저장소, PDF, Word (.docx), EPUB, 동영상, 로컬 코드베이스, Jupyter 노트북, 로컬 HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS/Atom 피드, Man 페이지, Confluence 위키, Notion 페이지, Slack/Discord 채팅 내보내기 전체 내용은 [전체 기능 매트릭스](docs/FEATURE_MATRIX.md)를 참조하세요. @@ -819,7 +834,7 @@ Claude Code에서 직접 요청: ## 🤖 AI 에이전트에 설치 -Skill Seekers는 10개 이상의 AI 코딩 에이전트에 스킬을 자동으로 설치할 수 있습니다. +Skill Seekers는 18개의 AI 코딩 에이전트에 스킬을 자동으로 설치할 수 있습니다. ```bash # 특정 에이전트에 설치 @@ -843,6 +858,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | 전역 | | **OpenCode** | `~/.opencode/skills/` | 전역 | | **Windsurf** | `~/.windsurf/skills/` | 전역 | +| **Roo Code** | `.roo/skills/` | 프로젝트 | +| **Cline** | `.cline/skills/` | 프로젝트 | +| **Aider** | `~/.aider/skills/` | 전역 | +| **Bolt** | `.bolt/skills/` | 프로젝트 | +| **Kilo Code** | `.kilo/skills/` | 프로젝트 | +| **Continue** | `~/.continue/skills/` | 전역 | +| **Kimi Code** | `~/.kimi/skills/` | 전역 | --- diff --git a/README.md b/README.md index 14299c5..431f1b6 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ English | [简体中文](README.zh-CN.md) | [日本語](README.ja.md) | [한국 [![Website](https://img.shields.io/badge/Website-skillseekersweb.com-blue.svg)](https://skillseekersweb.com/) [![Twitter Follow](https://img.shields.io/twitter/follow/_yUSyUS_?style=social)](https://x.com/_yUSyUS_) [![GitHub Repo stars](https://img.shields.io/github/stars/yusufkaraaslan/Skill_Seekers?style=social)](https://github.com/yusufkaraaslan/Skill_Seekers) +[![PyPI Downloads](https://static.pepy.tech/personalized-badge/skill-seekers?period=total&units=INTERNATIONAL_SYSTEM&left_color=BLACK&right_color=GREEN&left_text=downloads)](https://pepy.tech/projects/skill-seekers) + +yusufkaraaslan%2FSkill_Seekers | Trendshift **🧠 The data layer for AI systems.** Skill Seekers turns documentation sites, GitHub repos, PDFs, videos, notebooks, wikis, and 10+ more source types into structured knowledge assets—ready to power AI Skills (Claude, Gemini, OpenAI), RAG pipelines (LangChain, LlamaIndex, Pinecone), and AI coding assistants (Cursor, Windsurf, Cline) in minutes, not hours. @@ -25,6 +28,21 @@ English | [简体中文](README.zh-CN.md) | [日本語](README.ja.md) | [한국 > 📋 **[View Development Roadmap & Tasks](https://github.com/users/yusufkaraaslan/projects/2)** - 134 tasks across 10 categories, pick any to contribute! +## 🌐 Ecosystem + +Skill Seekers is a multi-repo project. Here's where everything lives: + +| Repository | Description | Links | +|-----------|-------------|-------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | Core CLI & MCP server (this repo) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Website & documentation | [Live](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Community config repository | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action for CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code plugin | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap for macOS | | + +> **Want to contribute?** The website and configs repos are great starting points for new contributors! + ## 🧠 The Data Layer for AI Systems **Skill Seekers is the universal preprocessing layer** that sits between raw documentation and every AI system that consumes it. Whether you are building Claude skills, a LangChain RAG pipeline, or a Cursor `.cursorrules` file — the data preparation is identical. You do it once, and export to all targets. @@ -248,7 +266,7 @@ Instead of spending days on manual preprocessing, Skill Seekers: - ✅ **Backward Compatible** - Legacy single-source configs still work ### 🤖 Multi-LLM Platform Support -- ✅ **4 LLM Platforms** - Claude AI, Google Gemini, OpenAI ChatGPT, Generic Markdown +- ✅ **12 LLM Platforms** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Generic Markdown, OpenCode, Kimi (Moonshot AI), DeepSeek AI, Qwen (Alibaba), OpenRouter, Together AI, Fireworks AI - ✅ **Universal Scraping** - Same documentation works for all platforms - ✅ **Platform-Specific Packaging** - Optimized formats for each LLM - ✅ **One-Command Export** - `--target` flag selects platform @@ -260,6 +278,7 @@ Instead of spending days on manual preprocessing, Skill Seekers: | **Claude AI** | ZIP + YAML | ✅ Auto | ✅ Yes | ANTHROPIC_API_KEY | ANTHROPIC_BASE_URL | | **Google Gemini** | tar.gz | ✅ Auto | ✅ Yes | GOOGLE_API_KEY | - | | **OpenAI ChatGPT** | ZIP + Vector Store | ✅ Auto | ✅ Yes | OPENAI_API_KEY | - | +| **MiniMax AI** | ZIP + Knowledge Files | ✅ Auto | ✅ Yes | MINIMAX_API_KEY | - | | **Generic Markdown** | ZIP | ❌ Manual | ❌ No | - | - | ```bash @@ -277,6 +296,11 @@ pip install skill-seekers[openai] skill-seekers package output/react/ --target openai skill-seekers upload react-openai.zip --target openai +# MiniMax AI +pip install skill-seekers[minimax] +skill-seekers package output/react/ --target minimax +skill-seekers upload react-minimax.zip --target minimax + # Generic Markdown (universal export) skill-seekers package output/react/ --target markdown # Use the markdown files directly in any LLM @@ -312,6 +336,9 @@ pip install skill-seekers[gemini] # Install with OpenAI support pip install skill-seekers[openai] +# Install with MiniMax support +pip install skill-seekers[minimax] + # Install with all LLM platforms pip install skill-seekers[all-llms] ``` @@ -698,21 +725,21 @@ skill-seekers install --config react --dry-run ## 📊 Feature Matrix -Skill Seekers supports **4 LLM platforms**, **17 source types**, and full feature parity across all targets. +Skill Seekers supports **12 LLM platforms**, **17 source types**, and full feature parity across all targets. -**Platforms:** Claude AI, Google Gemini, OpenAI ChatGPT, Generic Markdown +**Platforms:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Generic Markdown, OpenCode, Kimi (Moonshot AI), DeepSeek AI, Qwen (Alibaba), OpenRouter, Together AI, Fireworks AI **Source Types:** Documentation websites, GitHub repos, PDFs, Word (.docx), EPUB, Video, Local codebases, Jupyter Notebooks, Local HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS/Atom feeds, Man pages, Confluence wikis, Notion pages, Slack/Discord chat exports See [Complete Feature Matrix](docs/FEATURE_MATRIX.md) for detailed platform and feature support. ### Quick Platform Comparison -| Feature | Claude | Gemini | OpenAI | Markdown | -|---------|--------|--------|--------|----------| -| Format | ZIP + YAML | tar.gz | ZIP + Vector | ZIP | -| Upload | ✅ API | ✅ API | ✅ API | ❌ Manual | -| Enhancement | ✅ Sonnet 4 | ✅ 2.0 Flash | ✅ GPT-4o | ❌ None | -| All Skill Modes | ✅ | ✅ | ✅ | ✅ | +| Feature | Claude | Gemini | OpenAI | MiniMax | Markdown | +|---------|--------|--------|--------|--------|----------| +| Format | ZIP + YAML | tar.gz | ZIP + Vector | ZIP + Knowledge | ZIP | +| Upload | ✅ API | ✅ API | ✅ API | ✅ API | ❌ Manual | +| Enhancement | ✅ Sonnet 4 | ✅ 2.0 Flash | ✅ GPT-4o | ✅ M2.7 | ❌ None | +| All Skill Modes | ✅ | ✅ | ✅ | ✅ | ✅ | --- @@ -885,6 +912,27 @@ graph LR 3. **Enhance**: AI analyzes docs and creates comprehensive SKILL.md with examples 4. **Package**: Bundles everything into a Claude-ready `.zip` file +## Architecture + +The system is organized into **8 core modules** and **5 utility modules** (~200 classes total): + +![Package Overview](docs/UML/exports/00_package_overview.png) + +| Module | Purpose | Key Classes | +|--------|---------|-------------| +| **CLICore** | Git-style command dispatcher | `CLIDispatcher`, `SourceDetector`, `CreateCommand` | +| **Scrapers** | 17 source-type extractors | `DocToSkillConverter`, `GitHubScraper`, `UnifiedScraper` | +| **Adaptors** | 20+ output platform formats | `SkillAdaptor` (ABC), `ClaudeAdaptor`, `LangChainAdaptor` | +| **Analysis** | C3.x codebase analysis pipeline | `UnifiedCodebaseAnalyzer`, `PatternRecognizer`, 10 GoF detectors | +| **Enhancement** | AI-powered skill improvement | `AIEnhancer`, `UnifiedEnhancer`, `WorkflowEngine` | +| **Packaging** | Package, upload, install skills | `PackageSkill`, `InstallAgent` | +| **MCP** | FastMCP server (34 tools) | `SkillSeekerMCPServer`, 8 tool modules | +| **Sync** | Doc change detection | `ChangeDetector`, `SyncMonitor`, `Notifier` | + +Utility modules: **Parsers** (28 CLI parsers), **Storage** (S3/GCS/Azure), **Embedding** (multi-provider vectors), **Benchmark** (performance), **Utilities** (16 shared helpers). + +Full UML diagrams: **[docs/UML_ARCHITECTURE.md](docs/UML_ARCHITECTURE.md)** | StarUML project: `docs/UML/skill_seekers.mdj` | HTML API reference: `docs/UML/html/` + ## 📋 Prerequisites **Before you start, make sure you have:** @@ -938,7 +986,7 @@ In Claude Code, just ask: ## 🤖 Installing to AI Agents -Skill Seekers can automatically install skills to 10+ AI coding agents. +Skill Seekers can automatically install skills to 18 AI coding agents. ```bash # Install to specific agent @@ -962,6 +1010,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Project | +| **Cline** | `.cline/skills/` | Project | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Project | +| **Kilo Code** | `.kilo/skills/` | Project | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- @@ -1145,6 +1200,12 @@ skill-seekers config --github - **[TROUBLESHOOTING.md](TROUBLESHOOTING.md)** - Common issues and solutions - **[docs/QUICK_REFERENCE.md](docs/QUICK_REFERENCE.md)** - One-page cheat sheet +### Architecture +- **[docs/UML_ARCHITECTURE.md](docs/UML_ARCHITECTURE.md)** - UML architecture overview with 14 diagrams +- **[docs/UML/exports/](docs/UML/exports/)** - PNG diagram exports (package overview + 13 class diagrams) +- **[docs/UML/html/](docs/UML/html/index.html/index.html)** - Full HTML API reference (all classes, operations, attributes) +- **[docs/UML/skill_seekers.mdj](docs/UML/skill_seekers.mdj)** - StarUML project file (open with [StarUML](https://staruml.io/)) + ### Guides - **[docs/LARGE_DOCUMENTATION.md](docs/LARGE_DOCUMENTATION.md)** - Handle 10K-40K+ page docs - **[ASYNC_SUPPORT.md](ASYNC_SUPPORT.md)** - Async mode guide (2-3x faster scraping) diff --git a/README.pt-BR.md b/README.pt-BR.md index b9ed56d..ba18588 100644 --- a/README.pt-BR.md +++ b/README.pt-BR.md @@ -31,6 +31,21 @@ > 📋 **[Veja o Roteiro de Desenvolvimento e Tarefas](https://github.com/users/yusufkaraaslan/projects/2)** - 134 tarefas em 10 categorias, escolha qualquer uma para contribuir! +## 🌐 Ecossistema + +Skill Seekers é um projeto multi-repositório. Aqui está onde tudo se encontra: + +| Repositório | Descrição | Links | +|------------|-----------|-------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | CLI principal e servidor MCP (este repo) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Website e documentação | [Site](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Repositório de configurações da comunidade | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action para CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Plugin Claude Code | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap para macOS | | + +> **Quer contribuir?** Os repos do website e configurações são ótimos pontos de partida para novos contribuidores! + ## 🧠 A Camada de Dados para Sistemas de IA **Skill Seekers é a camada universal de pré-processamento** que fica entre a documentação bruta e todo sistema de IA que a consome. Seja para construir Claude Skills, um pipeline RAG com LangChain ou um arquivo `.cursorrules` para o Cursor — a preparação dos dados é idêntica. Faça uma vez e exporte para todos os destinos. @@ -239,7 +254,7 @@ O Skill Seekers substitui dias de pré-processamento manual com os seguintes pas - ✅ **Retrocompatível** - Configurações legadas de fonte única continuam funcionando ### 🤖 Suporte a Múltiplas Plataformas LLM -- ✅ **4 Plataformas LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, Markdown Genérico +- ✅ **12 Plataformas LLM** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown Genérico, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **Coleta Universal** - A mesma documentação funciona para todas as plataformas - ✅ **Empacotamento Específico por Plataforma** - Formatos otimizados para cada LLM - ✅ **Exportação com Um Comando** - Flag `--target` seleciona a plataforma @@ -689,9 +704,9 @@ skill-seekers install --config react --dry-run ## 📊 Matriz de Funcionalidades -O Skill Seekers suporta **4 plataformas LLM**, **17 tipos de fontes** e paridade completa de funcionalidades em todos os destinos. +O Skill Seekers suporta **12 plataformas LLM**, **17 tipos de fontes** e paridade completa de funcionalidades em todos os destinos. -**Plataformas:** Claude AI, Google Gemini, OpenAI ChatGPT, Markdown Genérico +**Plataformas:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Markdown Genérico, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Tipos de Fontes:** Sites de documentação, repositórios GitHub, PDFs, Word (.docx), EPUB, Vídeo, Codebases locais, Jupyter Notebooks, HTML local, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), feeds RSS/Atom, Man pages, wikis Confluence, páginas Notion, exportações de chat Slack/Discord Consulte a [Matriz Completa de Funcionalidades](docs/FEATURE_MATRIX.md) para suporte detalhado por plataforma e funcionalidade. @@ -929,7 +944,7 @@ No Claude Code, basta pedir: ## 🤖 Instalando em Agentes de IA -O Skill Seekers pode instalar automaticamente skills em mais de 10 agentes de programação com IA. +O Skill Seekers pode instalar automaticamente skills em 18 agentes de programação com IA. ```bash # Instalar em agente específico @@ -953,6 +968,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Projeto | +| **Cline** | `.cline/skills/` | Projeto | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Projeto | +| **Kilo Code** | `.kilo/skills/` | Projeto | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- diff --git a/README.ru.md b/README.ru.md index 32ade4d..ba1dcfa 100644 --- a/README.ru.md +++ b/README.ru.md @@ -29,6 +29,21 @@ > 📋 **[Смотрите дорожную карту разработки и задачи](https://github.com/users/yusufkaraaslan/projects/2)** — 134 задачи в 10 категориях, выберите любую для участия! +## 🌐 Экосистема + +Skill Seekers — это мульти-репозиторный проект. Вот где находится каждая часть: + +| Репозиторий | Описание | Ссылки | +|------------|----------|--------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | Основной CLI и MCP сервер (этот репозиторий) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Веб-сайт и документация | [Сайт](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Репозиторий конфигураций сообщества | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action для CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Плагин Claude Code | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | Homebrew tap для macOS | | + +> **Хотите внести вклад?** Репозитории сайта и конфигураций — отличная отправная точка для новых участников! + ## 🧠 Слой данных для ИИ-систем **Skill Seekers — это универсальный слой предобработки**, расположенный между необработанной документацией и всеми ИИ-системами, которые её потребляют. Независимо от того, создаёте ли вы навыки для Claude, RAG-конвейер LangChain или файл `.cursorrules` для Cursor — подготовка данных одинакова. Выполните её один раз и экспортируйте во все целевые платформы. @@ -192,7 +207,7 @@ Skill Seekers заменяет дни ручной предобработки с - ✅ **Обратная совместимость** — устаревшие одноисточниковые конфигурации продолжают работать ### 🤖 Поддержка нескольких LLM-платформ -- ✅ **4 LLM-платформы** — Claude AI, Google Gemini, OpenAI ChatGPT, универсальный Markdown +- ✅ **12 LLM-платформ** — Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, универсальный Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **Универсальное сканирование** — одна и та же документация для всех платформ - ✅ **Платформоспецифичная упаковка** — оптимизированные форматы для каждой LLM - ✅ **Экспорт одной командой** — флаг `--target` для выбора платформы @@ -579,9 +594,9 @@ skill-seekers install --config react --dry-run ## 📊 Матрица функций -Skill Seekers поддерживает **4 LLM-платформы**, **17 типов источников** и полный паритет функций по всем целевым платформам. +Skill Seekers поддерживает **12 LLM-платформ**, **17 типов источников** и полный паритет функций по всем целевым платформам. -**Платформы:** Claude AI, Google Gemini, OpenAI ChatGPT, универсальный Markdown +**Платформы:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, универсальный Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Типы источников:** Документация сайтов, репозитории GitHub, PDF, Word (.docx), EPUB, видео, локальные кодовые базы, Jupyter-ноутбуки, локальный HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS/Atom-ленты, man-страницы, вики Confluence, страницы Notion, экспорты чатов Slack/Discord Подробности см. в [Полной матрице функций](docs/FEATURE_MATRIX.md). @@ -817,7 +832,7 @@ skill-seekers package output/react/ ## 🤖 Установка в ИИ-агенты -Skill Seekers может автоматически устанавливать навыки в 10+ ИИ-агентов для программирования. +Skill Seekers может автоматически устанавливать навыки в 18 ИИ-агентов для программирования. ```bash # Установка в конкретный агент @@ -841,6 +856,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Глобальный | | **OpenCode** | `~/.opencode/skills/` | Глобальный | | **Windsurf** | `~/.windsurf/skills/` | Глобальный | +| **Roo Code** | `.roo/skills/` | Проектный | +| **Cline** | `.cline/skills/` | Проектный | +| **Aider** | `~/.aider/skills/` | Глобальный | +| **Bolt** | `.bolt/skills/` | Проектный | +| **Kilo Code** | `.kilo/skills/` | Проектный | +| **Continue** | `~/.continue/skills/` | Глобальный | +| **Kimi Code** | `~/.kimi/skills/` | Глобальный | --- diff --git a/README.tr.md b/README.tr.md index 8344f6a..c5d9ff4 100644 --- a/README.tr.md +++ b/README.tr.md @@ -31,6 +31,21 @@ > 📋 **[Geliştirme Yol Haritası ve Görevleri Görüntüleyin](https://github.com/users/yusufkaraaslan/projects/2)** - 10 kategoride 134 görev, istediğinizi seçip katkıda bulunun! +## 🌐 Ekosistem + +Skill Seekers çoklu depo projesidır. Her şeyin bulunduğu yerler: + +| Depo | Açıklama | Bağlantılar | +|------|----------|-------------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | Ana CLI ve MCP sunucusu (bu depo) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | Web sitesi ve belgeler | [Site](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | Topluluk yapılandırma deposu | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code eklentisi | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | macOS için Homebrew tap | | + +> **Katkıda bulunmak ister misiniz?** Web sitesi ve yapılandırma depoları yeni katkıda bulunanlar için harika başlangıç noktalarıdır! + ## 🧠 Yapay Zeka Sistemleri İçin Veri Katmanı **Skill Seekers, evrensel bir ön işleme katmanıdır** ve ham dokümantasyon ile onu tüketen tüm yapay zeka sistemleri arasında yer alır. İster Claude yetenekleri, ister LangChain RAG hattı, ister Cursor `.cursorrules` dosyası oluşturuyor olun — veri hazırlık süreci aynıdır. Bir kez yaparsınız, tüm hedef platformlara dışa aktarırsınız. @@ -254,7 +269,7 @@ Skill Seekers, günlerce süren manuel ön işleme çalışması yerine şunlar - ✅ **Geriye Dönük Uyumluluk** - Eski tek kaynaklı yapılandırmalar çalışmaya devam eder ### 🤖 Çoklu LLM Platform Desteği -- ✅ **4 LLM Platformu** - Claude AI, Google Gemini, OpenAI ChatGPT, Genel Markdown +- ✅ **12 LLM Platformu** - Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Genel Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI - ✅ **Evrensel Tarama** - Aynı dokümantasyon tüm platformlar için çalışır - ✅ **Platforma Özel Paketleme** - Her LLM için optimize edilmiş formatlar - ✅ **Tek Komutla Dışa Aktarma** - `--target` bayrağı ile platform seçimi @@ -703,9 +718,9 @@ skill-seekers install --config react --dry-run ## 📊 Özellik Matrisi -Skill Seekers **4 LLM platformu**, **17 kaynak türü** ve tüm hedeflerde tam özellik eşitliğini destekler. +Skill Seekers **12 LLM platformu**, **17 kaynak türü** ve tüm hedeflerde tam özellik eşitliğini destekler. -**Platformlar:** Claude AI, Google Gemini, OpenAI ChatGPT, Genel Markdown +**Platformlar:** Claude AI, Google Gemini, OpenAI ChatGPT, MiniMax AI, Genel Markdown, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI **Kaynak Türleri:** Dokümantasyon siteleri, GitHub depoları, PDF'ler, Word (.docx), EPUB, Video, Yerel kod tabanları, Jupyter Not Defterleri, Yerel HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint (.pptx), RSS/Atom beslemeleri, Man sayfaları, Confluence vikileri, Notion sayfaları, Slack/Discord sohbet dışa aktarımları Ayrıntılı platform ve özellik desteği için [Tam Özellik Matrisi](docs/FEATURE_MATRIX.md) bölümüne bakın. @@ -943,7 +958,7 @@ Claude Code'da şunu sorun: ## 🤖 AI Ajanlara Yükleme -Skill Seekers, yetenekleri 10+ AI kodlama ajanına otomatik olarak yükleyebilir. +Skill Seekers, yetenekleri 18 AI kodlama ajanına otomatik olarak yükleyebilir. ```bash # Belirli bir ajana yükle @@ -967,6 +982,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | Global | | **OpenCode** | `~/.opencode/skills/` | Global | | **Windsurf** | `~/.windsurf/skills/` | Global | +| **Roo Code** | `.roo/skills/` | Proje | +| **Cline** | `.cline/skills/` | Proje | +| **Aider** | `~/.aider/skills/` | Global | +| **Bolt** | `.bolt/skills/` | Proje | +| **Kilo Code** | `.kilo/skills/` | Proje | +| **Continue** | `~/.continue/skills/` | Global | +| **Kimi Code** | `~/.kimi/skills/` | Global | --- diff --git a/README.zh-CN.md b/README.zh-CN.md index fe3fe95..4175ec1 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -29,6 +29,21 @@ > 📋 **[查看开发路线图和任务](https://github.com/users/yusufkaraaslan/projects/2)** - 10 个类别的 134 个任务,选择任意一个参与贡献! +## 🌐 生态系统 + +Skill Seekers 是一个多仓库项目。以下是各部分所在位置: + +| 仓库 | 描述 | 链接 | +|------|------|------| +| **[Skill_Seekers](https://github.com/yusufkaraaslan/Skill_Seekers)** | 核心 CLI 和 MCP 服务器(本仓库) | [PyPI](https://pypi.org/project/skill-seekers/) | +| **[skillseekersweb](https://github.com/yusufkaraaslan/skillseekersweb)** | 网站和文档 | [在线](https://skillseekersweb.com/) | +| **[skill-seekers-configs](https://github.com/yusufkaraaslan/skill-seekers-configs)** | 社区配置仓库 | | +| **[skill-seekers-action](https://github.com/yusufkaraaslan/skill-seekers-action)** | GitHub Action CI/CD | | +| **[skill-seekers-plugin](https://github.com/yusufkaraaslan/skill-seekers-plugin)** | Claude Code 插件 | | +| **[homebrew-skill-seekers](https://github.com/yusufkaraaslan/homebrew-skill-seekers)** | macOS Homebrew tap | | + +> **想要贡献?** 网站和配置仓库是新贡献者的最佳起点! + ## 🧠 AI 系统的数据层 **Skill Seekers 是通用预处理层**,位于原始文档和所有使用它的 AI 系统之间。无论您是在构建 Claude 技能、LangChain RAG 流水线,还是 Cursor `.cursorrules` 文件——数据准备工作完全相同。只需执行一次,即可导出到所有目标平台。 @@ -192,7 +207,7 @@ Skill Seekers 通过以下步骤代替数天的手动预处理工作: - ✅ **向后兼容** - 遗留单源配置继续有效 ### 🤖 多 LLM 平台支持 -- ✅ **4 个 LLM 平台** - Claude AI、Google Gemini、OpenAI ChatGPT、通用 Markdown +- ✅ **12 个 LLM 平台** - Claude AI、Google Gemini、OpenAI ChatGPT、MiniMax AI、通用 Markdown、OpenCode、Kimi、DeepSeek、Qwen、OpenRouter、Together AI、Fireworks AI - ✅ **通用抓取** - 相同文档适用于所有平台 - ✅ **平台专用打包** - 针对每个 LLM 的优化格式 - ✅ **一键导出** - `--target` 标志选择平台 @@ -576,9 +591,9 @@ skill-seekers install --config react --dry-run ## 📊 功能矩阵 -Skill Seekers 支持 **4 个 LLM 平台**、**17 种来源类型**和 **5 种技能模式**,功能完全对等。 +Skill Seekers 支持 **12 个 LLM 平台**、**17 种来源类型**和 **5 种技能模式**,功能完全对等。 -**平台:** Claude AI、Google Gemini、OpenAI ChatGPT、通用 Markdown +**平台:** Claude AI、Google Gemini、OpenAI ChatGPT、MiniMax AI、通用 Markdown、OpenCode、Kimi、DeepSeek、Qwen、OpenRouter、Together AI、Fireworks AI **来源类型:** 文档网站、GitHub 仓库、PDF、Word、EPUB、视频、本地代码库、Jupyter 笔记本、本地 HTML、OpenAPI/Swagger 规范、AsciiDoc 文档、PowerPoint 演示文稿、RSS/Atom 订阅源、Man 手册页、Confluence 维基、Notion 页面、Slack/Discord 聊天记录 **技能模式:** 文档、GitHub、PDF、统一多源、本地仓库 @@ -815,7 +830,7 @@ skill-seekers package output/react/ ## 🤖 安装到 AI 代理 -Skill Seekers 可自动将技能安装到 10+ 个 AI 编程代理。 +Skill Seekers 可自动将技能安装到 18 个 AI 编程代理。 ```bash # 安装到特定代理 @@ -839,6 +854,13 @@ skill-seekers install-agent output/react/ --agent cursor --dry-run | **Goose** | `~/.config/goose/skills/` | 全局 | | **OpenCode** | `~/.opencode/skills/` | 全局 | | **Windsurf** | `~/.windsurf/skills/` | 全局 | +| **Roo Code** | `.roo/skills/` | 项目 | +| **Cline** | `.cline/skills/` | 项目 | +| **Aider** | `~/.aider/skills/` | 全局 | +| **Bolt** | `.bolt/skills/` | 项目 | +| **Kilo Code** | `.kilo/skills/` | 项目 | +| **Continue** | `~/.continue/skills/` | 全局 | +| **Kimi Code** | `~/.kimi/skills/` | 全局 | --- diff --git a/TESTING_GAP_REPORT.md b/TESTING_GAP_REPORT.md deleted file mode 100644 index 2277fb0..0000000 --- a/TESTING_GAP_REPORT.md +++ /dev/null @@ -1,345 +0,0 @@ -# Comprehensive Testing Gap Report - -**Project:** Skill Seekers v3.1.0 -**Date:** 2026-02-22 -**Total Test Files:** 113 -**Total Test Functions:** ~208+ (collected: 2173 tests) - ---- - -## Executive Summary - -### Overall Test Health: 🟡 GOOD with Gaps - -| Category | Status | Coverage | Key Gaps | -|----------|--------|----------|----------| -| CLI Arguments | ✅ Good | 85% | Some edge cases | -| Workflow System | ✅ Excellent | 90% | Inline stage parsing edge cases | -| Scrapers | 🟡 Moderate | 70% | Missing real HTTP/PDF tests | -| Enhancement | 🟡 Partial | 60% | Core logic not tested | -| MCP Tools | 🟡 Good | 75% | 8 tools not covered | -| Integration/E2E | 🟡 Moderate | 65% | Heavy mocking | -| Adaptors | ✅ Good | 80% | Good coverage per platform | - ---- - -## Detailed Findings by Category - -### 1. CLI Argument Tests ✅ GOOD - -**Files Reviewed:** -- `test_analyze_command.py` (269 lines, 26 tests) -- `test_unified.py` - TestUnifiedCLIArguments class (6 tests) -- `test_pdf_scraper.py` - TestPDFCLIArguments class (4 tests) -- `test_create_arguments.py` (399 lines) -- `test_create_integration_basic.py` (310 lines, 23 tests) - -**Strengths:** -- All new workflow flags are tested (`--enhance-workflow`, `--enhance-stage`, `--var`, `--workflow-dry-run`) -- Argument parsing thoroughly tested -- Default values verified -- Complex command combinations tested - -**Gaps:** -- `test_create_integration_basic.py`: 2 tests skipped (source auto-detection not fully tested) -- No tests for invalid argument combinations beyond basic parsing errors - ---- - -### 2. Workflow Tests ✅ EXCELLENT - -**Files Reviewed:** -- `test_workflow_runner.py` (445 lines, 30+ tests) -- `test_workflows_command.py` (571 lines, 40+ tests) -- `test_workflow_tools_mcp.py` (295 lines, 20+ tests) - -**Strengths:** -- Comprehensive workflow execution tests -- Variable substitution thoroughly tested -- Dry-run mode tested -- Workflow chaining tested -- All 6 workflow subcommands tested (list, show, copy, add, remove, validate) -- MCP workflow tools tested - -**Minor Gaps:** -- No tests for `_build_inline_engine` edge cases -- No tests for malformed stage specs (empty, invalid format) - ---- - -### 3. Scraper Tests 🟡 MODERATE with Significant Gaps - -**Files Reviewed:** -- `test_scraper_features.py` (524 lines) - Doc scraper features -- `test_codebase_scraper.py` (478 lines) - Codebase analysis -- `test_pdf_scraper.py` (558 lines) - PDF scraper -- `test_github_scraper.py` (1015 lines) - GitHub scraper -- `test_unified_analyzer.py` (428 lines) - Unified analyzer - -**Critical Gaps:** - -#### A. Missing Real External Resource Tests -| Resource | Test Type | Status | -|----------|-----------|--------| -| HTTP Requests (docs) | Mocked only | ❌ Gap | -| PDF Extraction | Mocked only | ❌ Gap | -| GitHub API | Mocked only | ❌ Gap (acceptable) | -| Local Files | Real tests | ✅ Good | - -#### B. Missing Core Function Tests -| Function | Location | Priority | -|----------|----------|----------| -| `UnifiedScraper.run()` | unified_scraper.py | 🔴 High | -| `UnifiedScraper._scrape_documentation()` | unified_scraper.py | 🔴 High | -| `UnifiedScraper._scrape_github()` | unified_scraper.py | 🔴 High | -| `UnifiedScraper._scrape_pdf()` | unified_scraper.py | 🔴 High | -| `UnifiedScraper._scrape_local()` | unified_scraper.py | 🟡 Medium | -| `DocToSkillConverter.scrape()` | doc_scraper.py | 🔴 High | -| `PDFToSkillConverter.extract_pdf()` | pdf_scraper.py | 🔴 High | - -#### C. PDF Scraper Limited Coverage -- No actual PDF parsing tests (only mocked) -- OCR functionality not tested -- Page range extraction not tested - ---- - -### 4. Enhancement Tests 🟡 PARTIAL - MAJOR GAPS - -**Files Reviewed:** -- `test_enhance_command.py` (367 lines, 25+ tests) -- `test_enhance_skill_local.py` (163 lines, 14 tests) - -**Critical Gap in `test_enhance_skill_local.py`:** - -| Function | Lines | Tested? | Priority | -|----------|-------|---------|----------| -| `summarize_reference()` | ~50 | ❌ No | 🔴 High | -| `create_enhancement_prompt()` | ~200 | ❌ No | 🔴 High | -| `run()` | ~100 | ❌ No | 🔴 High | -| `_run_headless()` | ~130 | ❌ No | 🔴 High | -| `_run_background()` | ~80 | ❌ No | 🟡 Medium | -| `_run_daemon()` | ~60 | ❌ No | 🟡 Medium | -| `write_status()` | ~30 | ❌ No | 🟡 Medium | -| `read_status()` | ~40 | ❌ No | 🟡 Medium | -| `detect_terminal_app()` | ~80 | ❌ No | 🟡 Medium | - -**Current Tests Only Cover:** -- Agent presets configuration -- Command building -- Agent name normalization -- Environment variable handling - -**Recommendation:** Add comprehensive tests for the core enhancement logic. - ---- - -### 5. MCP Tool Tests 🟡 GOOD with Coverage Gaps - -**Files Reviewed:** -- `test_mcp_fastmcp.py` (868 lines) -- `test_mcp_server.py` (715 lines) -- `test_mcp_vector_dbs.py` (259 lines) -- `test_real_world_fastmcp.py` (558 lines) - -**Coverage Analysis:** - -| Tool Category | Tools | Tested | Coverage | -|---------------|-------|--------|----------| -| Config Tools | 3 | 3 | ✅ 100% | -| Scraping Tools | 8 | 4 | 🟡 50% | -| Packaging Tools | 4 | 4 | ✅ 100% | -| Splitting Tools | 2 | 2 | ✅ 100% | -| Source Tools | 5 | 5 | ✅ 100% | -| Vector DB Tools | 4 | 4 | ✅ 100% | -| Workflow Tools | 5 | 0 | ❌ 0% | -| **Total** | **31** | **22** | **🟡 71%** | - -**Untested Tools:** -1. `detect_patterns` -2. `extract_test_examples` -3. `build_how_to_guides` -4. `extract_config_patterns` -5. `list_workflows` -6. `get_workflow` -7. `create_workflow` -8. `update_workflow` -9. `delete_workflow` - -**Note:** `test_mcp_server.py` tests legacy server, `test_mcp_fastmcp.py` tests modern server. - ---- - -### 6. Integration/E2E Tests 🟡 MODERATE - -**Files Reviewed:** -- `test_create_integration_basic.py` (310 lines) -- `test_e2e_three_stream_pipeline.py` (598 lines) -- `test_analyze_e2e.py` (344 lines) -- `test_install_skill_e2e.py` (533 lines) -- `test_c3_integration.py` (362 lines) - -**Issues Found:** - -1. **Skipped Tests:** - - `test_create_detects_web_url` - Source auto-detection incomplete - - `test_create_invalid_source_shows_error` - Error handling incomplete - - `test_cli_via_unified_command` - Asyncio issues - -2. **Heavy Mocking:** - - Most GitHub API tests use mocking - - No real HTTP tests for doc scraping - - Integration tests don't test actual integration - -3. **Limited Scope:** - - Only `--quick` preset tested (not `--comprehensive`) - - C3.x tests use mock data only - - Most E2E tests are unit tests with mocks - ---- - -### 7. Adaptor Tests ✅ GOOD - -**Files Reviewed:** -- `test_adaptors/test_adaptors_e2e.py` (893 lines) -- `test_adaptors/test_claude_adaptor.py` (314 lines) -- `test_adaptors/test_gemini_adaptor.py` (146 lines) -- `test_adaptors/test_openai_adaptor.py` (188 lines) -- Plus 8 more platform adaptors - -**Strengths:** -- Each adaptor has dedicated tests -- Package format testing -- Upload success/failure scenarios -- Platform-specific features tested - -**Minor Gaps:** -- Some adaptors only test 1-2 scenarios -- Error handling coverage varies by platform - ---- - -### 8. Config/Validation Tests ✅ GOOD - -**Files Reviewed:** -- `test_config_validation.py` (270 lines) -- `test_config_extractor.py` (629 lines) -- `test_config_fetcher.py` (340 lines) - -**Strengths:** -- Unified vs legacy format detection -- Field validation comprehensive -- Error message quality tested - ---- - -## Summary of Critical Testing Gaps - -### 🔴 HIGH PRIORITY (Must Fix) - -1. **Enhancement Core Logic** - - File: `test_enhance_skill_local.py` - - Missing: 9 major functions - - Impact: Core feature untested - -2. **Unified Scraper Main Flow** - - File: New tests needed - - Missing: `_scrape_*()` methods, `run()` orchestration - - Impact: Multi-source scraping untested - -3. **Actual HTTP/PDF/GitHub Integration** - - Missing: Real external resource tests - - Impact: Only mock tests exist - -### 🟡 MEDIUM PRIORITY (Should Fix) - -4. **MCP Workflow Tools** - - Missing: 5 workflow tools (0% coverage) - - Impact: MCP workflow features untested - -5. **Skipped Integration Tests** - - 3 tests skipped - - Impact: Source auto-detection incomplete - -6. **PDF Real Extraction** - - Missing: Actual PDF parsing - - Impact: PDF feature quality unknown - -### 🟢 LOW PRIORITY (Nice to Have) - -7. **Additional Scraping Tools** - - Missing: 4 scraping tool tests - - Impact: Low (core tools covered) - -8. **Edge Case Coverage** - - Missing: Invalid argument combinations - - Impact: Low (happy path covered) - ---- - -## Recommendations - -### Immediate Actions (Next Sprint) - -1. **Add Enhancement Logic Tests** (~400 lines) - - Test `summarize_reference()` - - Test `create_enhancement_prompt()` - - Test `run()` method - - Test status read/write - -2. **Fix Skipped Tests** (~100 lines) - - Fix asyncio issues in `test_cli_via_unified_command` - - Complete source auto-detection tests - -3. **Add MCP Workflow Tool Tests** (~200 lines) - - Test all 5 workflow tools - -### Short Term (Next Month) - -4. **Add Unified Scraper Integration Tests** (~300 lines) - - Test main orchestration flow - - Test individual source scraping - -5. **Add Real PDF Tests** (~150 lines) - - Test with actual PDF files - - Test OCR if available - -### Long Term (Next Quarter) - -6. **HTTP Integration Tests** (~200 lines) - - Test with real websites (use test sites) - - Mock server approach - -7. **Complete E2E Pipeline** (~300 lines) - - Full workflow from scrape to upload - - Real GitHub repo (fork test repo) - ---- - -## Test Quality Metrics - -| Metric | Score | Notes | -|--------|-------|-------| -| Test Count | 🟢 Good | 2173+ tests | -| Coverage | 🟡 Moderate | ~75% estimated | -| Real Tests | 🟡 Moderate | Many mocked | -| Documentation | 🟢 Good | Most tests documented | -| Maintenance | 🟢 Good | Tests recently updated | - ---- - -## Conclusion - -The Skill Seekers test suite is **comprehensive in quantity** (2173+ tests) but has **quality gaps** in critical areas: - -1. **Core enhancement logic** is largely untested -2. **Multi-source scraping** orchestration lacks integration tests -3. **MCP workflow tools** have zero coverage -4. **Real external resource** testing is minimal - -**Priority:** Fix the 🔴 HIGH priority gaps first, as they impact core functionality. - ---- - -*Report generated: 2026-02-22* -*Reviewer: Systematic test review with parallel subagent analysis* diff --git a/demo_conflicts.py b/demo_conflicts.py deleted file mode 100644 index 5ee5f72..0000000 --- a/demo_conflicts.py +++ /dev/null @@ -1,204 +0,0 @@ -#!/usr/bin/env python3 -""" -Demo: Conflict Detection and Reporting - -This demonstrates the unified scraper's ability to detect and report -conflicts between documentation and code implementation. -""" - -import json -import sys -from pathlib import Path - -# Add CLI to path -sys.path.insert(0, str(Path(__file__).parent / "cli")) - - -print("=" * 70) -print("UNIFIED SCRAPER - CONFLICT DETECTION DEMO") -print("=" * 70) -print() - -# Load test data -print("📂 Loading test data...") -print(" - Documentation APIs from example docs") -print(" - Code APIs from example repository") -print() - -with open("cli/conflicts.json") as f: - conflicts_data = json.load(f) - -conflicts = conflicts_data["conflicts"] -summary = conflicts_data["summary"] - -print(f"✅ Loaded {summary['total']} conflicts") -print() - -# Display summary -print("=" * 70) -print("CONFLICT SUMMARY") -print("=" * 70) -print() - -print(f"📊 **Total Conflicts**: {summary['total']}") -print() - -print("**By Type:**") -for conflict_type, count in summary["by_type"].items(): - if count > 0: - emoji = ( - "📖" - if conflict_type == "missing_in_docs" - else "💻" - if conflict_type == "missing_in_code" - else "⚠️" - ) - print(f" {emoji} {conflict_type}: {count}") -print() - -print("**By Severity:**") -for severity, count in summary["by_severity"].items(): - if count > 0: - emoji = "🔴" if severity == "high" else "🟡" if severity == "medium" else "🟢" - print(f" {emoji} {severity.upper()}: {count}") -print() - -# Display detailed conflicts -print("=" * 70) -print("DETAILED CONFLICT REPORTS") -print("=" * 70) -print() - -# Group by severity -high = [c for c in conflicts if c["severity"] == "high"] -medium = [c for c in conflicts if c["severity"] == "medium"] -low = [c for c in conflicts if c["severity"] == "low"] - -# Show high severity first -if high: - print("🔴 **HIGH SEVERITY CONFLICTS** (Requires immediate attention)") - print("-" * 70) - for conflict in high: - print() - print(f"**API**: `{conflict['api_name']}`") - print(f"**Type**: {conflict['type']}") - print(f"**Issue**: {conflict['difference']}") - print(f"**Suggestion**: {conflict['suggestion']}") - - if conflict["docs_info"]: - print("\n**Documented as**:") - print(f" Signature: {conflict['docs_info'].get('raw_signature', 'N/A')}") - - if conflict["code_info"]: - print("\n**Implemented as**:") - params = conflict["code_info"].get("parameters", []) - param_str = ", ".join( - f"{p['name']}: {p.get('type_hint', 'Any')}" for p in params if p["name"] != "self" - ) - print(f" Signature: {conflict['code_info']['name']}({param_str})") - print(f" Return type: {conflict['code_info'].get('return_type', 'None')}") - print( - f" Location: {conflict['code_info'].get('source', 'N/A')}:{conflict['code_info'].get('line', '?')}" - ) - print() - -# Show medium severity -if medium: - print("🟡 **MEDIUM SEVERITY CONFLICTS** (Review recommended)") - print("-" * 70) - for conflict in medium[:3]: # Show first 3 - print() - print(f"**API**: `{conflict['api_name']}`") - print(f"**Type**: {conflict['type']}") - print(f"**Issue**: {conflict['difference']}") - - if conflict["code_info"]: - print(f"**Location**: {conflict['code_info'].get('source', 'N/A')}") - - if len(medium) > 3: - print(f"\n ... and {len(medium) - 3} more medium severity conflicts") - print() - -# Example: How conflicts appear in final skill -print("=" * 70) -print("HOW CONFLICTS APPEAR IN SKILL.MD") -print("=" * 70) -print() - -example_conflict = high[0] if high else medium[0] if medium else conflicts[0] - -print("```markdown") -print("## 🔧 API Reference") -print() -print("### ⚠️ APIs with Conflicts") -print() -print(f"#### `{example_conflict['api_name']}`") -print() -print(f"⚠️ **Conflict**: {example_conflict['difference']}") -print() - -if example_conflict.get("docs_info"): - print("**Documentation says:**") - print("```") - print(example_conflict["docs_info"].get("raw_signature", "N/A")) - print("```") - print() - -if example_conflict.get("code_info"): - print("**Code implementation:**") - print("```python") - params = example_conflict["code_info"].get("parameters", []) - param_strs = [] - for p in params: - if p["name"] == "self": - continue - param_str = p["name"] - if p.get("type_hint"): - param_str += f": {p['type_hint']}" - if p.get("default"): - param_str += f" = {p['default']}" - param_strs.append(param_str) - - sig = f"def {example_conflict['code_info']['name']}({', '.join(param_strs)})" - if example_conflict["code_info"].get("return_type"): - sig += f" -> {example_conflict['code_info']['return_type']}" - - print(sig) - print("```") -print() - -print("*Source: both (conflict)*") -print("```") -print() - -# Key takeaways -print("=" * 70) -print("KEY TAKEAWAYS") -print("=" * 70) -print() - -print("✅ **What the Unified Scraper Does:**") -print(" 1. Extracts APIs from both documentation and code") -print(" 2. Compares them to detect discrepancies") -print(" 3. Classifies conflicts by type and severity") -print(" 4. Provides actionable suggestions") -print(" 5. Shows both versions transparently in the skill") -print() - -print("⚠️ **Common Conflict Types:**") -print(" - **Missing in docs**: Undocumented features in code") -print(" - **Missing in code**: Documented but not implemented") -print(" - **Signature mismatch**: Different parameters/types") -print(" - **Description mismatch**: Different explanations") -print() - -print("🎯 **Value:**") -print(" - Identifies documentation gaps") -print(" - Catches outdated documentation") -print(" - Highlights implementation differences") -print(" - Creates single source of truth showing reality") -print() - -print("=" * 70) -print("END OF DEMO") -print("=" * 70) diff --git a/distribution/claude-plugin/.claude-plugin/plugin.json b/distribution/claude-plugin/.claude-plugin/plugin.json new file mode 100644 index 0000000..1b3ed69 --- /dev/null +++ b/distribution/claude-plugin/.claude-plugin/plugin.json @@ -0,0 +1,11 @@ +{ + "name": "skill-seekers", + "description": "Transform 17 source types (docs, GitHub, PDFs, videos, Jupyter, Confluence, Notion, Slack, and more) into AI-ready skills and RAG knowledge for 16+ LLM platforms.", + "version": "3.3.0", + "author": { + "name": "Yusuf Karaaslan" + }, + "homepage": "https://github.com/yusufkaraaslan/Skill_Seekers", + "repository": "https://github.com/yusufkaraaslan/Skill_Seekers", + "license": "MIT" +} diff --git a/distribution/claude-plugin/.mcp.json b/distribution/claude-plugin/.mcp.json new file mode 100644 index 0000000..c0fa9c9 --- /dev/null +++ b/distribution/claude-plugin/.mcp.json @@ -0,0 +1,6 @@ +{ + "skill-seekers": { + "command": "python", + "args": ["-m", "skill_seekers.mcp.server_fastmcp"] + } +} diff --git a/distribution/claude-plugin/README.md b/distribution/claude-plugin/README.md new file mode 100644 index 0000000..a433fc1 --- /dev/null +++ b/distribution/claude-plugin/README.md @@ -0,0 +1,93 @@ +# Skill Seekers — Claude Code Plugin + +Transform 17 source types into AI-ready skills and RAG knowledge, directly from Claude Code. + +## Installation + +### From the Official Plugin Directory + +``` +/plugin install skill-seekers@claude-plugin-directory +``` + +Or browse for it in `/plugin > Discover`. + +### Local Installation (for development) + +```bash +claude --plugin-dir ./path/to/skill-seekers-plugin +``` + +### Prerequisites + +The plugin requires `skill-seekers` to be installed: + +```bash +pip install skill-seekers[mcp] +``` + +## What's Included + +### MCP Server (35 tools) + +The plugin bundles the Skill Seekers MCP server providing tools for: +- Scraping documentation, GitHub repos, PDFs, videos, and 13 other source types +- Packaging skills for 16+ LLM platforms +- Exporting to vector databases (Weaviate, Chroma, FAISS, Qdrant) +- Managing configs, workflows, and sources + +### Slash Commands + +| Command | Description | +|---------|-------------| +| `/skill-seekers:create-skill ` | Create a skill from any source (auto-detects type) | +| `/skill-seekers:sync-config ` | Sync config URLs against live docs | +| `/skill-seekers:install-skill ` | End-to-end: fetch, scrape, enhance, package, install | + +### Agent Skill + +The **skill-builder** skill is automatically available to Claude. It detects source types and uses the appropriate MCP tools to build skills autonomously. + +## Usage Examples + +``` +# Create a skill from a documentation site +/skill-seekers:create-skill https://react.dev + +# Create from a GitHub repo, targeting LangChain +/skill-seekers:create-skill pallets/flask --target langchain + +# Full install workflow with AI enhancement +/skill-seekers:install-skill https://fastapi.tiangolo.com --enhance + +# Sync an existing config +/skill-seekers:sync-config react +``` + +Or just ask Claude naturally: +> "Create an AI skill from the React documentation" +> "Scrape the Flask GitHub repo and package it for OpenAI" +> "Export my skill to a Chroma vector database" + +The skill-builder agent skill will automatically detect the intent and use the right tools. + +## Remote MCP Alternative + +By default, the plugin runs the MCP server locally via `python -m skill_seekers.mcp.server_fastmcp`. To use a remote server instead, edit `.mcp.json`: + +```json +{ + "skill-seekers": { + "type": "http", + "url": "https://your-hosted-server.com/mcp" + } +} +``` + +## Supported Source Types + +Documentation (web), GitHub repos, PDFs, Word docs, EPUBs, videos, local codebases, Jupyter notebooks, HTML files, OpenAPI specs, AsciiDoc, PowerPoint, RSS/Atom feeds, man pages, Confluence, Notion, Slack/Discord exports. + +## License + +MIT — https://github.com/yusufkaraaslan/Skill_Seekers diff --git a/distribution/claude-plugin/commands/create-skill.md b/distribution/claude-plugin/commands/create-skill.md new file mode 100644 index 0000000..6130871 --- /dev/null +++ b/distribution/claude-plugin/commands/create-skill.md @@ -0,0 +1,62 @@ +--- +description: Create an AI skill from any source (URL, repo, PDF, video, notebook, etc.) +--- + +# Create Skill + +Create an AI-ready skill from a source. The source type is auto-detected. + +## Usage + +``` +/skill-seekers:create-skill [--preset ] [--output ] +``` + +## Instructions + +When the user provides a source via `$ARGUMENTS`, run the `skill-seekers create` command to generate a skill. + +1. Parse the arguments: extract the source (first argument) and any flags. +2. If no `--preset` is specified, default to `quick` for fast results. +3. If no `--output` is specified, default to `./output`. +4. Run the create command: + ```bash + skill-seekers create "$SOURCE" --preset quick --output "$OUTPUT" + ``` +5. After completion, read the generated `SKILL.md` and summarize what was created. +6. If the user wants to target a specific platform (e.g., Claude, OpenAI, LangChain), run the package command after: + ```bash + skill-seekers package "$SKILL_DIR" --target "$PLATFORM" + ``` + +## Presets + +- `-p quick` — 1-2 minutes, basic skill +- `-p standard` — 5-10 minutes, good coverage +- `-p comprehensive` — 20-60 minutes, full analysis + +## Source Types (auto-detected) + +- **URL** (https://...) — Documentation scraping +- **owner/repo** or github.com URL — GitHub repo analysis +- **file.pdf** — PDF extraction +- **file.ipynb** — Jupyter notebook +- **file.docx** — Word document +- **file.epub** — EPUB book +- **YouTube/Vimeo URL** — Video transcript +- **./directory** — Local codebase analysis +- **file.yaml** with OpenAPI — API spec +- **file.pptx** — PowerPoint +- **file.adoc** — AsciiDoc +- **file.html** — HTML page +- **file.rss** — RSS/Atom feed +- **cmd.1** — Man page + +## Examples + +``` +/skill-seekers:create-skill https://react.dev +/skill-seekers:create-skill pallets/flask -p standard +/skill-seekers:create-skill ./docs/api.pdf +/skill-seekers:create-skill https://youtube.com/watch?v=abc123 +``` diff --git a/distribution/claude-plugin/commands/install-skill.md b/distribution/claude-plugin/commands/install-skill.md new file mode 100644 index 0000000..0d9c1de --- /dev/null +++ b/distribution/claude-plugin/commands/install-skill.md @@ -0,0 +1,41 @@ +--- +description: One-command skill creation and packaging for a target platform +--- + +# Install Skill + +End-to-end workflow: create a skill from any source, then package it for a target LLM platform. + +## Usage + +``` +/skill-seekers:install-skill [--target ] [--preset ] +``` + +## Instructions + +When the user provides a source via `$ARGUMENTS`: + +1. Parse the arguments: extract source, `--target` (default: claude), `--preset` (default: quick). +2. Run the create command: + ```bash + skill-seekers create "$SOURCE" --preset "$PRESET" --output ./output + ``` +3. Find the generated skill directory (look for the directory containing SKILL.md in ./output/). +4. Run the package command for the target platform: + ```bash + skill-seekers package "$SKILL_DIR" --target "$TARGET" + ``` +5. Report what was created and where to find the packaged output. + +## Target Platforms + +`claude` (default), `openai`, `gemini`, `langchain`, `llamaindex`, `haystack`, `cursor`, `windsurf`, `continue`, `cline`, `markdown` + +## Examples + +``` +/skill-seekers:install-skill https://react.dev --target claude +/skill-seekers:install-skill pallets/flask --target langchain -p standard +/skill-seekers:install-skill ./docs/api.pdf --target openai +``` diff --git a/distribution/claude-plugin/commands/sync-config.md b/distribution/claude-plugin/commands/sync-config.md new file mode 100644 index 0000000..273bd15 --- /dev/null +++ b/distribution/claude-plugin/commands/sync-config.md @@ -0,0 +1,32 @@ +--- +description: Sync a scraping config's URLs against the live documentation site +--- + +# Sync Config + +Synchronize a Skill Seekers config file with the current state of a documentation site. Detects new pages, removed pages, and URL changes. + +## Usage + +``` +/skill-seekers:sync-config +``` + +## Instructions + +When the user provides a config path or preset name via `$ARGUMENTS`: + +1. If it's a preset name (e.g., `react`, `godot`), look for it in the `configs/` directory or fetch from the API. +2. Run the sync command: + ```bash + skill-seekers sync-config "$CONFIG" + ``` +3. Report what changed: new URLs found, removed URLs, and any conflicts. +4. Ask the user if they want to update the config and re-scrape. + +## Examples + +``` +/skill-seekers:sync-config configs/react.json +/skill-seekers:sync-config react +``` diff --git a/distribution/claude-plugin/skills/skill-builder/SKILL.md b/distribution/claude-plugin/skills/skill-builder/SKILL.md new file mode 100644 index 0000000..c0d8b40 --- /dev/null +++ b/distribution/claude-plugin/skills/skill-builder/SKILL.md @@ -0,0 +1,69 @@ +--- +name: skill-builder +description: Automatically detect source types and build AI skills using Skill Seekers. Use when the user wants to create skills from documentation, repos, PDFs, videos, or other knowledge sources. +--- + +# Skill Builder + +You have access to the Skill Seekers MCP server which provides 35 tools for converting knowledge sources into AI-ready skills. + +## When to Use This Skill + +Use this skill when the user: +- Wants to create an AI skill from a documentation site, GitHub repo, PDF, video, or other source +- Needs to convert documentation into a format suitable for LLM consumption +- Wants to update or sync existing skills with their source documentation +- Needs to export skills to vector databases (Weaviate, Chroma, FAISS, Qdrant) +- Asks about scraping, converting, or packaging documentation for AI + +## Source Type Detection + +Automatically detect the source type from user input: + +| Input Pattern | Source Type | Tool to Use | +|---------------|-------------|-------------| +| `https://...` (not GitHub/YouTube) | Documentation | `scrape_docs` | +| `owner/repo` or `github.com/...` | GitHub | `scrape_github` | +| `*.pdf` | PDF | `scrape_pdf` | +| YouTube/Vimeo URL or video file | Video | `scrape_video` | +| Local directory path | Codebase | `scrape_codebase` | +| `*.ipynb`, `*.html`, `*.yaml` (OpenAPI), `*.adoc`, `*.pptx`, `*.rss`, `*.1`-`.8` | Various | `scrape_generic` | +| JSON config file | Unified | Use config with `scrape_docs` | + +## Recommended Workflow + +1. **Detect source type** from the user's input +2. **Generate or fetch config** using `generate_config` or `fetch_config` if needed +3. **Estimate scope** with `estimate_pages` for documentation sites +4. **Scrape the source** using the appropriate scraping tool +5. **Enhance** with `enhance_skill` if the user wants AI-powered improvements +6. **Package** with `package_skill` for the target platform +7. **Export to vector DB** if requested using `export_to_*` tools + +## Available MCP Tools + +### Config Management +- `generate_config` — Generate a scraping config from a URL +- `list_configs` — List available preset configs +- `validate_config` — Validate a config file + +### Scraping (use based on source type) +- `scrape_docs` — Documentation sites +- `scrape_github` — GitHub repositories +- `scrape_pdf` — PDF files +- `scrape_video` — Video transcripts +- `scrape_codebase` — Local code analysis +- `scrape_generic` — Jupyter, HTML, OpenAPI, AsciiDoc, PPTX, RSS, manpage, Confluence, Notion, chat + +### Post-processing +- `enhance_skill` — AI-powered skill enhancement +- `package_skill` — Package for target platform +- `upload_skill` — Upload to platform API +- `install_skill` — End-to-end install workflow + +### Advanced +- `detect_patterns` — Design pattern detection in code +- `extract_test_examples` — Extract usage examples from tests +- `build_how_to_guides` — Generate how-to guides from tests +- `split_config` — Split large configs into focused skills +- `export_to_weaviate`, `export_to_chroma`, `export_to_faiss`, `export_to_qdrant` — Vector DB export diff --git a/distribution/github-action/README.md b/distribution/github-action/README.md new file mode 100644 index 0000000..dd9f46e --- /dev/null +++ b/distribution/github-action/README.md @@ -0,0 +1,147 @@ +# Skill Seekers GitHub Action + +Transform documentation, GitHub repos, PDFs, videos, and 13 other source types into AI-ready skills and RAG knowledge — directly in your CI/CD pipeline. + +## Quick Start + +```yaml +- uses: yusufkaraaslan/skill-seekers-action@v3 + with: + source: 'https://react.dev' +``` + +## Inputs + +| Input | Required | Default | Description | +|-------|----------|---------|-------------| +| `source` | Yes | — | Source URL, file path, or `owner/repo` | +| `command` | No | `create` | Command: `create`, `scrape`, `github`, `pdf`, `video`, `analyze`, `unified` | +| `target` | No | `claude` | Target platform: `claude`, `openai`, `gemini`, `langchain`, `llamaindex`, `markdown` | +| `config` | No | — | Path to JSON config file | +| `output-dir` | No | `output` | Output directory | +| `extra-args` | No | — | Additional CLI arguments | + +## Outputs + +| Output | Description | +|--------|-------------| +| `skill-dir` | Path to the generated skill directory | +| `skill-name` | Name of the generated skill | + +## Examples + +### Auto-update documentation skill weekly + +```yaml +name: Update AI Skills +on: + schedule: + - cron: '0 6 * * 1' # Every Monday 6am UTC + workflow_dispatch: + +jobs: + update-skills: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: yusufkaraaslan/skill-seekers-action@v3 + with: + source: 'https://react.dev' + target: 'langchain' + + - uses: actions/upload-artifact@v4 + with: + name: react-skill + path: output/ +``` + +### Generate skill from GitHub repo + +```yaml +- uses: yusufkaraaslan/skill-seekers-action@v3 + with: + source: 'pallets/flask' + command: 'github' + target: 'claude' +``` + +### Process PDF documentation + +```yaml +- uses: actions/checkout@v4 + +- uses: yusufkaraaslan/skill-seekers-action@v3 + with: + source: 'docs/api-reference.pdf' + command: 'pdf' +``` + +### Unified multi-source build with config + +```yaml +- uses: actions/checkout@v4 + +- uses: yusufkaraaslan/skill-seekers-action@v3 + with: + config: 'configs/my-project.json' + command: 'unified' + target: 'openai' +``` + +### Commit generated skill back to repo + +```yaml +- uses: actions/checkout@v4 + +- uses: yusufkaraaslan/skill-seekers-action@v3 + id: generate + with: + source: 'https://fastapi.tiangolo.com' + +- name: Commit skill + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add output/ + git diff --staged --quiet || git commit -m "Update AI skill: ${{ steps.generate.outputs.skill-name }}" + git push +``` + +## Environment Variables + +Pass API keys as environment variables for AI-enhanced skills: + +```yaml +env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} + GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + +## Supported Source Types + +| Type | Example Source | +|------|---------------| +| Documentation (web) | `https://react.dev` | +| GitHub repo | `pallets/flask` or `https://github.com/pallets/flask` | +| PDF | `docs/manual.pdf` | +| Video | `https://youtube.com/watch?v=...` | +| Local codebase | `./src` | +| Jupyter Notebook | `analysis.ipynb` | +| OpenAPI/Swagger | `openapi.yaml` | +| Word (.docx) | `docs/guide.docx` | +| EPUB | `book.epub` | +| PowerPoint | `slides.pptx` | +| AsciiDoc | `docs/guide.adoc` | +| HTML | `page.html` | +| RSS/Atom | `feed.rss` | +| Man pages | `tool.1` | +| Confluence | Via config file | +| Notion | Via config file | +| Chat (Slack/Discord) | Via config file | + +## License + +MIT diff --git a/distribution/github-action/action.yml b/distribution/github-action/action.yml new file mode 100644 index 0000000..17b9977 --- /dev/null +++ b/distribution/github-action/action.yml @@ -0,0 +1,92 @@ +name: 'Skill Seekers - AI Knowledge Builder' +description: 'Transform documentation, repos, PDFs, videos, and 13 other source types into AI skills and RAG knowledge' +author: 'Yusuf Karaaslan' + +branding: + icon: 'book-open' + color: 'blue' + +inputs: + source: + description: 'Source URL, file path, or owner/repo for GitHub repos' + required: true + command: + description: 'Command to run: create (auto-detect), scrape, github, pdf, video, analyze, unified' + required: false + default: 'create' + target: + description: 'Output target platform: claude, openai, gemini, langchain, llamaindex, markdown, cursor, windsurf' + required: false + default: 'claude' + config: + description: 'Path to JSON config file (for unified/advanced scraping)' + required: false + output-dir: + description: 'Output directory for generated skills' + required: false + default: 'output' + extra-args: + description: 'Additional CLI arguments to pass to skill-seekers' + required: false + default: '' + +outputs: + skill-dir: + description: 'Path to the generated skill directory' + value: ${{ steps.run.outputs.skill-dir }} + skill-name: + description: 'Name of the generated skill' + value: ${{ steps.run.outputs.skill-name }} + +runs: + using: 'composite' + steps: + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + + - name: Install Skill Seekers + shell: bash + run: pip install skill-seekers + + - name: Run Skill Seekers + id: run + shell: bash + env: + ANTHROPIC_API_KEY: ${{ env.ANTHROPIC_API_KEY }} + OPENAI_API_KEY: ${{ env.OPENAI_API_KEY }} + GOOGLE_API_KEY: ${{ env.GOOGLE_API_KEY }} + GITHUB_TOKEN: ${{ env.GITHUB_TOKEN }} + run: | + set -euo pipefail + + OUTPUT_DIR="${{ inputs.output-dir }}" + mkdir -p "$OUTPUT_DIR" + + CMD="${{ inputs.command }}" + SOURCE="${{ inputs.source }}" + TARGET="${{ inputs.target }}" + CONFIG="${{ inputs.config }}" + EXTRA="${{ inputs.extra-args }}" + + # Build the command + if [ "$CMD" = "create" ]; then + skill-seekers create "$SOURCE" --target "$TARGET" --output "$OUTPUT_DIR" $EXTRA + elif [ -n "$CONFIG" ]; then + skill-seekers "$CMD" --config "$CONFIG" --target "$TARGET" --output "$OUTPUT_DIR" $EXTRA + else + skill-seekers "$CMD" "$SOURCE" --target "$TARGET" --output "$OUTPUT_DIR" $EXTRA + fi + + # Find the generated skill directory + SKILL_DIR=$(find "$OUTPUT_DIR" -name "SKILL.md" -exec dirname {} \; | head -1) + SKILL_NAME=$(basename "$SKILL_DIR" 2>/dev/null || echo "unknown") + + echo "skill-dir=$SKILL_DIR" >> "$GITHUB_OUTPUT" + echo "skill-name=$SKILL_NAME" >> "$GITHUB_OUTPUT" + + echo "### Skill Generated" >> "$GITHUB_STEP_SUMMARY" + echo "- **Name:** $SKILL_NAME" >> "$GITHUB_STEP_SUMMARY" + echo "- **Directory:** $SKILL_DIR" >> "$GITHUB_STEP_SUMMARY" + echo "- **Target:** $TARGET" >> "$GITHUB_STEP_SUMMARY" diff --git a/distribution/smithery/README.md b/distribution/smithery/README.md new file mode 100644 index 0000000..714cff4 --- /dev/null +++ b/distribution/smithery/README.md @@ -0,0 +1,107 @@ +# Skill Seekers — Smithery MCP Registry + +Publishing guide for the Skill Seekers MCP server on [Smithery](https://smithery.ai). + +## Status + +- **Namespace created:** `yusufkaraaslan` +- **Server created:** `yusufkaraaslan/skill-seekers` +- **Server page:** https://smithery.ai/servers/yusufkaraaslan/skill-seekers +- **Release status:** Needs re-publish (initial release failed — Smithery couldn't scan GitHub URL as MCP endpoint) + +## Publishing + +Smithery requires a live, scannable MCP HTTP endpoint for URL-based publishing. Two options: + +### Option A: Publish via Web UI (Recommended) + +1. Go to https://smithery.ai/servers/yusufkaraaslan/skill-seekers/releases +2. The server already exists — create a new release +3. For the "Local" tab: follow the prompts to publish as a stdio server +4. For the "URL" tab: provide a hosted HTTP endpoint URL + +### Option B: Deploy HTTP endpoint first, then publish via CLI + +1. Deploy the MCP server on Render/Railway/Fly.io: + ```bash + # Using existing Dockerfile.mcp + docker build -f Dockerfile.mcp -t skill-seekers-mcp . + # Deploy to your hosting provider + ``` +2. Publish the live URL: + ```bash + npx @smithery/cli@latest auth login + npx @smithery/cli@latest mcp publish "https://your-deployed-url/mcp" \ + -n yusufkaraaslan/skill-seekers + ``` + +### CLI Authentication (already done) + +```bash +# Install via npx (no global install needed) +npx @smithery/cli@latest auth login +npx @smithery/cli@latest namespace show # Should show: yusufkaraaslan +``` + +### After Publishing + +Update the server page with metadata: + +**Display name:** Skill Seekers — AI Skill & RAG Toolkit + +**Description:** +> Transform 17 source types into AI-ready skills and RAG knowledge. Ingest documentation sites, GitHub repos, PDFs, Jupyter notebooks, videos, Confluence, Notion, Slack/Discord exports, and more. Package for 16+ LLM platforms including Claude, GPT, Gemini, LangChain, LlamaIndex, and vector databases. + +**Tags:** `ai`, `rag`, `documentation`, `skills`, `preprocessing`, `mcp`, `knowledge-base`, `vector-database` + +## User Installation + +Once published, users can add the server to their MCP client: + +```bash +# Via Smithery CLI (adds to Claude Desktop, Cursor, etc.) +smithery mcp add yusufkaraaslan/skill-seekers --client claude + +# Or configure manually — users need skill-seekers installed: +pip install skill-seekers[mcp] +``` + +### Manual MCP Configuration + +For clients that use JSON config (Claude Desktop, Claude Code, Cursor): + +```json +{ + "mcpServers": { + "skill-seekers": { + "command": "python", + "args": ["-m", "skill_seekers.mcp.server_fastmcp"] + } + } +} +``` + +## Available Tools (35) + +| Category | Tools | Description | +|----------|-------|-------------| +| Config | 3 | Generate, list, validate scraping configs | +| Sync | 1 | Sync config URLs against live docs | +| Scraping | 11 | Scrape docs, GitHub, PDF, video, codebase, generic (10 types) | +| Packaging | 4 | Package, upload, enhance, install skills | +| Splitting | 2 | Split large configs, generate routers | +| Sources | 5 | Fetch, submit, manage config sources | +| Vector DB | 4 | Export to Weaviate, Chroma, FAISS, Qdrant | +| Workflows | 5 | List, get, create, update, delete workflows | + +## Maintenance + +- Update description/tags on major releases +- No code changes needed — users always get the latest via `pip install` + +## Notes + +- Smithery CLI v4.7.0 removed the `--transport stdio` flag from the docs +- The CLI `publish` command only supports URL-based (external) publishing +- For local/stdio servers, use the web UI at smithery.ai/servers/new +- The namespace and server entity are already created; only the release needs to succeed diff --git a/docs/FAQ.md b/docs/FAQ.md index d5a47ed..8d3298c 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -9,7 +9,7 @@ ### What is Skill Seekers? -Skill Seekers is a Python tool that converts 17 source types — documentation websites, GitHub repos, PDFs, videos, Word docs, EPUB books, Jupyter notebooks, local HTML files, OpenAPI specs, AsciiDoc, PowerPoint, RSS/Atom feeds, man pages, Confluence wikis, Notion pages, Slack/Discord exports, and local codebases — into AI-ready formats for 16+ platforms: LLM platforms (Claude, Gemini, OpenAI), RAG frameworks (LangChain, LlamaIndex, Haystack), vector databases (ChromaDB, FAISS, Weaviate, Qdrant, Pinecone), and AI coding assistants (Cursor, Windsurf, Cline, Continue.dev). +Skill Seekers is a Python tool that converts 17 source types — documentation websites, GitHub repos, PDFs, videos, Word docs, EPUB books, Jupyter notebooks, local HTML files, OpenAPI specs, AsciiDoc, PowerPoint, RSS/Atom feeds, man pages, Confluence wikis, Notion pages, Slack/Discord exports, and local codebases — into AI-ready formats for 30+ platforms: LLM platforms (Claude, Gemini, OpenAI, MiniMax, OpenCode, Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI, Markdown), RAG frameworks (LangChain, LlamaIndex, Haystack), vector databases (ChromaDB, FAISS, Weaviate, Qdrant, Pinecone), and AI coding assistants (Cursor, Windsurf, Cline, Continue.dev, Roo, Aider, Bolt, Kilo, Kimi Code). **Use Cases:** - Create custom documentation skills for your favorite frameworks @@ -23,31 +23,44 @@ Skill Seekers is a Python tool that converts 17 source types — documentation w ### Which platforms are supported? -**Supported Platforms (16+):** +**Supported Platforms (30+):** -*LLM Platforms:* +*LLM Platforms (12):* 1. **Claude AI** - ZIP format with YAML frontmatter 2. **Google Gemini** - tar.gz format for Grounded Generation 3. **OpenAI ChatGPT** - ZIP format for Vector Stores -4. **Generic Markdown** - ZIP format with markdown files +4. **MiniMax** - ZIP format +5. **OpenCode** - ZIP format +6. **Kimi** - ZIP format +7. **DeepSeek** - ZIP format +8. **Qwen** - ZIP format +9. **OpenRouter** - ZIP format for multi-model routing +10. **Together AI** - ZIP format for open-source models +11. **Fireworks AI** - ZIP format for fast inference +12. **Generic Markdown** - ZIP format with markdown files *RAG Frameworks:* -5. **LangChain** - Document objects for QA chains and agents -6. **LlamaIndex** - TextNodes for query engines -7. **Haystack** - Document objects for enterprise RAG +13. **LangChain** - Document objects for QA chains and agents +14. **LlamaIndex** - TextNodes for query engines +15. **Haystack** - Document objects for enterprise RAG *Vector Databases:* -8. **ChromaDB** - Direct collection upload -9. **FAISS** - Index files for local similarity search -10. **Weaviate** - Vector objects with schema creation -11. **Qdrant** - Points with payload indexing -12. **Pinecone** - Ready-to-upsert format +16. **ChromaDB** - Direct collection upload +17. **FAISS** - Index files for local similarity search +18. **Weaviate** - Vector objects with schema creation +19. **Qdrant** - Points with payload indexing +20. **Pinecone** - Ready-to-upsert format -*AI Coding Assistants:* -13. **Cursor** - .cursorrules persistent context -14. **Windsurf** - .windsurfrules AI coding rules -15. **Cline** - .clinerules + MCP integration -16. **Continue.dev** - HTTP context server (all IDEs) +*AI Coding Assistants (9):* +21. **Cursor** - .cursorrules persistent context +22. **Windsurf** - .windsurfrules AI coding rules +23. **Cline** - .clinerules + MCP integration +24. **Continue.dev** - HTTP context server (all IDEs) +25. **Roo** - .roorules AI coding rules +26. **Aider** - Terminal AI coding assistant +27. **Bolt** - Web IDE AI context +28. **Kilo** - IDE AI context +29. **Kimi Code** - IDE AI context Each platform has a dedicated adaptor for optimal formatting and upload. @@ -404,6 +417,8 @@ skill-seekers install react --target claude --upload - Claude AI: Best for Claude Code integration - Google Gemini: Best for Grounded Generation in Gemini - OpenAI ChatGPT: Best for ChatGPT Custom GPTs +- MiniMax/Kimi/DeepSeek/Qwen: Best for Chinese LLM ecosystem +- OpenRouter/Together/Fireworks: Best for multi-model routing or open-source model access - Markdown: Generic export for other tools ### Can I use multiple platforms at once? @@ -412,7 +427,7 @@ Yes! Package and upload to all platforms: ```bash # Package for all platforms -for platform in claude gemini openai markdown; do +for platform in claude gemini openai minimax kimi deepseek qwen openrouter together fireworks markdown; do skill-seekers package output/react/ --target $platform done diff --git a/docs/README.md b/docs/README.md index a656cbc..9397504 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,7 +6,7 @@ ## Welcome! -This is the official documentation for **Skill Seekers** - the universal tool for converting **17 source types** (documentation sites, GitHub repos, PDFs, videos, Word docs, EPUB books, Jupyter notebooks, local HTML, OpenAPI specs, AsciiDoc, PowerPoint, RSS/Atom feeds, man pages, Confluence, Notion, Slack/Discord, and local codebases) into AI-ready skills for 16+ platforms. +This is the official documentation for **Skill Seekers** - the universal tool for converting **17 source types** (documentation sites, GitHub repos, PDFs, videos, Word docs, EPUB books, Jupyter notebooks, local HTML, OpenAPI specs, AsciiDoc, PowerPoint, RSS/Atom feeds, man pages, Confluence, Notion, Slack/Discord, and local codebases) into AI-ready skills for 30+ platforms. --- @@ -172,7 +172,7 @@ For LangChain, LlamaIndex, vector DBs: ### I Want AI Coding Assistance -For Cursor, Windsurf, Cline: +For Cursor, Windsurf, Cline, Roo, Aider, Bolt, Kilo, Continue, Kimi Code: 1. [Your First Skill](getting-started/03-your-first-skill.md) 2. [Local Codebase Analysis](user-guide/02-scraping.md#local-codebase-analysis) diff --git a/docs/UML/exports/00_package_overview.png b/docs/UML/exports/00_package_overview.png new file mode 100644 index 0000000..a842061 Binary files /dev/null and b/docs/UML/exports/00_package_overview.png differ diff --git a/docs/UML/exports/01_cli_core.png b/docs/UML/exports/01_cli_core.png new file mode 100644 index 0000000..7205b58 Binary files /dev/null and b/docs/UML/exports/01_cli_core.png differ diff --git a/docs/UML/exports/02_scrapers.png b/docs/UML/exports/02_scrapers.png new file mode 100644 index 0000000..641d1b2 Binary files /dev/null and b/docs/UML/exports/02_scrapers.png differ diff --git a/docs/UML/exports/03_adaptors.png b/docs/UML/exports/03_adaptors.png new file mode 100644 index 0000000..0690a11 Binary files /dev/null and b/docs/UML/exports/03_adaptors.png differ diff --git a/docs/UML/exports/04_analysis.png b/docs/UML/exports/04_analysis.png new file mode 100644 index 0000000..f080c0d Binary files /dev/null and b/docs/UML/exports/04_analysis.png differ diff --git a/docs/UML/exports/05_enhancement.png b/docs/UML/exports/05_enhancement.png new file mode 100644 index 0000000..2323f5b Binary files /dev/null and b/docs/UML/exports/05_enhancement.png differ diff --git a/docs/UML/exports/06_packaging.png b/docs/UML/exports/06_packaging.png new file mode 100644 index 0000000..227e9a4 Binary files /dev/null and b/docs/UML/exports/06_packaging.png differ diff --git a/docs/UML/exports/07_mcp_server.png b/docs/UML/exports/07_mcp_server.png new file mode 100644 index 0000000..b61c1ca Binary files /dev/null and b/docs/UML/exports/07_mcp_server.png differ diff --git a/docs/UML/exports/08_sync.png b/docs/UML/exports/08_sync.png new file mode 100644 index 0000000..bce2792 Binary files /dev/null and b/docs/UML/exports/08_sync.png differ diff --git a/docs/UML/exports/09_parsers.png b/docs/UML/exports/09_parsers.png new file mode 100644 index 0000000..1bec168 Binary files /dev/null and b/docs/UML/exports/09_parsers.png differ diff --git a/docs/UML/exports/10_storage.png b/docs/UML/exports/10_storage.png new file mode 100644 index 0000000..d8db2a0 Binary files /dev/null and b/docs/UML/exports/10_storage.png differ diff --git a/docs/UML/exports/11_embedding.png b/docs/UML/exports/11_embedding.png new file mode 100644 index 0000000..7e1bfa9 Binary files /dev/null and b/docs/UML/exports/11_embedding.png differ diff --git a/docs/UML/exports/12_benchmark.png b/docs/UML/exports/12_benchmark.png new file mode 100644 index 0000000..80a59f6 Binary files /dev/null and b/docs/UML/exports/12_benchmark.png differ diff --git a/docs/UML/exports/13_utilities.png b/docs/UML/exports/13_utilities.png new file mode 100644 index 0000000..55ac073 Binary files /dev/null and b/docs/UML/exports/13_utilities.png differ diff --git a/docs/UML/html/index.html/assets/css/bootstrap.css b/docs/UML/html/index.html/assets/css/bootstrap.css new file mode 100755 index 0000000..fa26e3c --- /dev/null +++ b/docs/UML/html/index.html/assets/css/bootstrap.css @@ -0,0 +1,6158 @@ +/*! + * Bootstrap v2.3.1 + * + * Copyright 2012 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + */ + +.clearfix { + *zoom: 1; +} + +.clearfix:before, +.clearfix:after { + display: table; + line-height: 0; + content: ""; +} + +.clearfix:after { + clear: both; +} + +.hide-text { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} + +.input-block-level { + display: block; + width: 100%; + min-height: 30px; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +nav, +section { + display: block; +} + +audio, +canvas, +video { + display: inline-block; + *display: inline; + *zoom: 1; +} + +audio:not([controls]) { + display: none; +} + +html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; +} + +a:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +a:hover, +a:active { + outline: 0; +} + +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} + +sup { + top: -0.5em; +} + +sub { + bottom: -0.25em; +} + +img { + width: auto\9; + height: auto; + max-width: 100%; + vertical-align: middle; + border: 0; + -ms-interpolation-mode: bicubic; +} + +#map_canvas img, +.google-maps img { + max-width: none; +} + +button, +input, +select, +textarea { + margin: 0; + font-size: 100%; + vertical-align: middle; +} + +button, +input { + *overflow: visible; + line-height: normal; +} + +button::-moz-focus-inner, +input::-moz-focus-inner { + padding: 0; + border: 0; +} + +button, +html input[type="button"], +input[type="reset"], +input[type="submit"] { + cursor: pointer; + -webkit-appearance: button; +} + +label, +select, +button, +input[type="button"], +input[type="reset"], +input[type="submit"], +input[type="radio"], +input[type="checkbox"] { + cursor: pointer; +} + +input[type="search"] { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + -webkit-appearance: textfield; +} + +input[type="search"]::-webkit-search-decoration, +input[type="search"]::-webkit-search-cancel-button { + -webkit-appearance: none; +} + +textarea { + overflow: auto; + vertical-align: top; +} + +@media print { + * { + color: #000 !important; + text-shadow: none !important; + background: transparent !important; + box-shadow: none !important; + } + a, + a:visited { + text-decoration: underline; + } + a[href]:after { + content: " (" attr(href) ")"; + } + abbr[title]:after { + content: " (" attr(title) ")"; + } + .ir a:after, + a[href^="javascript:"]:after, + a[href^="#"]:after { + content: ""; + } + pre, + blockquote { + border: 1px solid #999; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + tr, + img { + page-break-inside: avoid; + } + img { + max-width: 100% !important; + } + @page { + margin: 0.5cm; + } + p, + h2, + h3 { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } +} + +body { + margin: 0; + font-family: 'Source Sans Pro', Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 20px; + color: #333333; + background-color: #ffffff; +} + +a { + color: #0088cc; + text-decoration: none; +} + +a:hover, +a:focus { + color: #005580; + text-decoration: underline; +} + +.img-rounded { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.img-polaroid { + padding: 4px; + background-color: #fff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); +} + +.img-circle { + -webkit-border-radius: 500px; + -moz-border-radius: 500px; + border-radius: 500px; +} + +.row { + margin-left: -20px; + *zoom: 1; +} + +.row:before, +.row:after { + display: table; + line-height: 0; + content: ""; +} + +.row:after { + clear: both; +} + +[class*="span"] { + float: left; + min-height: 1px; + margin-left: 20px; +} + +.container, +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.span12 { + width: 940px; +} + +.span11 { + width: 860px; +} + +.span10 { + width: 780px; +} + +.span9 { + width: 700px; +} + +.span8 { + width: 620px; +} + +.span7 { + width: 540px; +} + +.span6 { + width: 460px; +} + +.span5 { + width: 380px; +} + +.span4 { + width: 300px; +} + +.span3 { + width: 220px; +} + +.span2 { + width: 140px; +} + +.span1 { + width: 60px; +} + +.offset12 { + margin-left: 980px; +} + +.offset11 { + margin-left: 900px; +} + +.offset10 { + margin-left: 820px; +} + +.offset9 { + margin-left: 740px; +} + +.offset8 { + margin-left: 660px; +} + +.offset7 { + margin-left: 580px; +} + +.offset6 { + margin-left: 500px; +} + +.offset5 { + margin-left: 420px; +} + +.offset4 { + margin-left: 340px; +} + +.offset3 { + margin-left: 260px; +} + +.offset2 { + margin-left: 180px; +} + +.offset1 { + margin-left: 100px; +} + +.row-fluid { + width: 100%; + *zoom: 1; +} + +.row-fluid:before, +.row-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.row-fluid:after { + clear: both; +} + +.row-fluid [class*="span"] { + display: block; + float: left; + width: 100%; + min-height: 30px; + margin-left: 2.127659574468085%; + *margin-left: 2.074468085106383%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.row-fluid [class*="span"]:first-child { + margin-left: 0; +} + +.row-fluid .controls-row [class*="span"] + [class*="span"] { + margin-left: 2.127659574468085%; +} + +.row-fluid .span12 { + width: 100%; + *width: 99.94680851063829%; +} + +.row-fluid .span11 { + width: 91.48936170212765%; + *width: 91.43617021276594%; +} + +.row-fluid .span10 { + width: 82.97872340425532%; + *width: 82.92553191489361%; +} + +.row-fluid .span9 { + width: 74.46808510638297%; + *width: 74.41489361702126%; +} + +.row-fluid .span8 { + width: 65.95744680851064%; + *width: 65.90425531914893%; +} + +.row-fluid .span7 { + width: 57.44680851063829%; + *width: 57.39361702127659%; +} + +.row-fluid .span6 { + width: 48.93617021276595%; + *width: 48.88297872340425%; +} + +.row-fluid .span5 { + width: 40.42553191489362%; + *width: 40.37234042553192%; +} + +.row-fluid .span4 { + width: 31.914893617021278%; + *width: 31.861702127659576%; +} + +.row-fluid .span3 { + width: 23.404255319148934%; + *width: 23.351063829787233%; +} + +.row-fluid .span2 { + width: 14.893617021276595%; + *width: 14.840425531914894%; +} + +.row-fluid .span1 { + width: 6.382978723404255%; + *width: 6.329787234042553%; +} + +.row-fluid .offset12 { + margin-left: 104.25531914893617%; + *margin-left: 104.14893617021275%; +} + +.row-fluid .offset12:first-child { + margin-left: 102.12765957446808%; + *margin-left: 102.02127659574467%; +} + +.row-fluid .offset11 { + margin-left: 95.74468085106382%; + *margin-left: 95.6382978723404%; +} + +.row-fluid .offset11:first-child { + margin-left: 93.61702127659574%; + *margin-left: 93.51063829787232%; +} + +.row-fluid .offset10 { + margin-left: 87.23404255319149%; + *margin-left: 87.12765957446807%; +} + +.row-fluid .offset10:first-child { + margin-left: 85.1063829787234%; + *margin-left: 84.99999999999999%; +} + +.row-fluid .offset9 { + margin-left: 78.72340425531914%; + *margin-left: 78.61702127659572%; +} + +.row-fluid .offset9:first-child { + margin-left: 76.59574468085106%; + *margin-left: 76.48936170212764%; +} + +.row-fluid .offset8 { + margin-left: 70.2127659574468%; + *margin-left: 70.10638297872339%; +} + +.row-fluid .offset8:first-child { + margin-left: 68.08510638297872%; + *margin-left: 67.9787234042553%; +} + +.row-fluid .offset7 { + margin-left: 61.70212765957446%; + *margin-left: 61.59574468085106%; +} + +.row-fluid .offset7:first-child { + margin-left: 59.574468085106375%; + *margin-left: 59.46808510638297%; +} + +.row-fluid .offset6 { + margin-left: 53.191489361702125%; + *margin-left: 53.085106382978715%; +} + +.row-fluid .offset6:first-child { + margin-left: 51.063829787234035%; + *margin-left: 50.95744680851063%; +} + +.row-fluid .offset5 { + margin-left: 44.68085106382979%; + *margin-left: 44.57446808510638%; +} + +.row-fluid .offset5:first-child { + margin-left: 42.5531914893617%; + *margin-left: 42.4468085106383%; +} + +.row-fluid .offset4 { + margin-left: 36.170212765957444%; + *margin-left: 36.06382978723405%; +} + +.row-fluid .offset4:first-child { + margin-left: 34.04255319148936%; + *margin-left: 33.93617021276596%; +} + +.row-fluid .offset3 { + margin-left: 27.659574468085104%; + *margin-left: 27.5531914893617%; +} + +.row-fluid .offset3:first-child { + margin-left: 25.53191489361702%; + *margin-left: 25.425531914893618%; +} + +.row-fluid .offset2 { + margin-left: 19.148936170212764%; + *margin-left: 19.04255319148936%; +} + +.row-fluid .offset2:first-child { + margin-left: 17.02127659574468%; + *margin-left: 16.914893617021278%; +} + +.row-fluid .offset1 { + margin-left: 10.638297872340425%; + *margin-left: 10.53191489361702%; +} + +.row-fluid .offset1:first-child { + margin-left: 8.51063829787234%; + *margin-left: 8.404255319148938%; +} + +[class*="span"].hide, +.row-fluid [class*="span"].hide { + display: none; +} + +[class*="span"].pull-right, +.row-fluid [class*="span"].pull-right { + float: right; +} + +.container { + margin-right: auto; + margin-left: auto; + *zoom: 1; +} + +.container:before, +.container:after { + display: table; + line-height: 0; + content: ""; +} + +.container:after { + clear: both; +} + +.container-fluid { + padding-right: 20px; + padding-left: 20px; + *zoom: 1; +} + +.container-fluid:before, +.container-fluid:after { + display: table; + line-height: 0; + content: ""; +} + +.container-fluid:after { + clear: both; +} + +p { + margin: 0 0 10px; +} + +.lead { + margin-bottom: 20px; + font-size: 21px; + font-weight: 200; + line-height: 30px; +} + +small { + font-size: 85%; +} + +strong { + font-weight: bold; +} + +em { + font-style: italic; +} + +cite { + font-style: normal; +} + +.muted { + color: #999999; +} + +a.muted:hover, +a.muted:focus { + color: #808080; +} + +.text-warning { + color: #c09853; +} + +a.text-warning:hover, +a.text-warning:focus { + color: #a47e3c; +} + +.text-error { + color: #b94a48; +} + +a.text-error:hover, +a.text-error:focus { + color: #953b39; +} + +.text-info { + color: #3a87ad; +} + +a.text-info:hover, +a.text-info:focus { + color: #2d6987; +} + +.text-success { + color: #468847; +} + +a.text-success:hover, +a.text-success:focus { + color: #356635; +} + +.text-left { + text-align: left; +} + +.text-right { + text-align: right; +} + +.text-center { + text-align: center; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0; + font-family: inherit; + font-weight: bold; + line-height: 20px; + color: inherit; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + font-weight: normal; + line-height: 1; + color: #999999; +} + +h1, +h2, +h3 { + line-height: 40px; +} + +h1 { + font-size: 38.5px; +} + +h2 { + font-size: 31.5px; +} + +h3 { + font-size: 24.5px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +h2 small { + font-size: 17.5px; +} + +h3 small { + font-size: 14px; +} + +h4 small { + font-size: 14px; +} + +.page-header { + padding-bottom: 9px; + margin: 20px 0 30px; + border-bottom: 1px solid #eeeeee; +} + +ul, +ol { + padding: 0; + margin: 0 0 10px 25px; +} + +ul ul, +ul ol, +ol ol, +ol ul { + margin-bottom: 0; +} + +li { + line-height: 20px; +} + +ul.unstyled, +ol.unstyled { + margin-left: 0; + list-style: none; +} + +ul.inline, +ol.inline { + margin-left: 0; + list-style: none; +} + +ul.inline > li, +ol.inline > li { + display: inline-block; + *display: inline; + padding-right: 5px; + padding-left: 5px; + *zoom: 1; +} + +dl { + margin-bottom: 20px; +} + +dt, +dd { + line-height: 20px; +} + +dt { + font-weight: bold; +} + +dd { + margin-left: 10px; +} + +.dl-horizontal { + *zoom: 1; +} + +.dl-horizontal:before, +.dl-horizontal:after { + display: table; + line-height: 0; + content: ""; +} + +.dl-horizontal:after { + clear: both; +} + +.dl-horizontal dt { + float: left; + width: 160px; + overflow: hidden; + clear: left; + text-align: right; + text-overflow: ellipsis; + white-space: nowrap; +} + +.dl-horizontal dd { + margin-left: 180px; +} + +hr { + margin: 20px 0; + border: 0; + border-top: 1px solid #eeeeee; + border-bottom: 1px solid #ffffff; +} + +abbr[title], +abbr[data-original-title] { + cursor: help; + border-bottom: 1px dotted #999999; +} + +abbr.initialism { + font-size: 90%; + text-transform: uppercase; +} + +blockquote { + padding: 0 0 0 15px; + margin: 0 0 20px; + border-left: 5px solid #eeeeee; +} + +blockquote p { + margin-bottom: 0; + font-size: 17.5px; + font-weight: 300; + line-height: 1.25; +} + +blockquote small { + display: block; + line-height: 20px; + color: #999999; +} + +blockquote small:before { + content: '\2014 \00A0'; +} + +blockquote.pull-right { + float: right; + padding-right: 15px; + padding-left: 0; + border-right: 5px solid #eeeeee; + border-left: 0; +} + +blockquote.pull-right p, +blockquote.pull-right small { + text-align: right; +} + +blockquote.pull-right small:before { + content: ''; +} + +blockquote.pull-right small:after { + content: '\00A0 \2014'; +} + +q:before, +q:after, +blockquote:before, +blockquote:after { + content: ""; +} + +address { + display: block; + margin-bottom: 20px; + font-style: normal; + line-height: 20px; +} + +code, +pre { + padding: 0 3px 2px; + font-family: Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #333333; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +code { + padding: 2px 4px; + color: #d14; + white-space: nowrap; + background-color: #f7f7f9; + border: 1px solid #e1e1e8; +} + +pre { + display: block; + padding: 9.5px; + margin: 0 0 10px; + font-size: 13px; + line-height: 20px; + word-break: break-all; + word-wrap: break-word; + white-space: pre; + white-space: pre-wrap; + background-color: #f5f5f5; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.15); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +pre.prettyprint { + margin-bottom: 20px; +} + +pre code { + padding: 0; + color: inherit; + white-space: pre; + white-space: pre-wrap; + background-color: transparent; + border: 0; +} + +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} + +form { + margin: 0 0 20px; +} + +fieldset { + padding: 0; + margin: 0; + border: 0; +} + +legend { + display: block; + width: 100%; + padding: 0; + margin-bottom: 20px; + font-size: 21px; + line-height: 40px; + color: #333333; + border: 0; + border-bottom: 1px solid #e5e5e5; +} + +legend small { + font-size: 15px; + color: #999999; +} + +label, +input, +button, +select, +textarea { + font-size: 14px; + font-weight: normal; + line-height: 20px; +} + +input, +button, +select, +textarea { + font-family: source-sans-pro, Helvetica, Arial, sans-serif; +} + +label { + display: block; + margin-bottom: 5px; +} + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + display: inline-block; + height: 20px; + padding: 4px 6px; + margin-bottom: 10px; + font-size: 14px; + line-height: 20px; + color: #555555; + vertical-align: middle; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +input, +textarea, +.uneditable-input { + width: 206px; +} + +textarea { + height: auto; +} + +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + background-color: #ffffff; + border: 1px solid #cccccc; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -webkit-transition: border linear 0.2s, box-shadow linear 0.2s; + -moz-transition: border linear 0.2s, box-shadow linear 0.2s; + -o-transition: border linear 0.2s, box-shadow linear 0.2s; + transition: border linear 0.2s, box-shadow linear 0.2s; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: rgba(82, 168, 236, 0.8); + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6); +} + +input[type="radio"], +input[type="checkbox"] { + margin: 4px 0 0; + margin-top: 1px \9; + *margin-top: 0; + line-height: normal; +} + +input[type="file"], +input[type="image"], +input[type="submit"], +input[type="reset"], +input[type="button"], +input[type="radio"], +input[type="checkbox"] { + width: auto; +} + +select, +input[type="file"] { + height: 30px; + /* In IE7, the height of the select element cannot be changed by height, only font-size */ + + *margin-top: 4px; + /* For IE7, add top margin to align select with labels */ + + line-height: 30px; +} + +select { + width: 220px; + background-color: #ffffff; + border: 1px solid #cccccc; +} + +select[multiple], +select[size] { + height: auto; +} + +select:focus, +input[type="file"]:focus, +input[type="radio"]:focus, +input[type="checkbox"]:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.uneditable-input, +.uneditable-textarea { + color: #999999; + cursor: not-allowed; + background-color: #fcfcfc; + border-color: #cccccc; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025); +} + +.uneditable-input { + overflow: hidden; + white-space: nowrap; +} + +.uneditable-textarea { + width: auto; + height: auto; +} + +input:-moz-placeholder, +textarea:-moz-placeholder { + color: #999999; +} + +input:-ms-input-placeholder, +textarea:-ms-input-placeholder { + color: #999999; +} + +input::-webkit-input-placeholder, +textarea::-webkit-input-placeholder { + color: #999999; +} + +.radio, +.checkbox { + min-height: 20px; + padding-left: 20px; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -20px; +} + +.controls > .radio:first-child, +.controls > .checkbox:first-child { + padding-top: 5px; +} + +.radio.inline, +.checkbox.inline { + display: inline-block; + padding-top: 5px; + margin-bottom: 0; + vertical-align: middle; +} + +.radio.inline + .radio.inline, +.checkbox.inline + .checkbox.inline { + margin-left: 10px; +} + +.input-mini { + width: 60px; +} + +.input-small { + width: 90px; +} + +.input-medium { + width: 150px; +} + +.input-large { + width: 210px; +} + +.input-xlarge { + width: 270px; +} + +.input-xxlarge { + width: 530px; +} + +input[class*="span"], +select[class*="span"], +textarea[class*="span"], +.uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"] { + float: none; + margin-left: 0; +} + +.input-append input[class*="span"], +.input-append .uneditable-input[class*="span"], +.input-prepend input[class*="span"], +.input-prepend .uneditable-input[class*="span"], +.row-fluid input[class*="span"], +.row-fluid select[class*="span"], +.row-fluid textarea[class*="span"], +.row-fluid .uneditable-input[class*="span"], +.row-fluid .input-prepend [class*="span"], +.row-fluid .input-append [class*="span"] { + display: inline-block; +} + +input, +textarea, +.uneditable-input { + margin-left: 0; +} + +.controls-row [class*="span"] + [class*="span"] { + margin-left: 20px; +} + +input.span12, +textarea.span12, +.uneditable-input.span12 { + width: 926px; +} + +input.span11, +textarea.span11, +.uneditable-input.span11 { + width: 846px; +} + +input.span10, +textarea.span10, +.uneditable-input.span10 { + width: 766px; +} + +input.span9, +textarea.span9, +.uneditable-input.span9 { + width: 686px; +} + +input.span8, +textarea.span8, +.uneditable-input.span8 { + width: 606px; +} + +input.span7, +textarea.span7, +.uneditable-input.span7 { + width: 526px; +} + +input.span6, +textarea.span6, +.uneditable-input.span6 { + width: 446px; +} + +input.span5, +textarea.span5, +.uneditable-input.span5 { + width: 366px; +} + +input.span4, +textarea.span4, +.uneditable-input.span4 { + width: 286px; +} + +input.span3, +textarea.span3, +.uneditable-input.span3 { + width: 206px; +} + +input.span2, +textarea.span2, +.uneditable-input.span2 { + width: 126px; +} + +input.span1, +textarea.span1, +.uneditable-input.span1 { + width: 46px; +} + +.controls-row { + *zoom: 1; +} + +.controls-row:before, +.controls-row:after { + display: table; + line-height: 0; + content: ""; +} + +.controls-row:after { + clear: both; +} + +.controls-row [class*="span"], +.row-fluid .controls-row [class*="span"] { + float: left; +} + +.controls-row .checkbox[class*="span"], +.controls-row .radio[class*="span"] { + padding-top: 5px; +} + +input[disabled], +select[disabled], +textarea[disabled], +input[readonly], +select[readonly], +textarea[readonly] { + cursor: not-allowed; + background-color: #eeeeee; +} + +input[type="radio"][disabled], +input[type="checkbox"][disabled], +input[type="radio"][readonly], +input[type="checkbox"][readonly] { + background-color: transparent; +} + +.control-group.warning .control-label, +.control-group.warning .help-block, +.control-group.warning .help-inline { + color: #c09853; +} + +.control-group.warning .checkbox, +.control-group.warning .radio, +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + color: #c09853; +} + +.control-group.warning input, +.control-group.warning select, +.control-group.warning textarea { + border-color: #c09853; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.warning input:focus, +.control-group.warning select:focus, +.control-group.warning textarea:focus { + border-color: #a47e3c; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e; +} + +.control-group.warning .input-prepend .add-on, +.control-group.warning .input-append .add-on { + color: #c09853; + background-color: #fcf8e3; + border-color: #c09853; +} + +.control-group.error .control-label, +.control-group.error .help-block, +.control-group.error .help-inline { + color: #b94a48; +} + +.control-group.error .checkbox, +.control-group.error .radio, +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + color: #b94a48; +} + +.control-group.error input, +.control-group.error select, +.control-group.error textarea { + border-color: #b94a48; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.error input:focus, +.control-group.error select:focus, +.control-group.error textarea:focus { + border-color: #953b39; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392; +} + +.control-group.error .input-prepend .add-on, +.control-group.error .input-append .add-on { + color: #b94a48; + background-color: #f2dede; + border-color: #b94a48; +} + +.control-group.success .control-label, +.control-group.success .help-block, +.control-group.success .help-inline { + color: #468847; +} + +.control-group.success .checkbox, +.control-group.success .radio, +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + color: #468847; +} + +.control-group.success input, +.control-group.success select, +.control-group.success textarea { + border-color: #468847; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.success input:focus, +.control-group.success select:focus, +.control-group.success textarea:focus { + border-color: #356635; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b; +} + +.control-group.success .input-prepend .add-on, +.control-group.success .input-append .add-on { + color: #468847; + background-color: #dff0d8; + border-color: #468847; +} + +.control-group.info .control-label, +.control-group.info .help-block, +.control-group.info .help-inline { + color: #3a87ad; +} + +.control-group.info .checkbox, +.control-group.info .radio, +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + color: #3a87ad; +} + +.control-group.info input, +.control-group.info select, +.control-group.info textarea { + border-color: #3a87ad; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); +} + +.control-group.info input:focus, +.control-group.info select:focus, +.control-group.info textarea:focus { + border-color: #2d6987; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3; +} + +.control-group.info .input-prepend .add-on, +.control-group.info .input-append .add-on { + color: #3a87ad; + background-color: #d9edf7; + border-color: #3a87ad; +} + +input:focus:invalid, +textarea:focus:invalid, +select:focus:invalid { + color: #b94a48; + border-color: #ee5f5b; +} + +input:focus:invalid:focus, +textarea:focus:invalid:focus, +select:focus:invalid:focus { + border-color: #e9322d; + -webkit-box-shadow: 0 0 6px #f8b9b7; + -moz-box-shadow: 0 0 6px #f8b9b7; + box-shadow: 0 0 6px #f8b9b7; +} + +.form-actions { + padding: 19px 20px 20px; + margin-top: 20px; + margin-bottom: 20px; + background-color: #f5f5f5; + border-top: 1px solid #e5e5e5; + *zoom: 1; +} + +.form-actions:before, +.form-actions:after { + display: table; + line-height: 0; + content: ""; +} + +.form-actions:after { + clear: both; +} + +.help-block, +.help-inline { + color: #595959; +} + +.help-block { + display: block; + margin-bottom: 10px; +} + +.help-inline { + display: inline-block; + *display: inline; + padding-left: 5px; + vertical-align: middle; + *zoom: 1; +} + +.input-append, +.input-prepend { + display: inline-block; + margin-bottom: 10px; + font-size: 0; + white-space: nowrap; + vertical-align: middle; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input, +.input-append .dropdown-menu, +.input-prepend .dropdown-menu, +.input-append .popover, +.input-prepend .popover { + font-size: 14px; +} + +.input-append input, +.input-prepend input, +.input-append select, +.input-prepend select, +.input-append .uneditable-input, +.input-prepend .uneditable-input { + position: relative; + margin-bottom: 0; + *margin-left: 0; + vertical-align: top; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append input:focus, +.input-prepend input:focus, +.input-append select:focus, +.input-prepend select:focus, +.input-append .uneditable-input:focus, +.input-prepend .uneditable-input:focus { + z-index: 2; +} + +.input-append .add-on, +.input-prepend .add-on { + display: inline-block; + width: auto; + height: 20px; + min-width: 16px; + padding: 4px 5px; + font-size: 14px; + font-weight: normal; + line-height: 20px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + background-color: #eeeeee; + border: 1px solid #ccc; +} + +.input-append .add-on, +.input-prepend .add-on, +.input-append .btn, +.input-prepend .btn, +.input-append .btn-group > .dropdown-toggle, +.input-prepend .btn-group > .dropdown-toggle { + vertical-align: top; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-append .active, +.input-prepend .active { + background-color: #a9dba9; + border-color: #46a546; +} + +.input-prepend .add-on, +.input-prepend .btn { + margin-right: -1px; +} + +.input-prepend .add-on:first-child, +.input-prepend .btn:first-child { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input, +.input-append select, +.input-append .uneditable-input { + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-append input + .btn-group .btn:last-child, +.input-append select + .btn-group .btn:last-child, +.input-append .uneditable-input + .btn-group .btn:last-child { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-append .add-on, +.input-append .btn, +.input-append .btn-group { + margin-left: -1px; +} + +.input-append .add-on:last-child, +.input-append .btn:last-child, +.input-append .btn-group:last-child > .dropdown-toggle { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append input, +.input-prepend.input-append select, +.input-prepend.input-append .uneditable-input { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.input-prepend.input-append input + .btn-group .btn, +.input-prepend.input-append select + .btn-group .btn, +.input-prepend.input-append .uneditable-input + .btn-group .btn { + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .add-on:first-child, +.input-prepend.input-append .btn:first-child { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.input-prepend.input-append .add-on:last-child, +.input-prepend.input-append .btn:last-child { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.input-prepend.input-append .btn-group:first-child { + margin-left: 0; +} + +input.search-query { + padding-right: 14px; + padding-right: 4px \9; + padding-left: 14px; + padding-left: 4px \9; + /* IE7-8 doesn't have border-radius, so don't indent the padding */ + + margin-bottom: 0; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +/* Allow for input prepend/append in search forms */ + +.form-search .input-append .search-query, +.form-search .input-prepend .search-query { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.form-search .input-append .search-query { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search .input-append .btn { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .search-query { + -webkit-border-radius: 0 14px 14px 0; + -moz-border-radius: 0 14px 14px 0; + border-radius: 0 14px 14px 0; +} + +.form-search .input-prepend .btn { + -webkit-border-radius: 14px 0 0 14px; + -moz-border-radius: 14px 0 0 14px; + border-radius: 14px 0 0 14px; +} + +.form-search input, +.form-inline input, +.form-horizontal input, +.form-search textarea, +.form-inline textarea, +.form-horizontal textarea, +.form-search select, +.form-inline select, +.form-horizontal select, +.form-search .help-inline, +.form-inline .help-inline, +.form-horizontal .help-inline, +.form-search .uneditable-input, +.form-inline .uneditable-input, +.form-horizontal .uneditable-input, +.form-search .input-prepend, +.form-inline .input-prepend, +.form-horizontal .input-prepend, +.form-search .input-append, +.form-inline .input-append, +.form-horizontal .input-append { + display: inline-block; + *display: inline; + margin-bottom: 0; + vertical-align: middle; + *zoom: 1; +} + +.form-search .hide, +.form-inline .hide, +.form-horizontal .hide { + display: none; +} + +.form-search label, +.form-inline label, +.form-search .btn-group, +.form-inline .btn-group { + display: inline-block; +} + +.form-search .input-append, +.form-inline .input-append, +.form-search .input-prepend, +.form-inline .input-prepend { + margin-bottom: 0; +} + +.form-search .radio, +.form-search .checkbox, +.form-inline .radio, +.form-inline .checkbox { + padding-left: 0; + margin-bottom: 0; + vertical-align: middle; +} + +.form-search .radio input[type="radio"], +.form-search .checkbox input[type="checkbox"], +.form-inline .radio input[type="radio"], +.form-inline .checkbox input[type="checkbox"] { + float: left; + margin-right: 3px; + margin-left: 0; +} + +.control-group { + margin-bottom: 10px; +} + +legend + .control-group { + margin-top: 20px; + -webkit-margin-top-collapse: separate; +} + +.form-horizontal .control-group { + margin-bottom: 20px; + *zoom: 1; +} + +.form-horizontal .control-group:before, +.form-horizontal .control-group:after { + display: table; + line-height: 0; + content: ""; +} + +.form-horizontal .control-group:after { + clear: both; +} + +.form-horizontal .control-label { + float: left; + width: 160px; + padding-top: 5px; + text-align: right; +} + +.form-horizontal .controls { + *display: inline-block; + *padding-left: 20px; + margin-left: 180px; + *margin-left: 0; +} + +.form-horizontal .controls:first-child { + *padding-left: 180px; +} + +.form-horizontal .help-block { + margin-bottom: 0; +} + +.form-horizontal input + .help-block, +.form-horizontal select + .help-block, +.form-horizontal textarea + .help-block, +.form-horizontal .uneditable-input + .help-block, +.form-horizontal .input-prepend + .help-block, +.form-horizontal .input-append + .help-block { + margin-top: 10px; +} + +.form-horizontal .form-actions { + padding-left: 180px; +} + +table { + max-width: 100%; + background-color: transparent; + border-collapse: collapse; + border-spacing: 0; +} + +.table { + width: 100%; + margin-bottom: 20px; +} + +.table th, +.table td { + padding: 8px; + line-height: 20px; + text-align: left; + vertical-align: top; + border-top: 1px solid #dddddd; +} + +.table th { + font-weight: bold; +} + +.table thead th { + vertical-align: bottom; +} + +.table caption + thead tr:first-child th, +.table caption + thead tr:first-child td, +.table colgroup + thead tr:first-child th, +.table colgroup + thead tr:first-child td, +.table thead:first-child tr:first-child th, +.table thead:first-child tr:first-child td { + border-top: 0; +} + +.table tbody + tbody { + border-top: 2px solid #dddddd; +} + +.table .table { + background-color: #ffffff; +} + +.table-condensed th, +.table-condensed td { + padding: 4px 5px; +} + +.table-bordered { + border: 1px solid #dddddd; + border-collapse: separate; + *border-collapse: collapse; + border-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.table-bordered th, +.table-bordered td { + border-left: 1px solid #dddddd; +} + +.table-bordered caption + thead tr:first-child th, +.table-bordered caption + tbody tr:first-child th, +.table-bordered caption + tbody tr:first-child td, +.table-bordered colgroup + thead tr:first-child th, +.table-bordered colgroup + tbody tr:first-child th, +.table-bordered colgroup + tbody tr:first-child td, +.table-bordered thead:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child th, +.table-bordered tbody:first-child tr:first-child td { + border-top: 0; +} + +.table-bordered thead:first-child tr:first-child > th:first-child, +.table-bordered tbody:first-child tr:first-child > td:first-child, +.table-bordered tbody:first-child tr:first-child > th:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered thead:first-child tr:first-child > th:last-child, +.table-bordered tbody:first-child tr:first-child > td:last-child, +.table-bordered tbody:first-child tr:first-child > th:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:first-child, +.table-bordered tbody:last-child tr:last-child > td:first-child, +.table-bordered tbody:last-child tr:last-child > th:first-child, +.table-bordered tfoot:last-child tr:last-child > td:first-child, +.table-bordered tfoot:last-child tr:last-child > th:first-child { + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.table-bordered thead:last-child tr:last-child > th:last-child, +.table-bordered tbody:last-child tr:last-child > td:last-child, +.table-bordered tbody:last-child tr:last-child > th:last-child, +.table-bordered tfoot:last-child tr:last-child > td:last-child, +.table-bordered tfoot:last-child tr:last-child > th:last-child { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-bottomright: 4px; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:first-child { + -webkit-border-bottom-left-radius: 0; + border-bottom-left-radius: 0; + -moz-border-radius-bottomleft: 0; +} + +.table-bordered tfoot + tbody:last-child tr:last-child td:last-child { + -webkit-border-bottom-right-radius: 0; + border-bottom-right-radius: 0; + -moz-border-radius-bottomright: 0; +} + +.table-bordered caption + thead tr:first-child th:first-child, +.table-bordered caption + tbody tr:first-child td:first-child, +.table-bordered colgroup + thead tr:first-child th:first-child, +.table-bordered colgroup + tbody tr:first-child td:first-child { + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topleft: 4px; +} + +.table-bordered caption + thead tr:first-child th:last-child, +.table-bordered caption + tbody tr:first-child td:last-child, +.table-bordered colgroup + thead tr:first-child th:last-child, +.table-bordered colgroup + tbody tr:first-child td:last-child { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -moz-border-radius-topright: 4px; +} + +.table-striped tbody > tr:nth-child(odd) > td, +.table-striped tbody > tr:nth-child(odd) > th { + background-color: #f9f9f9; +} + +.table-hover tbody tr:hover > td, +.table-hover tbody tr:hover > th { + background-color: #f5f5f5; +} + +table td[class*="span"], +table th[class*="span"], +.row-fluid table td[class*="span"], +.row-fluid table th[class*="span"] { + display: table-cell; + float: none; + margin-left: 0; +} + +.table td.span1, +.table th.span1 { + float: none; + width: 44px; + margin-left: 0; +} + +.table td.span2, +.table th.span2 { + float: none; + width: 124px; + margin-left: 0; +} + +.table td.span3, +.table th.span3 { + float: none; + width: 204px; + margin-left: 0; +} + +.table td.span4, +.table th.span4 { + float: none; + width: 284px; + margin-left: 0; +} + +.table td.span5, +.table th.span5 { + float: none; + width: 364px; + margin-left: 0; +} + +.table td.span6, +.table th.span6 { + float: none; + width: 444px; + margin-left: 0; +} + +.table td.span7, +.table th.span7 { + float: none; + width: 524px; + margin-left: 0; +} + +.table td.span8, +.table th.span8 { + float: none; + width: 604px; + margin-left: 0; +} + +.table td.span9, +.table th.span9 { + float: none; + width: 684px; + margin-left: 0; +} + +.table td.span10, +.table th.span10 { + float: none; + width: 764px; + margin-left: 0; +} + +.table td.span11, +.table th.span11 { + float: none; + width: 844px; + margin-left: 0; +} + +.table td.span12, +.table th.span12 { + float: none; + width: 924px; + margin-left: 0; +} + +.table tbody tr.success > td { + background-color: #dff0d8; +} + +.table tbody tr.error > td { + background-color: #f2dede; +} + +.table tbody tr.warning > td { + background-color: #fcf8e3; +} + +.table tbody tr.info > td { + background-color: #d9edf7; +} + +.table-hover tbody tr.success:hover > td { + background-color: #d0e9c6; +} + +.table-hover tbody tr.error:hover > td { + background-color: #ebcccc; +} + +.table-hover tbody tr.warning:hover > td { + background-color: #faf2cc; +} + +.table-hover tbody tr.info:hover > td { + background-color: #c4e3f3; +} + +[class^="icon-"], +[class*=" icon-"] { + display: inline-block; + width: 14px; + height: 14px; + margin-top: 1px; + *margin-right: .3em; + line-height: 14px; + vertical-align: text-top; + background-image: url("../img/glyphicons-halflings.png"); + background-position: 14px 14px; + background-repeat: no-repeat; +} + +/* White icons with optional class, or on hover/focus/active states of certain elements */ + +.icon-white, +.nav-pills > .active > a > [class^="icon-"], +.nav-pills > .active > a > [class*=" icon-"], +.nav-list > .active > a > [class^="icon-"], +.nav-list > .active > a > [class*=" icon-"], +.navbar-inverse .nav > .active > a > [class^="icon-"], +.navbar-inverse .nav > .active > a > [class*=" icon-"], +.dropdown-menu > li > a:hover > [class^="icon-"], +.dropdown-menu > li > a:focus > [class^="icon-"], +.dropdown-menu > li > a:hover > [class*=" icon-"], +.dropdown-menu > li > a:focus > [class*=" icon-"], +.dropdown-menu > .active > a > [class^="icon-"], +.dropdown-menu > .active > a > [class*=" icon-"], +.dropdown-submenu:hover > a > [class^="icon-"], +.dropdown-submenu:focus > a > [class^="icon-"], +.dropdown-submenu:hover > a > [class*=" icon-"], +.dropdown-submenu:focus > a > [class*=" icon-"] { + background-image: url("../img/glyphicons-halflings-white.png"); +} + +.icon-glass { + background-position: 0 0; +} + +.icon-music { + background-position: -24px 0; +} + +.icon-search { + background-position: -48px 0; +} + +.icon-envelope { + background-position: -72px 0; +} + +.icon-heart { + background-position: -96px 0; +} + +.icon-star { + background-position: -120px 0; +} + +.icon-star-empty { + background-position: -144px 0; +} + +.icon-user { + background-position: -168px 0; +} + +.icon-film { + background-position: -192px 0; +} + +.icon-th-large { + background-position: -216px 0; +} + +.icon-th { + background-position: -240px 0; +} + +.icon-th-list { + background-position: -264px 0; +} + +.icon-ok { + background-position: -288px 0; +} + +.icon-remove { + background-position: -312px 0; +} + +.icon-zoom-in { + background-position: -336px 0; +} + +.icon-zoom-out { + background-position: -360px 0; +} + +.icon-off { + background-position: -384px 0; +} + +.icon-signal { + background-position: -408px 0; +} + +.icon-cog { + background-position: -432px 0; +} + +.icon-trash { + background-position: -456px 0; +} + +.icon-home { + background-position: 0 -24px; +} + +.icon-file { + background-position: -24px -24px; +} + +.icon-time { + background-position: -48px -24px; +} + +.icon-road { + background-position: -72px -24px; +} + +.icon-download-alt { + background-position: -96px -24px; +} + +.icon-download { + background-position: -120px -24px; +} + +.icon-upload { + background-position: -144px -24px; +} + +.icon-inbox { + background-position: -168px -24px; +} + +.icon-play-circle { + background-position: -192px -24px; +} + +.icon-repeat { + background-position: -216px -24px; +} + +.icon-refresh { + background-position: -240px -24px; +} + +.icon-list-alt { + background-position: -264px -24px; +} + +.icon-lock { + background-position: -287px -24px; +} + +.icon-flag { + background-position: -312px -24px; +} + +.icon-headphones { + background-position: -336px -24px; +} + +.icon-volume-off { + background-position: -360px -24px; +} + +.icon-volume-down { + background-position: -384px -24px; +} + +.icon-volume-up { + background-position: -408px -24px; +} + +.icon-qrcode { + background-position: -432px -24px; +} + +.icon-barcode { + background-position: -456px -24px; +} + +.icon-tag { + background-position: 0 -48px; +} + +.icon-tags { + background-position: -25px -48px; +} + +.icon-book { + background-position: -48px -48px; +} + +.icon-bookmark { + background-position: -72px -48px; +} + +.icon-print { + background-position: -96px -48px; +} + +.icon-camera { + background-position: -120px -48px; +} + +.icon-font { + background-position: -144px -48px; +} + +.icon-bold { + background-position: -167px -48px; +} + +.icon-italic { + background-position: -192px -48px; +} + +.icon-text-height { + background-position: -216px -48px; +} + +.icon-text-width { + background-position: -240px -48px; +} + +.icon-align-left { + background-position: -264px -48px; +} + +.icon-align-center { + background-position: -288px -48px; +} + +.icon-align-right { + background-position: -312px -48px; +} + +.icon-align-justify { + background-position: -336px -48px; +} + +.icon-list { + background-position: -360px -48px; +} + +.icon-indent-left { + background-position: -384px -48px; +} + +.icon-indent-right { + background-position: -408px -48px; +} + +.icon-facetime-video { + background-position: -432px -48px; +} + +.icon-picture { + background-position: -456px -48px; +} + +.icon-pencil { + background-position: 0 -72px; +} + +.icon-map-marker { + background-position: -24px -72px; +} + +.icon-adjust { + background-position: -48px -72px; +} + +.icon-tint { + background-position: -72px -72px; +} + +.icon-edit { + background-position: -96px -72px; +} + +.icon-share { + background-position: -120px -72px; +} + +.icon-check { + background-position: -144px -72px; +} + +.icon-move { + background-position: -168px -72px; +} + +.icon-step-backward { + background-position: -192px -72px; +} + +.icon-fast-backward { + background-position: -216px -72px; +} + +.icon-backward { + background-position: -240px -72px; +} + +.icon-play { + background-position: -264px -72px; +} + +.icon-pause { + background-position: -288px -72px; +} + +.icon-stop { + background-position: -312px -72px; +} + +.icon-forward { + background-position: -336px -72px; +} + +.icon-fast-forward { + background-position: -360px -72px; +} + +.icon-step-forward { + background-position: -384px -72px; +} + +.icon-eject { + background-position: -408px -72px; +} + +.icon-chevron-left { + background-position: -432px -72px; +} + +.icon-chevron-right { + background-position: -456px -72px; +} + +.icon-plus-sign { + background-position: 0 -96px; +} + +.icon-minus-sign { + background-position: -24px -96px; +} + +.icon-remove-sign { + background-position: -48px -96px; +} + +.icon-ok-sign { + background-position: -72px -96px; +} + +.icon-question-sign { + background-position: -96px -96px; +} + +.icon-info-sign { + background-position: -120px -96px; +} + +.icon-screenshot { + background-position: -144px -96px; +} + +.icon-remove-circle { + background-position: -168px -96px; +} + +.icon-ok-circle { + background-position: -192px -96px; +} + +.icon-ban-circle { + background-position: -216px -96px; +} + +.icon-arrow-left { + background-position: -240px -96px; +} + +.icon-arrow-right { + background-position: -264px -96px; +} + +.icon-arrow-up { + background-position: -289px -96px; +} + +.icon-arrow-down { + background-position: -312px -96px; +} + +.icon-share-alt { + background-position: -336px -96px; +} + +.icon-resize-full { + background-position: -360px -96px; +} + +.icon-resize-small { + background-position: -384px -96px; +} + +.icon-plus { + background-position: -408px -96px; +} + +.icon-minus { + background-position: -433px -96px; +} + +.icon-asterisk { + background-position: -456px -96px; +} + +.icon-exclamation-sign { + background-position: 0 -120px; +} + +.icon-gift { + background-position: -24px -120px; +} + +.icon-leaf { + background-position: -48px -120px; +} + +.icon-fire { + background-position: -72px -120px; +} + +.icon-eye-open { + background-position: -96px -120px; +} + +.icon-eye-close { + background-position: -120px -120px; +} + +.icon-warning-sign { + background-position: -144px -120px; +} + +.icon-plane { + background-position: -168px -120px; +} + +.icon-calendar { + background-position: -192px -120px; +} + +.icon-random { + width: 16px; + background-position: -216px -120px; +} + +.icon-comment { + background-position: -240px -120px; +} + +.icon-magnet { + background-position: -264px -120px; +} + +.icon-chevron-up { + background-position: -288px -120px; +} + +.icon-chevron-down { + background-position: -313px -119px; +} + +.icon-retweet { + background-position: -336px -120px; +} + +.icon-shopping-cart { + background-position: -360px -120px; +} + +.icon-folder-close { + width: 16px; + background-position: -384px -120px; +} + +.icon-folder-open { + width: 16px; + background-position: -408px -120px; +} + +.icon-resize-vertical { + background-position: -432px -119px; +} + +.icon-resize-horizontal { + background-position: -456px -118px; +} + +.icon-hdd { + background-position: 0 -144px; +} + +.icon-bullhorn { + background-position: -24px -144px; +} + +.icon-bell { + background-position: -48px -144px; +} + +.icon-certificate { + background-position: -72px -144px; +} + +.icon-thumbs-up { + background-position: -96px -144px; +} + +.icon-thumbs-down { + background-position: -120px -144px; +} + +.icon-hand-right { + background-position: -144px -144px; +} + +.icon-hand-left { + background-position: -168px -144px; +} + +.icon-hand-up { + background-position: -192px -144px; +} + +.icon-hand-down { + background-position: -216px -144px; +} + +.icon-circle-arrow-right { + background-position: -240px -144px; +} + +.icon-circle-arrow-left { + background-position: -264px -144px; +} + +.icon-circle-arrow-up { + background-position: -288px -144px; +} + +.icon-circle-arrow-down { + background-position: -312px -144px; +} + +.icon-globe { + background-position: -336px -144px; +} + +.icon-wrench { + background-position: -360px -144px; +} + +.icon-tasks { + background-position: -384px -144px; +} + +.icon-filter { + background-position: -408px -144px; +} + +.icon-briefcase { + background-position: -432px -144px; +} + +.icon-fullscreen { + background-position: -456px -144px; +} + +.dropup, +.dropdown { + position: relative; +} + +.dropdown-toggle { + *margin-bottom: -3px; +} + +.dropdown-toggle:active, +.open .dropdown-toggle { + outline: 0; +} + +.caret { + display: inline-block; + width: 0; + height: 0; + vertical-align: top; + border-top: 4px solid #000000; + border-right: 4px solid transparent; + border-left: 4px solid transparent; + content: ""; +} + +.dropdown .caret { + margin-top: 8px; + margin-left: 2px; +} + +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 160px; + padding: 5px 0; + margin: 2px 0 0; + list-style: none; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.dropdown-menu .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.dropdown-menu > li > a { + display: block; + padding: 3px 20px; + clear: both; + font-weight: normal; + line-height: 20px; + color: #333333; + white-space: nowrap; +} + +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus, +.dropdown-submenu:hover > a, +.dropdown-submenu:focus > a { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .active > a, +.dropdown-menu > .active > a:hover, +.dropdown-menu > .active > a:focus { + color: #ffffff; + text-decoration: none; + background-color: #0081c2; + background-image: -moz-linear-gradient(top, #0088cc, #0077b3); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3)); + background-image: -webkit-linear-gradient(top, #0088cc, #0077b3); + background-image: -o-linear-gradient(top, #0088cc, #0077b3); + background-image: linear-gradient(to bottom, #0088cc, #0077b3); + background-repeat: repeat-x; + outline: 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0); +} + +.dropdown-menu > .disabled > a, +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + color: #999999; +} + +.dropdown-menu > .disabled > a:hover, +.dropdown-menu > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; + background-image: none; + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.open { + *z-index: 1000; +} + +.open > .dropdown-menu { + display: block; +} + +.pull-right > .dropdown-menu { + right: 0; + left: auto; +} + +.dropup .caret, +.navbar-fixed-bottom .dropdown .caret { + border-top: 0; + border-bottom: 4px solid #000000; + content: ""; +} + +.dropup .dropdown-menu, +.navbar-fixed-bottom .dropdown .dropdown-menu { + top: auto; + bottom: 100%; + margin-bottom: 1px; +} + +.dropdown-submenu { + position: relative; +} + +.dropdown-submenu > .dropdown-menu { + top: 0; + left: 100%; + margin-top: -6px; + margin-left: -1px; + -webkit-border-radius: 0 6px 6px 6px; + -moz-border-radius: 0 6px 6px 6px; + border-radius: 0 6px 6px 6px; +} + +.dropdown-submenu:hover > .dropdown-menu { + display: block; +} + +.dropup .dropdown-submenu > .dropdown-menu { + top: auto; + bottom: 0; + margin-top: 0; + margin-bottom: -2px; + -webkit-border-radius: 5px 5px 5px 0; + -moz-border-radius: 5px 5px 5px 0; + border-radius: 5px 5px 5px 0; +} + +.dropdown-submenu > a:after { + display: block; + float: right; + width: 0; + height: 0; + margin-top: 5px; + margin-right: -10px; + border-color: transparent; + border-left-color: #cccccc; + border-style: solid; + border-width: 5px 0 5px 5px; + content: " "; +} + +.dropdown-submenu:hover > a:after { + border-left-color: #ffffff; +} + +.dropdown-submenu.pull-left { + float: none; +} + +.dropdown-submenu.pull-left > .dropdown-menu { + left: -100%; + margin-left: 10px; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.dropdown .dropdown-menu .nav-header { + padding-right: 20px; + padding-left: 20px; +} + +.typeahead { + z-index: 1051; + margin-top: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.well { + min-height: 20px; + padding: 19px; + margin-bottom: 20px; + background-color: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); +} + +.well blockquote { + border-color: #ddd; + border-color: rgba(0, 0, 0, 0.15); +} + +.well-large { + padding: 24px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.well-small { + padding: 9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.fade { + opacity: 0; + -webkit-transition: opacity 0.15s linear; + -moz-transition: opacity 0.15s linear; + -o-transition: opacity 0.15s linear; + transition: opacity 0.15s linear; +} + +.fade.in { + opacity: 1; +} + +.collapse { + position: relative; + height: 0; + overflow: hidden; + -webkit-transition: height 0.35s ease; + -moz-transition: height 0.35s ease; + -o-transition: height 0.35s ease; + transition: height 0.35s ease; +} + +.collapse.in { + height: auto; +} + +.close { + float: right; + font-size: 20px; + font-weight: bold; + line-height: 20px; + color: #000000; + text-shadow: 0 1px 0 #ffffff; + opacity: 0.2; + filter: alpha(opacity=20); +} + +.close:hover, +.close:focus { + color: #000000; + text-decoration: none; + cursor: pointer; + opacity: 0.4; + filter: alpha(opacity=40); +} + +button.close { + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + -webkit-appearance: none; +} + +.btn { + display: inline-block; + *display: inline; + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #333333; + text-align: center; + text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); + vertical-align: middle; + cursor: pointer; + background-color: #f5f5f5; + *background-color: #e6e6e6; + background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6)); + background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6); + background-image: -o-linear-gradient(top, #ffffff, #e6e6e6); + background-image: linear-gradient(to bottom, #ffffff, #e6e6e6); + background-repeat: repeat-x; + border: 1px solid #cccccc; + *border: 0; + border-color: #e6e6e6 #e6e6e6 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + border-bottom-color: #b3b3b3; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #333333; + background-color: #e6e6e6; + *background-color: #d9d9d9; +} + +.btn:active, +.btn.active { + background-color: #cccccc \9; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #333333; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + outline: thin dotted #333; + outline: 5px auto -webkit-focus-ring-color; + outline-offset: -2px; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + +.btn-warning { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #faa732; + *background-color: #f89406; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + border-color: #f89406 #f89406 #ad6704; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-warning:hover, +.btn-warning:focus, +.btn-warning:active, +.btn-warning.active, +.btn-warning.disabled, +.btn-warning[disabled] { + color: #ffffff; + background-color: #f89406; + *background-color: #df8505; +} + +.btn-warning:active, +.btn-warning.active { + background-color: #c67605 \9; +} + +.btn-danger { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #da4f49; + *background-color: #bd362f; + background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f); + background-image: -o-linear-gradient(top, #ee5f5b, #bd362f); + background-image: linear-gradient(to bottom, #ee5f5b, #bd362f); + background-repeat: repeat-x; + border-color: #bd362f #bd362f #802420; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-danger:hover, +.btn-danger:focus, +.btn-danger:active, +.btn-danger.active, +.btn-danger.disabled, +.btn-danger[disabled] { + color: #ffffff; + background-color: #bd362f; + *background-color: #a9302a; +} + +.btn-danger:active, +.btn-danger.active { + background-color: #942a25 \9; +} + +.btn-success { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #5bb75b; + *background-color: #51a351; + background-image: -moz-linear-gradient(top, #62c462, #51a351); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351)); + background-image: -webkit-linear-gradient(top, #62c462, #51a351); + background-image: -o-linear-gradient(top, #62c462, #51a351); + background-image: linear-gradient(to bottom, #62c462, #51a351); + background-repeat: repeat-x; + border-color: #51a351 #51a351 #387038; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-success:hover, +.btn-success:focus, +.btn-success:active, +.btn-success.active, +.btn-success.disabled, +.btn-success[disabled] { + color: #ffffff; + background-color: #51a351; + *background-color: #499249; +} + +.btn-success:active, +.btn-success.active { + background-color: #408140 \9; +} + +.btn-info { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #49afcd; + *background-color: #2f96b4; + background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4)); + background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4); + background-image: -o-linear-gradient(top, #5bc0de, #2f96b4); + background-image: linear-gradient(to bottom, #5bc0de, #2f96b4); + background-repeat: repeat-x; + border-color: #2f96b4 #2f96b4 #1f6377; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-info:hover, +.btn-info:focus, +.btn-info:active, +.btn-info.active, +.btn-info.disabled, +.btn-info[disabled] { + color: #ffffff; + background-color: #2f96b4; + *background-color: #2a85a0; +} + +.btn-info:active, +.btn-info.active { + background-color: #24748c \9; +} + +.btn-inverse { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #363636; + *background-color: #222222; + background-image: -moz-linear-gradient(top, #444444, #222222); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222)); + background-image: -webkit-linear-gradient(top, #444444, #222222); + background-image: -o-linear-gradient(top, #444444, #222222); + background-image: linear-gradient(to bottom, #444444, #222222); + background-repeat: repeat-x; + border-color: #222222 #222222 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-inverse:hover, +.btn-inverse:focus, +.btn-inverse:active, +.btn-inverse.active, +.btn-inverse.disabled, +.btn-inverse[disabled] { + color: #ffffff; + background-color: #222222; + *background-color: #151515; +} + +.btn-inverse:active, +.btn-inverse.active { + background-color: #080808 \9; +} + +button.btn, +input[type="submit"].btn { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn::-moz-focus-inner, +input[type="submit"].btn::-moz-focus-inner { + padding: 0; + border: 0; +} + +button.btn.btn-large, +input[type="submit"].btn.btn-large { + *padding-top: 7px; + *padding-bottom: 7px; +} + +button.btn.btn-small, +input[type="submit"].btn.btn-small { + *padding-top: 3px; + *padding-bottom: 3px; +} + +button.btn.btn-mini, +input[type="submit"].btn.btn-mini { + *padding-top: 1px; + *padding-bottom: 1px; +} + +.btn-link, +.btn-link:active, +.btn-link[disabled] { + background-color: transparent; + background-image: none; + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-link { + color: #0088cc; + cursor: pointer; + border-color: transparent; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-link:hover, +.btn-link:focus { + color: #005580; + text-decoration: underline; + background-color: transparent; +} + +.btn-link[disabled]:hover, +.btn-link[disabled]:focus { + color: #333333; + text-decoration: none; +} + +.btn-group { + position: relative; + display: inline-block; + *display: inline; + *margin-left: .3em; + font-size: 0; + white-space: nowrap; + vertical-align: middle; + *zoom: 1; +} + +.btn-group:first-child { + *margin-left: 0; +} + +.btn-group + .btn-group { + margin-left: 5px; +} + +.btn-toolbar { + margin-top: 10px; + margin-bottom: 10px; + font-size: 0; +} + +.btn-toolbar > .btn + .btn, +.btn-toolbar > .btn-group + .btn, +.btn-toolbar > .btn + .btn-group { + margin-left: 5px; +} + +.btn-group > .btn { + position: relative; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group > .btn + .btn { + margin-left: -1px; +} + +.btn-group > .btn, +.btn-group > .dropdown-menu, +.btn-group > .popover { + font-size: 14px; +} + +.btn-group > .btn-mini { + font-size: 10.5px; +} + +.btn-group > .btn-small { + font-size: 11.9px; +} + +.btn-group > .btn-large { + font-size: 17.5px; +} + +.btn-group > .btn:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.btn-group > .btn:last-child, +.btn-group > .dropdown-toggle { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.btn-group > .btn.large:first-child { + margin-left: 0; + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.btn-group > .btn.large:last-child, +.btn-group > .large.dropdown-toggle { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.btn-group > .btn:hover, +.btn-group > .btn:focus, +.btn-group > .btn:active, +.btn-group > .btn.active { + z-index: 2; +} + +.btn-group .dropdown-toggle:active, +.btn-group.open .dropdown-toggle { + outline: 0; +} + +.btn-group > .btn + .dropdown-toggle { + *padding-top: 5px; + padding-right: 8px; + *padding-bottom: 5px; + padding-left: 8px; + -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group > .btn-mini + .dropdown-toggle { + *padding-top: 2px; + padding-right: 5px; + *padding-bottom: 2px; + padding-left: 5px; +} + +.btn-group > .btn-small + .dropdown-toggle { + *padding-top: 5px; + *padding-bottom: 4px; +} + +.btn-group > .btn-large + .dropdown-toggle { + *padding-top: 7px; + padding-right: 12px; + *padding-bottom: 7px; + padding-left: 12px; +} + +.btn-group.open .dropdown-toggle { + background-image: none; + -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.btn-group.open .btn.dropdown-toggle { + background-color: #e6e6e6; +} + +.btn-group.open .btn-primary.dropdown-toggle { + background-color: #0044cc; +} + +.btn-group.open .btn-warning.dropdown-toggle { + background-color: #f89406; +} + +.btn-group.open .btn-danger.dropdown-toggle { + background-color: #bd362f; +} + +.btn-group.open .btn-success.dropdown-toggle { + background-color: #51a351; +} + +.btn-group.open .btn-info.dropdown-toggle { + background-color: #2f96b4; +} + +.btn-group.open .btn-inverse.dropdown-toggle { + background-color: #222222; +} + +.btn .caret { + margin-top: 8px; + margin-left: 0; +} + +.btn-large .caret { + margin-top: 6px; +} + +.btn-large .caret { + border-top-width: 5px; + border-right-width: 5px; + border-left-width: 5px; +} + +.btn-mini .caret, +.btn-small .caret { + margin-top: 8px; +} + +.dropup .btn-large .caret { + border-bottom-width: 5px; +} + +.btn-primary .caret, +.btn-warning .caret, +.btn-danger .caret, +.btn-info .caret, +.btn-success .caret, +.btn-inverse .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.btn-group-vertical { + display: inline-block; + *display: inline; + /* IE7 inline-block hack */ + + *zoom: 1; +} + +.btn-group-vertical > .btn { + display: block; + float: none; + max-width: 100%; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.btn-group-vertical > .btn + .btn { + margin-top: -1px; + margin-left: 0; +} + +.btn-group-vertical > .btn:first-child { + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.btn-group-vertical > .btn:last-child { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.btn-group-vertical > .btn-large:first-child { + -webkit-border-radius: 6px 6px 0 0; + -moz-border-radius: 6px 6px 0 0; + border-radius: 6px 6px 0 0; +} + +.btn-group-vertical > .btn-large:last-child { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.alert { + padding: 8px 35px 8px 14px; + margin-bottom: 20px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + background-color: #fcf8e3; + border: 1px solid #fbeed5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.alert, +.alert h4 { + color: #c09853; +} + +.alert h4 { + margin: 0; +} + +.alert .close { + position: relative; + top: -2px; + right: -21px; + line-height: 20px; +} + +.alert-success { + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6; +} + +.alert-success h4 { + color: #468847; +} + +.alert-danger, +.alert-error { + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7; +} + +.alert-danger h4, +.alert-error h4 { + color: #b94a48; +} + +.alert-info { + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1; +} + +.alert-info h4 { + color: #3a87ad; +} + +.alert-block { + padding-top: 14px; + padding-bottom: 14px; +} + +.alert-block > p, +.alert-block > ul { + margin-bottom: 0; +} + +.alert-block p + p { + margin-top: 5px; +} + +.nav { + margin-bottom: 20px; + margin-left: 0; + list-style: none; +} + +.nav > li > a { + display: block; +} + +.nav > li > a:hover, +.nav > li > a:focus { + text-decoration: none; + background-color: #eeeeee; +} + +.nav > li > a > img { + max-width: none; +} + +.nav > .pull-right { + float: right; +} + +.nav-header { + display: block; + padding: 3px 15px; + font-size: 11px; + font-weight: bold; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: uppercase; +} + +.nav li + .nav-header { + margin-top: 9px; +} + +.nav-list { + padding-right: 15px; + padding-left: 15px; + margin-bottom: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + margin-right: -15px; + margin-left: -15px; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); +} + +.nav-list > li > a { + padding: 3px 15px; +} + +.nav-list > .active > a, +.nav-list > .active > a:hover, +.nav-list > .active > a:focus { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2); + background-color: #0088cc; +} + +.nav-list [class^="icon-"], +.nav-list [class*=" icon-"] { + margin-right: 2px; +} + +.nav-list .divider { + *width: 100%; + height: 1px; + margin: 9px 1px; + *margin: -5px 0 5px; + overflow: hidden; + background-color: #e5e5e5; + border-bottom: 1px solid #ffffff; +} + +.nav-tabs, +.nav-pills { + *zoom: 1; +} + +.nav-tabs:before, +.nav-pills:before, +.nav-tabs:after, +.nav-pills:after { + display: table; + line-height: 0; + content: ""; +} + +.nav-tabs:after, +.nav-pills:after { + clear: both; +} + +.nav-tabs > li, +.nav-pills > li { + float: left; +} + +.nav-tabs > li > a, +.nav-pills > li > a { + padding-right: 12px; + padding-left: 12px; + margin-right: 2px; + line-height: 14px; +} + +.nav-tabs { + border-bottom: 1px solid #ddd; +} + +.nav-tabs > li { + margin-bottom: -1px; +} + +.nav-tabs > li > a { + padding-top: 8px; + padding-bottom: 8px; + line-height: 20px; + border: 1px solid transparent; + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; +} + +.nav-tabs > li > a:hover, +.nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #dddddd; +} + +.nav-tabs > .active > a, +.nav-tabs > .active > a:hover, +.nav-tabs > .active > a:focus { + color: #555555; + cursor: default; + background-color: #ffffff; + border: 1px solid #ddd; + border-bottom-color: transparent; +} + +.nav-pills > li > a { + padding-top: 8px; + padding-bottom: 8px; + margin-top: 2px; + margin-bottom: 2px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.nav-pills > .active > a, +.nav-pills > .active > a:hover, +.nav-pills > .active > a:focus { + color: #ffffff; + background-color: #0088cc; +} + +.nav-stacked > li { + float: none; +} + +.nav-stacked > li > a { + margin-right: 0; +} + +.nav-tabs.nav-stacked { + border-bottom: 0; +} + +.nav-tabs.nav-stacked > li > a { + border: 1px solid #ddd; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.nav-tabs.nav-stacked > li:first-child > a { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-topleft: 4px; +} + +.nav-tabs.nav-stacked > li:last-child > a { + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -moz-border-radius-bottomright: 4px; + -moz-border-radius-bottomleft: 4px; +} + +.nav-tabs.nav-stacked > li > a:hover, +.nav-tabs.nav-stacked > li > a:focus { + z-index: 2; + border-color: #ddd; +} + +.nav-pills.nav-stacked > li > a { + margin-bottom: 3px; +} + +.nav-pills.nav-stacked > li:last-child > a { + margin-bottom: 1px; +} + +.nav-tabs .dropdown-menu { + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; +} + +.nav-pills .dropdown-menu { + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.nav .dropdown-toggle .caret { + margin-top: 6px; + border-top-color: #0088cc; + border-bottom-color: #0088cc; +} + +.nav .dropdown-toggle:hover .caret, +.nav .dropdown-toggle:focus .caret { + border-top-color: #005580; + border-bottom-color: #005580; +} + +/* move down carets for tabs */ + +.nav-tabs .dropdown-toggle .caret { + margin-top: 8px; +} + +.nav .active .dropdown-toggle .caret { + border-top-color: #fff; + border-bottom-color: #fff; +} + +.nav-tabs .active .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.nav > .dropdown.active > a:hover, +.nav > .dropdown.active > a:focus { + cursor: pointer; +} + +.nav-tabs .open .dropdown-toggle, +.nav-pills .open .dropdown-toggle, +.nav > li.dropdown.open.active > a:hover, +.nav > li.dropdown.open.active > a:focus { + color: #ffffff; + background-color: #999999; + border-color: #999999; +} + +.nav li.dropdown.open .caret, +.nav li.dropdown.open.active .caret, +.nav li.dropdown.open a:hover .caret, +.nav li.dropdown.open a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; + opacity: 1; + filter: alpha(opacity=100); +} + +.tabs-stacked .open > a:hover, +.tabs-stacked .open > a:focus { + border-color: #999999; +} + +.tabbable { + *zoom: 1; +} + +.tabbable:before, +.tabbable:after { + display: table; + line-height: 0; + content: ""; +} + +.tabbable:after { + clear: both; +} + +.tab-content { + overflow: auto; +} + +.tabs-below > .nav-tabs, +.tabs-right > .nav-tabs, +.tabs-left > .nav-tabs { + border-bottom: 0; +} + +.tab-content > .tab-pane, +.pill-content > .pill-pane { + display: none; +} + +.tab-content > .active, +.pill-content > .active { + display: block; +} + +.tabs-below > .nav-tabs { + border-top: 1px solid #ddd; +} + +.tabs-below > .nav-tabs > li { + margin-top: -1px; + margin-bottom: 0; +} + +.tabs-below > .nav-tabs > li > a { + -webkit-border-radius: 0 0 4px 4px; + -moz-border-radius: 0 0 4px 4px; + border-radius: 0 0 4px 4px; +} + +.tabs-below > .nav-tabs > li > a:hover, +.tabs-below > .nav-tabs > li > a:focus { + border-top-color: #ddd; + border-bottom-color: transparent; +} + +.tabs-below > .nav-tabs > .active > a, +.tabs-below > .nav-tabs > .active > a:hover, +.tabs-below > .nav-tabs > .active > a:focus { + border-color: transparent #ddd #ddd #ddd; +} + +.tabs-left > .nav-tabs > li, +.tabs-right > .nav-tabs > li { + float: none; +} + +.tabs-left > .nav-tabs > li > a, +.tabs-right > .nav-tabs > li > a { + min-width: 74px; + margin-right: 0; + margin-bottom: 3px; +} + +.tabs-left > .nav-tabs { + float: left; + margin-right: 19px; + border-right: 1px solid #ddd; +} + +.tabs-left > .nav-tabs > li > a { + margin-right: -1px; + -webkit-border-radius: 4px 0 0 4px; + -moz-border-radius: 4px 0 0 4px; + border-radius: 4px 0 0 4px; +} + +.tabs-left > .nav-tabs > li > a:hover, +.tabs-left > .nav-tabs > li > a:focus { + border-color: #eeeeee #dddddd #eeeeee #eeeeee; +} + +.tabs-left > .nav-tabs .active > a, +.tabs-left > .nav-tabs .active > a:hover, +.tabs-left > .nav-tabs .active > a:focus { + border-color: #ddd transparent #ddd #ddd; + *border-right-color: #ffffff; +} + +.tabs-right > .nav-tabs { + float: right; + margin-left: 19px; + border-left: 1px solid #ddd; +} + +.tabs-right > .nav-tabs > li > a { + margin-left: -1px; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; +} + +.tabs-right > .nav-tabs > li > a:hover, +.tabs-right > .nav-tabs > li > a:focus { + border-color: #eeeeee #eeeeee #eeeeee #dddddd; +} + +.tabs-right > .nav-tabs .active > a, +.tabs-right > .nav-tabs .active > a:hover, +.tabs-right > .nav-tabs .active > a:focus { + border-color: #ddd #ddd #ddd transparent; + *border-left-color: #ffffff; +} + +.nav > .disabled > a { + color: #999999; +} + +.nav > .disabled > a:hover, +.nav > .disabled > a:focus { + text-decoration: none; + cursor: default; + background-color: transparent; +} + +.navbar { + *position: relative; + *z-index: 2; + margin-bottom: 20px; + overflow: visible; +} + +.navbar-inner { + min-height: 40px; + padding-right: 20px; + padding-left: 20px; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + border: 1px solid #d4d4d4; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.navbar-inner:before, +.navbar-inner:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-inner:after { + clear: both; +} + +.navbar .container { + width: auto; +} + +.nav-collapse.collapse { + height: auto; + overflow: visible; +} + +.navbar .brand { + display: block; + float: left; + padding: 10px 20px 10px; + margin-left: -20px; + font-size: 20px; + font-weight: 200; + color: #777777; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .brand:hover, +.navbar .brand:focus { + text-decoration: none; +} + +.navbar-text { + margin-bottom: 0; + line-height: 40px; + color: #777777; +} + +.navbar-link { + color: #777777; +} + +.navbar-link:hover, +.navbar-link:focus { + color: #333333; +} + +.navbar .divider-vertical { + height: 40px; + margin: 0 9px; + border-right: 1px solid #ffffff; + border-left: 1px solid #f2f2f2; +} + +.navbar .btn, +.navbar .btn-group { + margin-top: 5px; +} + +.navbar .btn-group .btn, +.navbar .input-prepend .btn, +.navbar .input-append .btn, +.navbar .input-prepend .btn-group, +.navbar .input-append .btn-group { + margin-top: 0; +} + +.navbar-form { + margin-bottom: 0; + *zoom: 1; +} + +.navbar-form:before, +.navbar-form:after { + display: table; + line-height: 0; + content: ""; +} + +.navbar-form:after { + clear: both; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .radio, +.navbar-form .checkbox { + margin-top: 5px; +} + +.navbar-form input, +.navbar-form select, +.navbar-form .btn { + display: inline-block; + margin-bottom: 0; +} + +.navbar-form input[type="image"], +.navbar-form input[type="checkbox"], +.navbar-form input[type="radio"] { + margin-top: 3px; +} + +.navbar-form .input-append, +.navbar-form .input-prepend { + margin-top: 5px; + white-space: nowrap; +} + +.navbar-form .input-append input, +.navbar-form .input-prepend input { + margin-top: 0; +} + +.navbar-search { + position: relative; + float: left; + margin-top: 5px; + margin-bottom: 0; +} + +.navbar-search .search-query { + padding: 4px 14px; + margin-bottom: 0; + font-family: source-sans-pro, Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: normal; + line-height: 1; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.navbar-static-top { + position: static; + margin-bottom: 0; +} + +.navbar-static-top .navbar-inner { + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-fixed-top, +.navbar-fixed-bottom { + position: fixed; + right: 0; + left: 0; + z-index: 1030; + margin-bottom: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + border-width: 0 0 1px; +} + +.navbar-fixed-bottom .navbar-inner { + border-width: 1px 0 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-fixed-bottom .navbar-inner { + padding-right: 0; + padding-left: 0; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-static-top .container, +.navbar-fixed-top .container, +.navbar-fixed-bottom .container { + width: 940px; +} + +.navbar-fixed-top { + top: 0; +} + +.navbar-fixed-top .navbar-inner, +.navbar-static-top .navbar-inner { + -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar-fixed-bottom { + bottom: 0; +} + +.navbar-fixed-bottom .navbar-inner { + -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); + box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1); +} + +.navbar .nav { + position: relative; + left: 0; + display: block; + float: left; + margin: 0 10px 0 0; +} + +.navbar .nav.pull-right { + float: right; + margin-right: 0; +} + +.navbar .nav > li { + float: left; +} + +.navbar .nav > li > a { + float: none; + padding: 10px 15px 10px; + color: #777777; + text-decoration: none; + text-shadow: 0 1px 0 #ffffff; +} + +.navbar .nav .dropdown-toggle .caret { + margin-top: 8px; +} + +.navbar .nav > li > a:focus, +.navbar .nav > li > a:hover { + color: #333333; + text-decoration: none; + background-color: transparent; +} + +.navbar .nav > .active > a, +.navbar .nav > .active > a:hover, +.navbar .nav > .active > a:focus { + color: #555555; + text-decoration: none; + background-color: #e5e5e5; + -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); + box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125); +} + +.navbar .btn-navbar { + display: none; + float: right; + padding: 7px 10px; + margin-right: 5px; + margin-left: 5px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #ededed; + *background-color: #e5e5e5; + background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5)); + background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5); + background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5); + background-repeat: repeat-x; + border-color: #e5e5e5 #e5e5e5 #bfbfbf; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075); +} + +.navbar .btn-navbar:hover, +.navbar .btn-navbar:focus, +.navbar .btn-navbar:active, +.navbar .btn-navbar.active, +.navbar .btn-navbar.disabled, +.navbar .btn-navbar[disabled] { + color: #ffffff; + background-color: #e5e5e5; + *background-color: #d9d9d9; +} + +.navbar .btn-navbar:active, +.navbar .btn-navbar.active { + background-color: #cccccc \9; +} + +.navbar .btn-navbar .icon-bar { + display: block; + width: 18px; + height: 2px; + background-color: #f5f5f5; + -webkit-border-radius: 1px; + -moz-border-radius: 1px; + border-radius: 1px; + -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); + box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25); +} + +.btn-navbar .icon-bar + .icon-bar { + margin-top: 3px; +} + +.navbar .nav > li > .dropdown-menu:before { + position: absolute; + top: -7px; + left: 9px; + display: inline-block; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-left: 7px solid transparent; + border-bottom-color: rgba(0, 0, 0, 0.2); + content: ''; +} + +.navbar .nav > li > .dropdown-menu:after { + position: absolute; + top: -6px; + left: 10px; + display: inline-block; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + border-left: 6px solid transparent; + content: ''; +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:before { + top: auto; + bottom: -7px; + border-top: 7px solid #ccc; + border-bottom: 0; + border-top-color: rgba(0, 0, 0, 0.2); +} + +.navbar-fixed-bottom .nav > li > .dropdown-menu:after { + top: auto; + bottom: -6px; + border-top: 6px solid #ffffff; + border-bottom: 0; +} + +.navbar .nav li.dropdown > a:hover .caret, +.navbar .nav li.dropdown > a:focus .caret { + border-top-color: #333333; + border-bottom-color: #333333; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle, +.navbar .nav li.dropdown.active > .dropdown-toggle, +.navbar .nav li.dropdown.open.active > .dropdown-toggle { + color: #555555; + background-color: #e5e5e5; +} + +.navbar .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #777777; + border-bottom-color: #777777; +} + +.navbar .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #555555; + border-bottom-color: #555555; +} + +.navbar .pull-right > li > .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right { + right: 0; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:before, +.navbar .nav > li > .dropdown-menu.pull-right:before { + right: 12px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu:after, +.navbar .nav > li > .dropdown-menu.pull-right:after { + right: 13px; + left: auto; +} + +.navbar .pull-right > li > .dropdown-menu .dropdown-menu, +.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu { + right: 100%; + left: auto; + margin-right: -1px; + margin-left: 0; + -webkit-border-radius: 6px 0 6px 6px; + -moz-border-radius: 6px 0 6px 6px; + border-radius: 6px 0 6px 6px; +} + +.navbar-inverse .navbar-inner { + background-color: #1b1b1b; + background-image: -moz-linear-gradient(top, #222222, #111111); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111)); + background-image: -webkit-linear-gradient(top, #222222, #111111); + background-image: -o-linear-gradient(top, #222222, #111111); + background-image: linear-gradient(to bottom, #222222, #111111); + background-repeat: repeat-x; + border-color: #252525; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #999999; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #ffffff; +} + +.navbar-inverse .brand { + color: #999999; +} + +.navbar-inverse .navbar-text { + color: #999999; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #ffffff; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .navbar-link { + color: #999999; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #ffffff; +} + +.navbar-inverse .divider-vertical { + border-right-color: #222222; + border-left-color: #111111; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle { + color: #ffffff; + background-color: #111111; +} + +.navbar-inverse .nav li.dropdown > a:hover .caret, +.navbar-inverse .nav li.dropdown > a:focus .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret { + border-top-color: #999999; + border-bottom-color: #999999; +} + +.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret, +.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret { + border-top-color: #ffffff; + border-bottom-color: #ffffff; +} + +.navbar-inverse .navbar-search .search-query { + color: #ffffff; + background-color: #515151; + border-color: #111111; + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15); + -webkit-transition: none; + -moz-transition: none; + -o-transition: none; + transition: none; +} + +.navbar-inverse .navbar-search .search-query:-moz-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder { + color: #cccccc; +} + +.navbar-inverse .navbar-search .search-query:focus, +.navbar-inverse .navbar-search .search-query.focused { + padding: 5px 15px; + color: #333333; + text-shadow: 0 1px 0 #ffffff; + background-color: #ffffff; + border: 0; + outline: 0; + -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); + box-shadow: 0 0 3px rgba(0, 0, 0, 0.15); +} + +.navbar-inverse .btn-navbar { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e0e0e; + *background-color: #040404; + background-image: -moz-linear-gradient(top, #151515, #040404); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404)); + background-image: -webkit-linear-gradient(top, #151515, #040404); + background-image: -o-linear-gradient(top, #151515, #040404); + background-image: linear-gradient(to bottom, #151515, #040404); + background-repeat: repeat-x; + border-color: #040404 #040404 #000000; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.navbar-inverse .btn-navbar:hover, +.navbar-inverse .btn-navbar:focus, +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active, +.navbar-inverse .btn-navbar.disabled, +.navbar-inverse .btn-navbar[disabled] { + color: #ffffff; + background-color: #040404; + *background-color: #000000; +} + +.navbar-inverse .btn-navbar:active, +.navbar-inverse .btn-navbar.active { + background-color: #000000 \9; +} + +.breadcrumb { + padding: 8px 15px; + margin: 0 0 20px; + list-style: none; + background-color: #f5f5f5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.breadcrumb > li { + display: inline-block; + *display: inline; + text-shadow: 0 1px 0 #ffffff; + *zoom: 1; +} + +.breadcrumb > li > .divider { + padding: 0 5px; + color: #ccc; +} + +.breadcrumb > .active { + color: #999999; +} + +.pagination { + margin: 20px 0; +} + +.pagination ul { + display: inline-block; + *display: inline; + margin-bottom: 0; + margin-left: 0; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + *zoom: 1; + -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05); +} + +.pagination ul > li { + display: inline; +} + +.pagination ul > li > a, +.pagination ul > li > span { + float: left; + padding: 4px 12px; + line-height: 20px; + text-decoration: none; + background-color: #ffffff; + border: 1px solid #dddddd; + border-left-width: 0; +} + +.pagination ul > li > a:hover, +.pagination ul > li > a:focus, +.pagination ul > .active > a, +.pagination ul > .active > span { + background-color: #f5f5f5; +} + +.pagination ul > .active > a, +.pagination ul > .active > span { + color: #999999; + cursor: default; +} + +.pagination ul > .disabled > span, +.pagination ul > .disabled > a, +.pagination ul > .disabled > a:hover, +.pagination ul > .disabled > a:focus { + color: #999999; + cursor: default; + background-color: transparent; +} + +.pagination ul > li:first-child > a, +.pagination ul > li:first-child > span { + border-left-width: 1px; + -webkit-border-bottom-left-radius: 4px; + border-bottom-left-radius: 4px; + -webkit-border-top-left-radius: 4px; + border-top-left-radius: 4px; + -moz-border-radius-bottomleft: 4px; + -moz-border-radius-topleft: 4px; +} + +.pagination ul > li:last-child > a, +.pagination ul > li:last-child > span { + -webkit-border-top-right-radius: 4px; + border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; +} + +.pagination-centered { + text-align: center; +} + +.pagination-right { + text-align: right; +} + +.pagination-large ul > li > a, +.pagination-large ul > li > span { + padding: 11px 19px; + font-size: 17.5px; +} + +.pagination-large ul > li:first-child > a, +.pagination-large ul > li:first-child > span { + -webkit-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -webkit-border-top-left-radius: 6px; + border-top-left-radius: 6px; + -moz-border-radius-bottomleft: 6px; + -moz-border-radius-topleft: 6px; +} + +.pagination-large ul > li:last-child > a, +.pagination-large ul > li:last-child > span { + -webkit-border-top-right-radius: 6px; + border-top-right-radius: 6px; + -webkit-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + -moz-border-radius-topright: 6px; + -moz-border-radius-bottomright: 6px; +} + +.pagination-mini ul > li:first-child > a, +.pagination-small ul > li:first-child > a, +.pagination-mini ul > li:first-child > span, +.pagination-small ul > li:first-child > span { + -webkit-border-bottom-left-radius: 3px; + border-bottom-left-radius: 3px; + -webkit-border-top-left-radius: 3px; + border-top-left-radius: 3px; + -moz-border-radius-bottomleft: 3px; + -moz-border-radius-topleft: 3px; +} + +.pagination-mini ul > li:last-child > a, +.pagination-small ul > li:last-child > a, +.pagination-mini ul > li:last-child > span, +.pagination-small ul > li:last-child > span { + -webkit-border-top-right-radius: 3px; + border-top-right-radius: 3px; + -webkit-border-bottom-right-radius: 3px; + border-bottom-right-radius: 3px; + -moz-border-radius-topright: 3px; + -moz-border-radius-bottomright: 3px; +} + +.pagination-small ul > li > a, +.pagination-small ul > li > span { + padding: 2px 10px; + font-size: 11.9px; +} + +.pagination-mini ul > li > a, +.pagination-mini ul > li > span { + padding: 0 6px; + font-size: 10.5px; +} + +.pager { + margin: 20px 0; + text-align: center; + list-style: none; + *zoom: 1; +} + +.pager:before, +.pager:after { + display: table; + line-height: 0; + content: ""; +} + +.pager:after { + clear: both; +} + +.pager li { + display: inline; +} + +.pager li > a, +.pager li > span { + display: inline-block; + padding: 5px 14px; + background-color: #fff; + border: 1px solid #ddd; + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.pager li > a:hover, +.pager li > a:focus { + text-decoration: none; + background-color: #f5f5f5; +} + +.pager .next > a, +.pager .next > span { + float: right; +} + +.pager .previous > a, +.pager .previous > span { + float: left; +} + +.pager .disabled > a, +.pager .disabled > a:hover, +.pager .disabled > a:focus, +.pager .disabled > span { + color: #999999; + cursor: default; + background-color: #fff; +} + +.modal-backdrop { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1040; + background-color: #000000; +} + +.modal-backdrop.fade { + opacity: 0; +} + +.modal-backdrop, +.modal-backdrop.fade.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.modal { + position: fixed; + top: 10%; + left: 50%; + z-index: 1050; + width: 560px; + margin-left: -280px; + background-color: #ffffff; + border: 1px solid #999; + border: 1px solid rgba(0, 0, 0, 0.3); + *border: 1px solid #999; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + outline: none; + -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3); + -webkit-background-clip: padding-box; + -moz-background-clip: padding-box; + background-clip: padding-box; +} + +.modal.fade { + top: -25%; + -webkit-transition: opacity 0.3s linear, top 0.3s ease-out; + -moz-transition: opacity 0.3s linear, top 0.3s ease-out; + -o-transition: opacity 0.3s linear, top 0.3s ease-out; + transition: opacity 0.3s linear, top 0.3s ease-out; +} + +.modal.fade.in { + top: 10%; +} + +.modal-header { + padding: 9px 15px; + border-bottom: 1px solid #eee; +} + +.modal-header .close { + margin-top: 2px; +} + +.modal-header h3 { + margin: 0; + line-height: 30px; +} + +.modal-body { + position: relative; + max-height: 400px; + padding: 15px; + overflow-y: auto; +} + +.modal-form { + margin-bottom: 0; +} + +.modal-footer { + padding: 14px 15px 15px; + margin-bottom: 0; + text-align: right; + background-color: #f5f5f5; + border-top: 1px solid #ddd; + -webkit-border-radius: 0 0 6px 6px; + -moz-border-radius: 0 0 6px 6px; + border-radius: 0 0 6px 6px; + *zoom: 1; + -webkit-box-shadow: inset 0 1px 0 #ffffff; + -moz-box-shadow: inset 0 1px 0 #ffffff; + box-shadow: inset 0 1px 0 #ffffff; +} + +.modal-footer:before, +.modal-footer:after { + display: table; + line-height: 0; + content: ""; +} + +.modal-footer:after { + clear: both; +} + +.modal-footer .btn + .btn { + margin-bottom: 0; + margin-left: 5px; +} + +.modal-footer .btn-group .btn + .btn { + margin-left: -1px; +} + +.modal-footer .btn-block + .btn-block { + margin-left: 0; +} + +.tooltip { + position: absolute; + z-index: 1030; + display: block; + font-size: 11px; + line-height: 1.4; + opacity: 0; + filter: alpha(opacity=0); + visibility: visible; +} + +.tooltip.in { + opacity: 0.8; + filter: alpha(opacity=80); +} + +.tooltip.top { + padding: 5px 0; + margin-top: -3px; +} + +.tooltip.right { + padding: 0 5px; + margin-left: 3px; +} + +.tooltip.bottom { + padding: 5px 0; + margin-top: 3px; +} + +.tooltip.left { + padding: 0 5px; + margin-left: -3px; +} + +.tooltip-inner { + max-width: 200px; + padding: 8px; + color: #ffffff; + text-align: center; + text-decoration: none; + background-color: #000000; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.tooltip-arrow { + position: absolute; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.tooltip.top .tooltip-arrow { + bottom: 0; + left: 50%; + margin-left: -5px; + border-top-color: #000000; + border-width: 5px 5px 0; +} + +.tooltip.right .tooltip-arrow { + top: 50%; + left: 0; + margin-top: -5px; + border-right-color: #000000; + border-width: 5px 5px 5px 0; +} + +.tooltip.left .tooltip-arrow { + top: 50%; + right: 0; + margin-top: -5px; + border-left-color: #000000; + border-width: 5px 0 5px 5px; +} + +.tooltip.bottom .tooltip-arrow { + top: 0; + left: 50%; + margin-left: -5px; + border-bottom-color: #000000; + border-width: 0 5px 5px; +} + +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1010; + display: none; + max-width: 276px; + padding: 1px; + text-align: left; + white-space: normal; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.popover.top { + margin-top: -10px; +} + +.popover.right { + margin-left: 10px; +} + +.popover.bottom { + margin-top: 10px; +} + +.popover.left { + margin-left: -10px; +} + +.popover-title { + padding: 8px 14px; + margin: 0; + font-size: 14px; + font-weight: normal; + line-height: 18px; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + -webkit-border-radius: 5px 5px 0 0; + -moz-border-radius: 5px 5px 0 0; + border-radius: 5px 5px 0 0; +} + +.popover-title:empty { + display: none; +} + +.popover-content { + padding: 9px 14px; +} + +.popover .arrow, +.popover .arrow:after { + position: absolute; + display: block; + width: 0; + height: 0; + border-color: transparent; + border-style: solid; +} + +.popover .arrow { + border-width: 11px; +} + +.popover .arrow:after { + border-width: 10px; + content: ""; +} + +.popover.top .arrow { + bottom: -11px; + left: 50%; + margin-left: -11px; + border-top-color: #999; + border-top-color: rgba(0, 0, 0, 0.25); + border-bottom-width: 0; +} + +.popover.top .arrow:after { + bottom: 1px; + margin-left: -10px; + border-top-color: #ffffff; + border-bottom-width: 0; +} + +.popover.right .arrow { + top: 50%; + left: -11px; + margin-top: -11px; + border-right-color: #999; + border-right-color: rgba(0, 0, 0, 0.25); + border-left-width: 0; +} + +.popover.right .arrow:after { + bottom: -10px; + left: 1px; + border-right-color: #ffffff; + border-left-width: 0; +} + +.popover.bottom .arrow { + top: -11px; + left: 50%; + margin-left: -11px; + border-bottom-color: #999; + border-bottom-color: rgba(0, 0, 0, 0.25); + border-top-width: 0; +} + +.popover.bottom .arrow:after { + top: 1px; + margin-left: -10px; + border-bottom-color: #ffffff; + border-top-width: 0; +} + +.popover.left .arrow { + top: 50%; + right: -11px; + margin-top: -11px; + border-left-color: #999; + border-left-color: rgba(0, 0, 0, 0.25); + border-right-width: 0; +} + +.popover.left .arrow:after { + right: 1px; + bottom: -10px; + border-left-color: #ffffff; + border-right-width: 0; +} + +.thumbnails { + margin-left: -20px; + list-style: none; + *zoom: 1; +} + +.thumbnails:before, +.thumbnails:after { + display: table; + line-height: 0; + content: ""; +} + +.thumbnails:after { + clear: both; +} + +.row-fluid .thumbnails { + margin-left: 0; +} + +.thumbnails > li { + float: left; + margin-bottom: 20px; + margin-left: 20px; +} + +.thumbnail { + display: block; + padding: 4px; + line-height: 20px; + border: 1px solid #ddd; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055); + -webkit-transition: all 0.2s ease-in-out; + -moz-transition: all 0.2s ease-in-out; + -o-transition: all 0.2s ease-in-out; + transition: all 0.2s ease-in-out; +} + +a.thumbnail:hover, +a.thumbnail:focus { + border-color: #0088cc; + -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); + box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25); +} + +.thumbnail > img { + display: block; + max-width: 100%; + margin-right: auto; + margin-left: auto; +} + +.thumbnail .caption { + padding: 9px; + color: #555555; +} + +.media, +.media-body { + overflow: hidden; + *overflow: visible; + zoom: 1; +} + +.media, +.media .media { + margin-top: 15px; +} + +.media:first-child { + margin-top: 0; +} + +.media-object { + display: block; +} + +.media-heading { + margin: 0 0 5px; +} + +.media > .pull-left { + margin-right: 10px; +} + +.media > .pull-right { + margin-left: 10px; +} + +.media-list { + margin-left: 0; + list-style: none; +} + +.label, +.badge { + display: inline-block; + padding: 2px 4px; + font-size: 11.844px; + font-weight: bold; + line-height: 14px; + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + white-space: nowrap; + vertical-align: baseline; + background-color: #999999; +} + +.label { + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.badge { + padding-right: 9px; + padding-left: 9px; + -webkit-border-radius: 9px; + -moz-border-radius: 9px; + border-radius: 9px; +} + +.label:empty, +.badge:empty { + display: none; +} + +a.label:hover, +a.label:focus, +a.badge:hover, +a.badge:focus { + color: #ffffff; + text-decoration: none; + cursor: pointer; +} + +.label-important, +.badge-important { + background-color: #b94a48; +} + +.label-important[href], +.badge-important[href] { + background-color: #953b39; +} + +.label-warning, +.badge-warning { + background-color: #f89406; +} + +.label-warning[href], +.badge-warning[href] { + background-color: #c67605; +} + +.label-success, +.badge-success { + background-color: #468847; +} + +.label-success[href], +.badge-success[href] { + background-color: #356635; +} + +.label-info, +.badge-info { + background-color: #3a87ad; +} + +.label-info[href], +.badge-info[href] { + background-color: #2d6987; +} + +.label-inverse, +.badge-inverse { + background-color: #333333; +} + +.label-inverse[href], +.badge-inverse[href] { + background-color: #1a1a1a; +} + +.btn .label, +.btn .badge { + position: relative; + top: -1px; +} + +.btn-mini .label, +.btn-mini .badge { + top: 0; +} + +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-moz-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-ms-keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +@-o-keyframes progress-bar-stripes { + from { + background-position: 0 0; + } + to { + background-position: 40px 0; + } +} + +@keyframes progress-bar-stripes { + from { + background-position: 40px 0; + } + to { + background-position: 0 0; + } +} + +.progress { + height: 20px; + margin-bottom: 20px; + overflow: hidden; + background-color: #f7f7f7; + background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9)); + background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9); + background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9); + background-repeat: repeat-x; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0); + -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); + box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); +} + +.progress .bar { + float: left; + width: 0; + height: 100%; + font-size: 12px; + color: #ffffff; + text-align: center; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #0e90d2; + background-image: -moz-linear-gradient(top, #149bdf, #0480be); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be)); + background-image: -webkit-linear-gradient(top, #149bdf, #0480be); + background-image: -o-linear-gradient(top, #149bdf, #0480be); + background-image: linear-gradient(to bottom, #149bdf, #0480be); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0); + -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; + -webkit-transition: width 0.6s ease; + -moz-transition: width 0.6s ease; + -o-transition: width 0.6s ease; + transition: width 0.6s ease; +} + +.progress .bar + .bar { + -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15); +} + +.progress-striped .bar { + background-color: #149bdf; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + -webkit-background-size: 40px 40px; + -moz-background-size: 40px 40px; + -o-background-size: 40px 40px; + background-size: 40px 40px; +} + +.progress.active .bar { + -webkit-animation: progress-bar-stripes 2s linear infinite; + -moz-animation: progress-bar-stripes 2s linear infinite; + -ms-animation: progress-bar-stripes 2s linear infinite; + -o-animation: progress-bar-stripes 2s linear infinite; + animation: progress-bar-stripes 2s linear infinite; +} + +.progress-danger .bar, +.progress .bar-danger { + background-color: #dd514c; + background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35)); + background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35); + background-image: -o-linear-gradient(top, #ee5f5b, #c43c35); + background-image: linear-gradient(to bottom, #ee5f5b, #c43c35); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0); +} + +.progress-danger.progress-striped .bar, +.progress-striped .bar-danger { + background-color: #ee5f5b; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-success .bar, +.progress .bar-success { + background-color: #5eb95e; + background-image: -moz-linear-gradient(top, #62c462, #57a957); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957)); + background-image: -webkit-linear-gradient(top, #62c462, #57a957); + background-image: -o-linear-gradient(top, #62c462, #57a957); + background-image: linear-gradient(to bottom, #62c462, #57a957); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0); +} + +.progress-success.progress-striped .bar, +.progress-striped .bar-success { + background-color: #62c462; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-info .bar, +.progress .bar-info { + background-color: #4bb1cf; + background-image: -moz-linear-gradient(top, #5bc0de, #339bb9); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9)); + background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9); + background-image: -o-linear-gradient(top, #5bc0de, #339bb9); + background-image: linear-gradient(to bottom, #5bc0de, #339bb9); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0); +} + +.progress-info.progress-striped .bar, +.progress-striped .bar-info { + background-color: #5bc0de; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.progress-warning .bar, +.progress .bar-warning { + background-color: #faa732; + background-image: -moz-linear-gradient(top, #fbb450, #f89406); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406)); + background-image: -webkit-linear-gradient(top, #fbb450, #f89406); + background-image: -o-linear-gradient(top, #fbb450, #f89406); + background-image: linear-gradient(to bottom, #fbb450, #f89406); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0); +} + +.progress-warning.progress-striped .bar, +.progress-striped .bar-warning { + background-color: #fbb450; + background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent)); + background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); + background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); +} + +.accordion { + margin-bottom: 20px; +} + +.accordion-group { + margin-bottom: 2px; + border: 1px solid #e5e5e5; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} + +.accordion-heading { + border-bottom: 0; +} + +.accordion-heading .accordion-toggle { + display: block; + padding: 8px 15px; +} + +.accordion-toggle { + cursor: pointer; +} + +.accordion-inner { + padding: 9px 15px; + border-top: 1px solid #e5e5e5; +} + +.carousel { + position: relative; + margin-bottom: 20px; + line-height: 1; +} + +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} + +.carousel-inner > .item { + position: relative; + display: none; + -webkit-transition: 0.6s ease-in-out left; + -moz-transition: 0.6s ease-in-out left; + -o-transition: 0.6s ease-in-out left; + transition: 0.6s ease-in-out left; +} + +.carousel-inner > .item > img, +.carousel-inner > .item > a > img { + display: block; + line-height: 1; +} + +.carousel-inner > .active, +.carousel-inner > .next, +.carousel-inner > .prev { + display: block; +} + +.carousel-inner > .active { + left: 0; +} + +.carousel-inner > .next, +.carousel-inner > .prev { + position: absolute; + top: 0; + width: 100%; +} + +.carousel-inner > .next { + left: 100%; +} + +.carousel-inner > .prev { + left: -100%; +} + +.carousel-inner > .next.left, +.carousel-inner > .prev.right { + left: 0; +} + +.carousel-inner > .active.left { + left: -100%; +} + +.carousel-inner > .active.right { + left: 100%; +} + +.carousel-control { + position: absolute; + top: 40%; + left: 15px; + width: 40px; + height: 40px; + margin-top: -20px; + font-size: 60px; + font-weight: 100; + line-height: 30px; + color: #ffffff; + text-align: center; + background: #222222; + border: 3px solid #ffffff; + -webkit-border-radius: 23px; + -moz-border-radius: 23px; + border-radius: 23px; + opacity: 0.5; + filter: alpha(opacity=50); +} + +.carousel-control.right { + right: 15px; + left: auto; +} + +.carousel-control:hover, +.carousel-control:focus { + color: #ffffff; + text-decoration: none; + opacity: 0.9; + filter: alpha(opacity=90); +} + +.carousel-indicators { + position: absolute; + top: 15px; + right: 15px; + z-index: 5; + margin: 0; + list-style: none; +} + +.carousel-indicators li { + display: block; + float: left; + width: 10px; + height: 10px; + margin-left: 5px; + text-indent: -999px; + background-color: #ccc; + background-color: rgba(255, 255, 255, 0.25); + border-radius: 5px; +} + +.carousel-indicators .active { + background-color: #fff; +} + +.carousel-caption { + position: absolute; + right: 0; + bottom: 0; + left: 0; + padding: 15px; + background: #333333; + background: rgba(0, 0, 0, 0.75); +} + +.carousel-caption h4, +.carousel-caption p { + line-height: 20px; + color: #ffffff; +} + +.carousel-caption h4 { + margin: 0 0 5px; +} + +.carousel-caption p { + margin-bottom: 0; +} + +.hero-unit { + padding: 60px; + margin-bottom: 30px; + font-size: 18px; + font-weight: 200; + line-height: 30px; + color: inherit; + background-color: #eeeeee; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.hero-unit h1 { + margin-bottom: 0; + font-size: 60px; + line-height: 1; + letter-spacing: -1px; + color: inherit; +} + +.hero-unit li { + line-height: 30px; +} + +.pull-right { + float: right; +} + +.pull-left { + float: left; +} + +.hide { + display: none; +} + +.show { + display: block; +} + +.invisible { + visibility: hidden; +} + +.affix { + position: fixed; +} diff --git a/docs/UML/html/index.html/assets/css/jquery.bonsai.css b/docs/UML/html/index.html/assets/css/jquery.bonsai.css new file mode 100755 index 0000000..9cd9214 --- /dev/null +++ b/docs/UML/html/index.html/assets/css/jquery.bonsai.css @@ -0,0 +1,36 @@ +.bonsai, +.bonsai li { + margin: 0; + padding: 0; + list-style: none; + overflow: hidden; +} + +.bonsai li { + position: relative; + padding-left: 1.3em; /* padding for the thumb */ +} + +li .thumb { + margin: -1px 0 0 -1em; /* negative margin into the padding of the li */ + position: absolute; + cursor: pointer; +} + +li.has-children > .thumb:after { + content: '▸'; +} + +li.has-children.expanded > .thumb:after { + content: '▾'; +} + +li.collapsed > ol.bonsai { + height: 0; + overflow: hidden; +} + +.bonsai .all, +.bonsai .none { + cursor: pointer; +} diff --git a/docs/UML/html/index.html/assets/css/main.css b/docs/UML/html/index.html/assets/css/main.css new file mode 100755 index 0000000..8ad3ecb --- /dev/null +++ b/docs/UML/html/index.html/assets/css/main.css @@ -0,0 +1,812 @@ +/* bootstrap.css override +---------------------------------------------------------*/ + +body { + margin: 0; + font-family: source-sans-pro, Helvetica, Arial, sans-serif !imporant; + font-size: 14px; + font-weight: 400; + color: #555; + background-color: #F8F8F8; + -webkit-font-smoothing: antialiased; +} + +.module, .left-section { + overflow-y: auto; + height: calc(100vh - 95px); +} + +a { + color: #137cd4; +} + +a:focus { + outline: none; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 2px #6fb5f1; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 2px #6fb5f1; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 2px #6fb5f1; +} + +p { + margin-bottom: 20px; +} + +code, +pre { + padding: 20px; + font-family: source-code-pro, Monaco, Menlo, Consolas, "Courier New", monospace; + font-size: 12px; + color: #454545; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +p code, +p pre, +li code, +li pre { + border-radius: 2px; + padding: 0; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + margin: 10px 0 0; + font-weight: 300; + line-height: 20px; + color: #000; + text-rendering: optimizelegibility; +} + +h1 small, +h2 small, +h3 small, +h4 small, +h5 small, +h6 small { + color: #888; +} + +h1, +h2, +h3 { + line-height: 1.3em; +} + +h1 { + font-size: 40px; + font-weight: 400; + margin-top: 30px; +} + +h2 { + font-size: 30px; +} + +h3 { + font-size: 27px; +} + +h4 { + font-size: 17.5px; +} + +h5 { + font-size: 14px; +} + +h6 { + font-size: 11.9px; +} + +h1 small { + font-size: 24.5px; +} + +dl { + margin-bottom: 0; +} + +dt, +dd { + line-height: 20px; +} + +dt { + color: #000; + font-weight: 400; + margin-bottom: 5px; + -webkit-font-smoothing: subpixel-antialiased; /* this makes it slightly bolder */ +} + +dd { + display: inline-block; + margin-bottom: 20px; +} + +input, +button, +select, +textarea { + font-family: source-sans-pro, Helvetica, Arial, sans-serif; +} + +table p { + margin-bottom: 0px; +} + +.btn { + padding: 4px 12px; + margin-bottom: 0; + *margin-left: .3em; + font-size: 14px; + line-height: 20px; + color: #454545; + text-align: center; + text-shadow: none; + background-color: #e5e9e9; + *background-color: #e5e9e9; + background-image: none; + + border: 1px solid #cdcdcd; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn:hover, +.btn:focus, +.btn:active, +.btn.active, +.btn.disabled, +.btn[disabled] { + color: #454545; + background-color: #e5e9e9; + *background-color: #e5e9e9; +} + +.btn:active, +.btn.active { + background-color: #d3d7d7; +} + +.btn:first-child { + *margin-left: 0; +} + +.btn:hover, +.btn:focus { + color: #454545; + text-decoration: none; + background-position: 0 -15px; + -webkit-transition: background-position 0.1s linear; + -moz-transition: background-position 0.1s linear; + -o-transition: background-position 0.1s linear; + transition: background-position 0.1s linear; +} + +.btn:focus { + border: 1px solid #2893ef; + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: 0 0 0 1px #94ceff; + -moz-box-shadow: 0 0 0 1px #94ceff; + box-shadow: 0 0 0 1px #94ceff; +} + +.btn.active, +.btn:active { + background-image: none; + outline: 0; + -webkit-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.15); + -moz-box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.15); + box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.15); +} + +.btn.disabled, +.btn[disabled] { + cursor: default; + background-image: none; + opacity: 0.65; + filter: alpha(opacity=65); + -webkit-box-shadow: none; + -moz-box-shadow: none; + box-shadow: none; +} + +.btn-large { + padding: 11px 19px; + font-size: 17.5px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; +} + +.btn-large [class^="icon-"], +.btn-large [class*=" icon-"] { + margin-top: 4px; +} + +.btn-small { + padding: 2px 10px; + font-size: 11.9px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-small [class^="icon-"], +.btn-small [class*=" icon-"] { + margin-top: 0; +} + +.btn-mini [class^="icon-"], +.btn-mini [class*=" icon-"] { + margin-top: -1px; +} + +.btn-mini { + padding: 0 6px; + font-size: 10.5px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +.btn-block { + display: block; + width: 100%; + padding-right: 0; + padding-left: 0; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} + +.btn-block + .btn-block { + margin-top: 5px; +} + +input[type="submit"].btn-block, +input[type="reset"].btn-block, +input[type="button"].btn-block { + width: 100%; +} + +.btn-primary.active, +.btn-warning.active, +.btn-danger.active, +.btn-success.active, +.btn-info.active, +.btn-inverse.active { + color: rgba(255, 255, 255, 0.75); +} + +.btn-primary { + color: #ffffff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); + background-color: #006dcc; + *background-color: #0044cc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(to bottom, #0088cc, #0044cc); + background-repeat: repeat-x; + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); +} + +.btn-primary:hover, +.btn-primary:focus, +.btn-primary:active, +.btn-primary.active, +.btn-primary.disabled, +.btn-primary[disabled] { + color: #ffffff; + background-color: #0044cc; + *background-color: #003bb3; +} + +.btn-primary:active, +.btn-primary.active { + background-color: #003399 \9; +} + + +select, +textarea, +input[type="text"], +input[type="password"], +input[type="datetime"], +input[type="datetime-local"], +input[type="date"], +input[type="month"], +input[type="time"], +input[type="week"], +input[type="number"], +input[type="email"], +input[type="url"], +input[type="search"], +input[type="tel"], +input[type="color"], +.uneditable-input { + color: #454545; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} + +textarea:focus, +input[type="text"]:focus, +input[type="password"]:focus, +input[type="datetime"]:focus, +input[type="datetime-local"]:focus, +input[type="date"]:focus, +input[type="month"]:focus, +input[type="time"]:focus, +input[type="week"]:focus, +input[type="number"]:focus, +input[type="email"]:focus, +input[type="url"]:focus, +input[type="search"]:focus, +input[type="tel"]:focus, +input[type="color"]:focus, +.uneditable-input:focus { + border-color: #2893ef; + outline: 0; + outline: thin dotted \9; + /* IE6-9 */ + + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 1px #94ceff; + -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 1px #94ceff; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 0 1px #94ceff; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: #e0f0fa; + border-radius: 3px; + color: #137cd4; + text-decoration: none; +} + +.navbar .nav > li > a { + padding: 10px 15px 10px; + color: #000; + font-weight: 300; + text-shadow: none; +} + +.nav-list { + margin-left: 15px; +} + +.package-list.nav-list { + margin-left: 0; +} + +.nav-list > li > a, +.nav-list .nav-header { + text-shadow: none; +} + +.nav-header a, +.nav-header a:hover { + color: #000 !important; +} + +.navbar .brand { + font-weight: 500; + color: #000; + text-shadow: none; +} + +.navbar-inner { + min-height: 40px; + border: none; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} + +.navbar-inverse .navbar-inner { + background-image: none; + background: #fff; + border-bottom: 1px solid rgba(0, 0, 0, 0.12); + + -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06); + -moz-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06); + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.06); +} + +.navbar-inverse .brand, +.navbar-inverse .nav > li > a { + color: #000; + text-shadow: none; +} + +.navbar-inverse .brand:hover, +.navbar-inverse .nav > li > a:hover, +.navbar-inverse .brand:focus, +.navbar-inverse .nav > li > a:focus { + color: #000; +} + +.navbar-inverse .brand { + color: #000; + margin-left: -10px; +} + +.navbar-inverse .navbar-text { + color: #454545; +} + +.navbar-inverse .nav > li > a:focus, +.navbar-inverse .nav > li > a:hover { + color: #000; + background-color: transparent; +} + +.navbar-inverse .nav .active > a, +.navbar-inverse .nav .active > a:hover, +.navbar-inverse .nav .active > a:focus { + color: #000; + background-color: transparent; +} + +.navbar-inverse .navbar-link { + color: #000; +} + +.navbar-inverse .navbar-link:hover, +.navbar-inverse .navbar-link:focus { + color: #000; +} + +.nav-header { + padding: 3px 15px; + font-size: 11px; + font-weight: 400; + line-height: 20px; + color: #999999; + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); + text-transform: none; + letter-spacing: 1px; +} + +.page-header { + padding-bottom: 0; + margin: 10px 0 40px; + border-bottom: 1px solid #d7d7d7; +} + + +.page-header h1 { + background: #F8F8F8; + display: inline-block; + position: relative; + bottom: -19px; +} + +.alert { + padding: 4px 7px; +} + +.alert-info { + color: #000; + background-color: #e0f0fa; + border-color: #d9eaf4; + border-radius: 3px; + font-size: 12px; + text-shadow: none; +} + +.radio input[type="radio"], +.checkbox input[type="checkbox"] { + float: left; + margin-left: -15px; +} + +.label, +badge { + padding: 4px 7px; + font-weight: 400; + color: #ffffff; + text-shadow: none; +} + +.label-non-nullable, +.label-nullable, +.label-optional, +.label-info, +.badge-info { + background-color: #eee; + color: #222; + text-shadow: none; +} + +.well { + padding: 19px 19px 0; +} + +.table { + background-color: #fff; +} + +/* non-bootstrap css +---------------------------------------------------------*/ + +[class^="icon-"], [class*=" icon-"] { + background: none; +} +body{ + padding-left: 1.5em; + padding-right: 1.5em; +} + +.number-of-modules { + font-size: 14px; + font-weight: 400; + line-height: 1.5em; + margin: 10px 0 0 15px; +} + +#other-module{ + display: none; + overflow: scroll; +} +#toggle-other-modules i{ + font-size: 28px; +} +.nav-header{ +} + +#description { + font-size: 14px; + line-height: 22px; +} +section > h2, +section > h3{ + font-size: 30px; + line-height: 30px; + margin-bottom: 10px; + margin-top: 25px; + text-indent: 2px; +} +.properties > h3 { + font-size: 20px; + line-height: 20px; + margin-bottom: 15px; + margin-top: 30px; + text-indent: 2px; +} +.methods > h3 { + font-size: 20px; + line-height: 20px; + margin-bottom: 15px; + margin-top: 30px; + text-indent: 2px; +} +h3 .checkbox{ + display: inline-block; + font-weight: 300; + margin-left: 10px; + vertical-align: middle; + width: auto; +} +.element-list ul{ + margin: 0; + padding: 0; +} +.element-list ul li { + display: inline-block; + padding: 3px 8px; + margin-bottom: 10px; + margin-right: 5px; + font-size: 14px; + line-height: 20px; + color: #454545; + text-align: center; + background-color: #e0f0fa; + *background-color: #e0f0fa; + border: 1px solid #d9eaf4; + background-image: none; + + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +.element-list ul li a { + padding-top:0; + padding-bottom:0; +} +.element-list ul li a:hover { + background: transparent; +} +.member{ + background: #fff; + color: #454545; + margin-bottom: 20px; + overflow: hidden; /* clearfix */ + padding: 20px 17px; + border-radius: 4px; + border: 1px solid #dedede; + border-top: 1px solid #eee; +} +/*.member:last-of-type{*/ + /*margin-bottom: 0;*/ +/*}*/ +.member h4{ + border-bottom: 1px solid #e7e7e7; + font-weight: 400; + padding-bottom: 10px; + margin-top: -10px; + margin-bottom: 10px; +} +.member .code, +.member .code { + background: #f9f9f9; + border: 1px solid #eee; + border-top: 1px solid #e7e7e7; + display: none; + margin-top: 0; + margin-bottom: 0; +} + +.member .example { + display: block; + margin-bottom: 15px; + position: relative; +} + +.member .example:before { + color: #888; + content: 'Example'; + font-style: italic; + position: absolute; + right: 10px; + top: 10px; +} + +.member.private{ + display: none; + background: #fff; +} +.show-private .member.private{ + display: block; +} +.member .scope{ + color: #888; + font-style: italic; + padding-bottom: 10px; + margin-top: -10px; +} + +.member .anchor { + color: inherit; + visibility: hidden +} + +.member .anchor:hover { + text-decoration: none; +} + +.member .anchor:focus { + box-shadow: none; +} + +.member .anchor .icon-link { + line-height: 24px; +} + +.member:hover .anchor { + visibility: visible; +} + +.deprecated { + background: #EBEBEB; + background-image: repeating-linear-gradient(135deg, transparent, transparent 35px, rgba(255,255,255,.5) 35px, rgba(255,255,255,.5) 70px); +} + +.deprecated .label-deprecated { + margin-right: 10px; +} + +.deprecated .scope { + text-decoration: line-through; +} + +.show-code { + float: right; +} + +/* Typeahead styles (Bootstrap conflicts) */ + +.twitter-typeahead .tt-query, +.twitter-typeahead .tt-hint { + margin-bottom: 0; +} + +.tt-dropdown-menu { + min-width: 160px; + margin-top: 0; + padding: 5px 0; + background-color: #fff; + border: 1px solid #d7d7d7; + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + -webkit-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12); + -moz-box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12); + box-shadow: 0 1px 6px rgba(0, 0, 0, 0.12); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.tt-suggestion { + display: block; + font-family: source-sans-pro, Helvetica, Arial, sans-serif; + font-size: 14px; + padding: 3px 10px; +} + +.tt-suggestion.tt-is-under-cursor { + color: #000; + background-color: #e0f0fa; + background-image: none; +} + +.tt-suggestion.tt-is-under-cursor a { + color: #fff; +} + +.tt-suggestion p { + margin: 0; +} + +.navbar-fixed-top .container { + margin: 5px; + width: auto; +} + +span.twitter-typeahead { + float: right; + margin: 5px; +} + +input.typeahead, input.tt-hint { + margin: 0; +} + +input.tt-hint { + color: #999; +} + +dl .label { + margin-bottom: 7px; +} + +/* --------------- Appended ---------------- */ + +.node-icon { + width: 16px; + height: 16px; + display: inline-block; +} diff --git a/docs/UML/html/index.html/assets/icon-font/icons.css b/docs/UML/html/index.html/assets/icon-font/icons.css new file mode 100755 index 0000000..7350e86 --- /dev/null +++ b/docs/UML/html/index.html/assets/icon-font/icons.css @@ -0,0 +1,3117 @@ +/* Generated by grunt-webfont */ + + + +@font-face { + font-family:"icons"; + src:url("icons.eot?4e9eb228d42455658e5c5d119e628bf2"); + src:url("icons.eot?4e9eb228d42455658e5c5d119e628bf2#iefix") format("embedded-opentype"), + url("icons.woff?4e9eb228d42455658e5c5d119e628bf2") format("woff"), + url("icons.ttf?4e9eb228d42455658e5c5d119e628bf2") format("truetype"); + font-weight:normal; + font-style:normal; +} + +.staruml-icon { + + font-family:"icons"; + + display:inline-block; + line-height:1; + font-weight:normal; + font-style:normal; + speak:none; + text-decoration:inherit; + text-transform:none; + text-rendering:auto; + -webkit-font-smoothing:antialiased; + -moz-osx-font-smoothing:grayscale; +} + + +/* Icons */ + + +.icon-AWSArrow:before { + content:"\f101"; +} + + +.icon-AWSAvailabilityZone:before { + content:"\f102"; +} + + +.icon-AWSCallout:before { + content:"\f103"; +} + + +.icon-AWSDiagram:before { + content:"\f104"; +} + + +.icon-AWSGeneralResource:before { + content:"\f105"; +} + + +.icon-AWSGenericGroup:before { + content:"\f106"; +} + + +.icon-AWSGroup:before { + content:"\f107"; +} + + +.icon-AWSModel:before { + content:"\f108"; +} + + +.icon-AWSResource:before { + content:"\f109"; +} + + +.icon-AWSSecurityGroup:before { + content:"\f10a"; +} + + +.icon-AWSService:before { + content:"\f10b"; +} + + +.icon-AzureCallout:before { + content:"\f10c"; +} + + +.icon-AzureConnector:before { + content:"\f10d"; +} + + +.icon-AzureDiagram:before { + content:"\f10e"; +} + + +.icon-AzureGroup:before { + content:"\f10f"; +} + + +.icon-AzureModel:before { + content:"\f110"; +} + + +.icon-AzureService:before { + content:"\f111"; +} + + +.icon-BPMNAdHocSubProcess:before { + content:"\f112"; +} + + +.icon-BPMNAssociation:before { + content:"\f113"; +} + + +.icon-BPMNBoundaryEvent:before { + content:"\f114"; +} + + +.icon-BPMNBusinessRuleTask:before { + content:"\f115"; +} + + +.icon-BPMNCallActivity:before { + content:"\f116"; +} + + +.icon-BPMNCallConversation:before { + content:"\f117"; +} + + +.icon-BPMNCancelEventDefinition:before { + content:"\f118"; +} + + +.icon-BPMNChoreography:before { + content:"\f119"; +} + + +.icon-BPMNChoreographyTask:before { + content:"\f11a"; +} + + +.icon-BPMNCollaboration:before { + content:"\f11b"; +} + + +.icon-BPMNCompensateEventDefinition:before { + content:"\f11c"; +} + + +.icon-BPMNComplexGateway:before { + content:"\f11d"; +} + + +.icon-BPMNConditionalEventDefinition:before { + content:"\f11e"; +} + + +.icon-BPMNConversation:before { + content:"\f11f"; +} + + +.icon-BPMNConversationLink:before { + content:"\f120"; +} + + +.icon-BPMNDataAssociation:before { + content:"\f121"; +} + + +.icon-BPMNDataInput:before { + content:"\f122"; +} + + +.icon-BPMNDataObject:before { + content:"\f123"; +} + + +.icon-BPMNDataOutput:before { + content:"\f124"; +} + + +.icon-BPMNDataStore:before { + content:"\f125"; +} + + +.icon-BPMNDiagram:before { + content:"\f126"; +} + + +.icon-BPMNEndEvent:before { + content:"\f127"; +} + + +.icon-BPMNErrorEventDefinition:before { + content:"\f128"; +} + + +.icon-BPMNEscalationEventDefinition:before { + content:"\f129"; +} + + +.icon-BPMNEvent:before { + content:"\f12a"; +} + + +.icon-BPMNEventBasedGateway:before { + content:"\f12b"; +} + + +.icon-BPMNExclusiveGateway:before { + content:"\f12c"; +} + + +.icon-BPMNGateway:before { + content:"\f12d"; +} + + +.icon-BPMNGlobalConversation:before { + content:"\f12e"; +} + + +.icon-BPMNGroup:before { + content:"\f12f"; +} + + +.icon-BPMNInclusiveGateway:before { + content:"\f130"; +} + + +.icon-BPMNIntermediateCatchEvent:before { + content:"\f131"; +} + + +.icon-BPMNIntermediateEvent:before { + content:"\f132"; +} + + +.icon-BPMNIntermediateThrowEvent:before { + content:"\f133"; +} + + +.icon-BPMNLane:before { + content:"\f134"; +} + + +.icon-BPMNLaneVert:before { + content:"\f135"; +} + + +.icon-BPMNLinkEventDefinition:before { + content:"\f136"; +} + + +.icon-BPMNManualTask:before { + content:"\f137"; +} + + +.icon-BPMNMessage:before { + content:"\f138"; +} + + +.icon-BPMNMessageEventDefinition:before { + content:"\f139"; +} + + +.icon-BPMNMessageFlow:before { + content:"\f13a"; +} + + +.icon-BPMNMessageLink:before { + content:"\f13b"; +} + + +.icon-BPMNParallelGateway:before { + content:"\f13c"; +} + + +.icon-BPMNParticipant:before { + content:"\f13d"; +} + + +.icon-BPMNParticipantVert:before { + content:"\f13e"; +} + + +.icon-BPMNProcess:before { + content:"\f13f"; +} + + +.icon-BPMNReceiveTask:before { + content:"\f140"; +} + + +.icon-BPMNScriptTask:before { + content:"\f141"; +} + + +.icon-BPMNSendTask:before { + content:"\f142"; +} + + +.icon-BPMNSequenceFlow:before { + content:"\f143"; +} + + +.icon-BPMNServiceTask:before { + content:"\f144"; +} + + +.icon-BPMNSignalEventDefinition:before { + content:"\f145"; +} + + +.icon-BPMNStartEvent:before { + content:"\f146"; +} + + +.icon-BPMNSubChoreography:before { + content:"\f147"; +} + + +.icon-BPMNSubConversation:before { + content:"\f148"; +} + + +.icon-BPMNSubProcess:before { + content:"\f149"; +} + + +.icon-BPMNTask:before { + content:"\f14a"; +} + + +.icon-BPMNTerminateEventDefinition:before { + content:"\f14b"; +} + + +.icon-BPMNTextAnnotation:before { + content:"\f14c"; +} + + +.icon-BPMNTimerEventDefinition:before { + content:"\f14d"; +} + + +.icon-BPMNTransaction:before { + content:"\f14e"; +} + + +.icon-BPMNUserTask:before { + content:"\f14f"; +} + + +.icon-C4Component:before { + content:"\f150"; +} + + +.icon-C4Container:before { + content:"\f151"; +} + + +.icon-C4Diagram:before { + content:"\f152"; +} + + +.icon-C4Element:before { + content:"\f153"; +} + + +.icon-C4Model:before { + content:"\f154"; +} + + +.icon-C4Person:before { + content:"\f155"; +} + + +.icon-C4Relationship:before { + content:"\f156"; +} + + +.icon-C4SoftwareSystem:before { + content:"\f157"; +} + + +.icon-DFDDataFlow:before { + content:"\f158"; +} + + +.icon-DFDDataFlowModel:before { + content:"\f159"; +} + + +.icon-DFDDataStore:before { + content:"\f15a"; +} + + +.icon-DFDDiagram:before { + content:"\f15b"; +} + + +.icon-DFDExternalEntity:before { + content:"\f15c"; +} + + +.icon-DFDProcess:before { + content:"\f15d"; +} + + +.icon-Ellipse:before { + content:"\f15e"; +} + + +.icon-ERDColumn:before { + content:"\f15f"; +} + + +.icon-ERDDataModel:before { + content:"\f160"; +} + + +.icon-ERDDiagram:before { + content:"\f161"; +} + + +.icon-ERDEntity:before { + content:"\f162"; +} + + +.icon-ERDManyToMany:before { + content:"\f163"; +} + + +.icon-ERDOneToMany:before { + content:"\f164"; +} + + +.icon-ERDOneToOne:before { + content:"\f165"; +} + + +.icon-ERDRelationship:before { + content:"\f166"; +} + + +.icon-ERDRelationshipEnd:before { + content:"\f167"; +} + + +.icon-FCAlternateProcess:before { + content:"\f168"; +} + + +.icon-FCCard:before { + content:"\f169"; +} + + +.icon-FCCollate:before { + content:"\f16a"; +} + + +.icon-FCConnector:before { + content:"\f16b"; +} + + +.icon-FCData:before { + content:"\f16c"; +} + + +.icon-FCDatabase:before { + content:"\f16d"; +} + + +.icon-FCDecision:before { + content:"\f16e"; +} + + +.icon-FCDelay:before { + content:"\f16f"; +} + + +.icon-FCDirectAccessStorage:before { + content:"\f170"; +} + + +.icon-FCDisplay:before { + content:"\f171"; +} + + +.icon-FCDocument:before { + content:"\f172"; +} + + +.icon-FCExtract:before { + content:"\f173"; +} + + +.icon-FCFlow:before { + content:"\f174"; +} + + +.icon-FCFlowchart:before { + content:"\f175"; +} + + +.icon-FCFlowchartDiagram:before { + content:"\f176"; +} + + +.icon-FCInternalStorage:before { + content:"\f177"; +} + + +.icon-FCManualInput:before { + content:"\f178"; +} + + +.icon-FCManualOperation:before { + content:"\f179"; +} + + +.icon-FCMerge:before { + content:"\f17a"; +} + + +.icon-FCMultiDocument:before { + content:"\f17b"; +} + + +.icon-FCOffPageConnector:before { + content:"\f17c"; +} + + +.icon-FCOr:before { + content:"\f17d"; +} + + +.icon-FCPredefinedProcess:before { + content:"\f17e"; +} + + +.icon-FCPreparation:before { + content:"\f17f"; +} + + +.icon-FCProcess:before { + content:"\f180"; +} + + +.icon-FCPunchedTape:before { + content:"\f181"; +} + + +.icon-FCSort:before { + content:"\f182"; +} + + +.icon-FCStoredData:before { + content:"\f183"; +} + + +.icon-FCSummingJunction:before { + content:"\f184"; +} + + +.icon-FCTerminator:before { + content:"\f185"; +} + + +.icon-FreeLine:before { + content:"\f186"; +} + + +.icon-GCPDiagram:before { + content:"\f187"; +} + + +.icon-GCPModel:before { + content:"\f188"; +} + + +.icon-GCPPath:before { + content:"\f189"; +} + + +.icon-GCPProduct:before { + content:"\f18a"; +} + + +.icon-GCPService:before { + content:"\f18b"; +} + + +.icon-GCPUser:before { + content:"\f18c"; +} + + +.icon-GCPZone:before { + content:"\f18d"; +} + + +.icon-Hyperlink:before { + content:"\f18e"; +} + + +.icon-Image:before { + content:"\f18f"; +} + + +.icon-MMEdge:before { + content:"\f190"; +} + + +.icon-MMMindmap:before { + content:"\f191"; +} + + +.icon-MMMindmapDiagram:before { + content:"\f192"; +} + + +.icon-MMNode:before { + content:"\f193"; +} + + +.icon-Project:before { + content:"\f194"; +} + + +.icon-Rectangle:before { + content:"\f195"; +} + + +.icon-RoundedRectangle:before { + content:"\f196"; +} + + +.icon-SysMLBlock:before { + content:"\f197"; +} + + +.icon-SysMLBlockDefinitionDiagram:before { + content:"\f198"; +} + + +.icon-SysMLConnector:before { + content:"\f199"; +} + + +.icon-SysMLConstraintBlock:before { + content:"\f19a"; +} + + +.icon-SysMLConstraintParameter:before { + content:"\f19b"; +} + + +.icon-SysMLConstraintProperty:before { + content:"\f19c"; +} + + +.icon-SysMLFlowProperty:before { + content:"\f19d"; +} + + +.icon-SysMLInterfaceBlock:before { + content:"\f19e"; +} + + +.icon-SysMLInternalBlockDiagram:before { + content:"\f19f"; +} + + +.icon-SysMLItemFlow:before { + content:"\f1a0"; +} + + +.icon-SysMLParametricDiagram:before { + content:"\f1a1"; +} + + +.icon-SysMLPart:before { + content:"\f1a2"; +} + + +.icon-SysMLPort:before { + content:"\f1a3"; +} + + +.icon-SysMLProperty:before { + content:"\f1a4"; +} + + +.icon-SysMLReference:before { + content:"\f1a5"; +} + + +.icon-SysMLRequirement:before { + content:"\f1a6"; +} + + +.icon-SysMLRequirementDiagram:before { + content:"\f1a7"; +} + + +.icon-SysMLValue:before { + content:"\f1a8"; +} + + +.icon-SysMLValueType:before { + content:"\f1a9"; +} + + +.icon-Tag:before { + content:"\f1aa"; +} + + +.icon-tool-add-sub-requirement:before { + content:"\f1ab"; +} + + +.icon-tool-add:before { + content:"\f1ac"; +} + + +.icon-tool-aggregation:before { + content:"\f1ad"; +} + + +.icon-tool-align-bottom:before { + content:"\f1ae"; +} + + +.icon-tool-align-center:before { + content:"\f1af"; +} + + +.icon-tool-align-left:before { + content:"\f1b0"; +} + + +.icon-tool-align-middle:before { + content:"\f1b1"; +} + + +.icon-tool-align-right:before { + content:"\f1b2"; +} + + +.icon-tool-align-space-even-horz:before { + content:"\f1b3"; +} + + +.icon-tool-align-space-even-vert:before { + content:"\f1b4"; +} + + +.icon-tool-align-top:before { + content:"\f1b5"; +} + + +.icon-tool-associate:before { + content:"\f1b6"; +} + + +.icon-tool-associated-actor:before { + content:"\f1b7"; +} + + +.icon-tool-associated-usecase:before { + content:"\f1b8"; +} + + +.icon-tool-association:before { + content:"\f1b9"; +} + + +.icon-tool-asynch-call:before { + content:"\f1ba"; +} + + +.icon-tool-asynch-signal:before { + content:"\f1bb"; +} + + +.icon-tool-attribute:before { + content:"\f1bc"; +} + + +.icon-tool-auto-resize:before { + content:"\f1bd"; +} + + +.icon-tool-aws-icon:before { + content:"\f1be"; +} + + +.icon-tool-azure-dashed:before { + content:"\f1bf"; +} + + +.icon-tool-azure-icon:before { + content:"\f1c0"; +} + + +.icon-tool-azure-rect:before { + content:"\f1c1"; +} + + +.icon-tool-azure-rounded:before { + content:"\f1c2"; +} + + +.icon-tool-azure-solid:before { + content:"\f1c3"; +} + + +.icon-tool-bpmn-add-annotation:before { + content:"\f1c4"; +} + + +.icon-tool-bpmn-choreography-add-initiating-message:before { + content:"\f1c5"; +} + + +.icon-tool-bpmn-choreography-add-participant-lower:before { + content:"\f1c6"; +} + + +.icon-tool-bpmn-choreography-add-participant-upper:before { + content:"\f1c7"; +} + + +.icon-tool-bpmn-choreography-add-return-message:before { + content:"\f1c8"; +} + + +.icon-tool-bpmn-choreography-create-participant-lower:before { + content:"\f1c9"; +} + + +.icon-tool-bpmn-choreography-create-participant-upper:before { + content:"\f1ca"; +} + + +.icon-tool-bpmn-choreography-initiating-participant:before { + content:"\f1cb"; +} + + +.icon-tool-BPMNBoundaryEvent:before { + content:"\f1cc"; +} + + +.icon-tool-BPMNCancelEventDefinition:before { + content:"\f1cd"; +} + + +.icon-tool-BPMNCompensateEventDefinition:before { + content:"\f1ce"; +} + + +.icon-tool-BPMNConditionalEventDefinition:before { + content:"\f1cf"; +} + + +.icon-tool-BPMNErrorEventDefinition:before { + content:"\f1d0"; +} + + +.icon-tool-BPMNEscalationEventDefinition:before { + content:"\f1d1"; +} + + +.icon-tool-BPMNLane:before { + content:"\f1d2"; +} + + +.icon-tool-BPMNLinkEventDefinition:before { + content:"\f1d3"; +} + + +.icon-tool-BPMNMessageEventDefinition:before { + content:"\f1d4"; +} + + +.icon-tool-BPMNSignalEventDefinition:before { + content:"\f1d5"; +} + + +.icon-tool-BPMNTerminateEventDefinition:before { + content:"\f1d6"; +} + + +.icon-tool-BPMNTimerEventDefinition:before { + content:"\f1d7"; +} + + +.icon-tool-bring-to-front:before { + content:"\f1d8"; +} + + +.icon-tool-choice:before { + content:"\f1d9"; +} + + +.icon-tool-communicating-node:before { + content:"\f1da"; +} + + +.icon-tool-composite:before { + content:"\f1db"; +} + + +.icon-tool-composition:before { + content:"\f1dc"; +} + + +.icon-tool-connected-lifeline:before { + content:"\f1dd"; +} + + +.icon-tool-connected-part:before { + content:"\f1de"; +} + + +.icon-tool-connection-point-reference:before { + content:"\f1df"; +} + + +.icon-tool-constraint-parameter:before { + content:"\f1e0"; +} + + +.icon-tool-constraint-property:before { + content:"\f1e1"; +} + + +.icon-tool-constraint:before { + content:"\f1e2"; +} + + +.icon-tool-create-block:before { + content:"\f1e3"; +} + + +.icon-tool-create-constraint-block:before { + content:"\f1e4"; +} + + +.icon-tool-create-item-flow:before { + content:"\f1e5"; +} + + +.icon-tool-create-message-lifeline:before { + content:"\f1e6"; +} + + +.icon-tool-create-message:before { + content:"\f1e7"; +} + + +.icon-tool-create-operation:before { + content:"\f1e8"; +} + + +.icon-tool-create-signal:before { + content:"\f1e9"; +} + + +.icon-tool-create-state-condition:before { + content:"\f1ea"; +} + + +.icon-tool-create-type:before { + content:"\f1eb"; +} + + +.icon-tool-create-value-type:before { + content:"\f1ec"; +} + + +.icon-tool-curve:before { + content:"\f1ed"; +} + + +.icon-tool-decision:before { + content:"\f1ee"; +} + + +.icon-tool-delete-item-flow:before { + content:"\f1ef"; +} + + +.icon-tool-delete-message:before { + content:"\f1f0"; +} + + +.icon-tool-delete:before { + content:"\f1f1"; +} + + +.icon-tool-dependant-package:before { + content:"\f1f2"; +} + + +.icon-tool-depending-package:before { + content:"\f1f3"; +} + + +.icon-tool-deployed-artifact:before { + content:"\f1f4"; +} + + +.icon-tool-deployed-component:before { + content:"\f1f5"; +} + + +.icon-tool-do-activity:before { + content:"\f1f6"; +} + + +.icon-tool-edit:before { + content:"\f1f7"; +} + + +.icon-tool-effect:before { + content:"\f1f8"; +} + + +.icon-tool-end-order-backward:before { + content:"\f1f9"; +} + + +.icon-tool-end-order-forward:before { + content:"\f1fa"; +} + + +.icon-tool-end-order-hide:before { + content:"\f1fb"; +} + + +.icon-tool-entry-activity:before { + content:"\f1fc"; +} + + +.icon-tool-enumeration-literal:before { + content:"\f1fd"; +} + + +.icon-tool-erd-column-key:before { + content:"\f1fe"; +} + + +.icon-tool-erd-column-non-key:before { + content:"\f1ff"; +} + + +.icon-tool-erd-column:before { + content:"\f200"; +} + + +.icon-tool-erd-identifying:before { + content:"\f201"; +} + + +.icon-tool-erd-many-to-many:before { + content:"\f202"; +} + + +.icon-tool-erd-many:before { + content:"\f203"; +} + + +.icon-tool-erd-non-identifying:before { + content:"\f204"; +} + + +.icon-tool-erd-one-to-many:before { + content:"\f205"; +} + + +.icon-tool-erd-one-to-one:before { + content:"\f206"; +} + + +.icon-tool-erd-one:before { + content:"\f207"; +} + + +.icon-tool-erd-zero-many:before { + content:"\f208"; +} + + +.icon-tool-erd-zero-one:before { + content:"\f209"; +} + + +.icon-tool-event:before { + content:"\f20a"; +} + + +.icon-tool-exit-activity:before { + content:"\f20b"; +} + + +.icon-tool-extended-usecase:before { + content:"\f20c"; +} + + +.icon-tool-extension-point:before { + content:"\f20d"; +} + + +.icon-tool-fc-incoming-decision:before { + content:"\f20e"; +} + + +.icon-tool-fc-incoming-process:before { + content:"\f20f"; +} + + +.icon-tool-fc-outgoing-decision:before { + content:"\f210"; +} + + +.icon-tool-fc-outgoing-process:before { + content:"\f211"; +} + + +.icon-tool-fill-color:before { + content:"\f212"; +} + + +.icon-tool-final-node:before { + content:"\f213"; +} + + +.icon-tool-final-state:before { + content:"\f214"; +} + + +.icon-tool-flow-property:before { + content:"\f215"; +} + + +.icon-tool-font-color:before { + content:"\f216"; +} + + +.icon-tool-fork:before { + content:"\f217"; +} + + +.icon-tool-forward-message:before { + content:"\f218"; +} + + +.icon-tool-found-message:before { + content:"\f219"; +} + + +.icon-tool-gcp-icon-zone-account:before { + content:"\f21a"; +} + + +.icon-tool-gcp-icon-zone-external-data-sources:before { + content:"\f21b"; +} + + +.icon-tool-gcp-icon-zone-external-firstparty-infrastructure:before { + content:"\f21c"; +} + + +.icon-tool-gcp-icon-zone-external-saas-providers:before { + content:"\f21d"; +} + + +.icon-tool-gcp-icon-zone-external-thirdparty-infrastructure:before { + content:"\f21e"; +} + + +.icon-tool-gcp-icon-zone-firewall:before { + content:"\f21f"; +} + + +.icon-tool-gcp-icon-zone-infrastructure-system:before { + content:"\f220"; +} + + +.icon-tool-gcp-icon-zone-instance-group:before { + content:"\f221"; +} + + +.icon-tool-gcp-icon-zone-kubernetes-cluster:before { + content:"\f222"; +} + + +.icon-tool-gcp-icon-zone-logical-group:before { + content:"\f223"; +} + + +.icon-tool-gcp-icon-zone-on-premises:before { + content:"\f224"; +} + + +.icon-tool-gcp-icon-zone-optional:before { + content:"\f225"; +} + + +.icon-tool-gcp-icon-zone-pod:before { + content:"\f226"; +} + + +.icon-tool-gcp-icon-zone-project:before { + content:"\f227"; +} + + +.icon-tool-gcp-icon-zone-region:before { + content:"\f228"; +} + + +.icon-tool-gcp-icon-zone-replica-pool:before { + content:"\f229"; +} + + +.icon-tool-gcp-icon-zone-sub-network:before { + content:"\f22a"; +} + + +.icon-tool-gcp-icon-zone-system:before { + content:"\f22b"; +} + + +.icon-tool-gcp-icon-zone-user:before { + content:"\f22c"; +} + + +.icon-tool-gcp-icon-zone-zone:before { + content:"\f22d"; +} + + +.icon-tool-gcp-icon:before { + content:"\f22e"; +} + + +.icon-tool-head-end-style-flat:before { + content:"\f22f"; +} + + +.icon-tool-head-end-style-solid:before { + content:"\f230"; +} + + +.icon-tool-head-end-style-stick:before { + content:"\f231"; +} + + +.icon-tool-included-usecase:before { + content:"\f232"; +} + + +.icon-tool-incoming-control-flow:before { + content:"\f233"; +} + + +.icon-tool-incoming-external-entity:before { + content:"\f234"; +} + + +.icon-tool-incoming-object-flow:before { + content:"\f235"; +} + + +.icon-tool-incoming-process:before { + content:"\f236"; +} + + +.icon-tool-incoming-transition:before { + content:"\f237"; +} + + +.icon-tool-initial-node:before { + content:"\f238"; +} + + +.icon-tool-initial-state:before { + content:"\f239"; +} + + +.icon-tool-input-pin:before { + content:"\f23a"; +} + + +.icon-tool-interface:before { + content:"\f23b"; +} + + +.icon-tool-internal-transition:before { + content:"\f23c"; +} + + +.icon-tool-join:before { + content:"\f23d"; +} + + +.icon-tool-line-color:before { + content:"\f23e"; +} + + +.icon-tool-linemode-dashed:before { + content:"\f23f"; +} + + +.icon-tool-linemode-dotted:before { + content:"\f240"; +} + + +.icon-tool-linemode-solid:before { + content:"\f241"; +} + + +.icon-tool-linked-object:before { + content:"\f242"; +} + + +.icon-tool-lock:before { + content:"\f243"; +} + + +.icon-tool-lost-message:before { + content:"\f244"; +} + + +.icon-tool-merge:before { + content:"\f245"; +} + + +.icon-tool-message-from-gate:before { + content:"\f246"; +} + + +.icon-tool-message-lifeline:before { + content:"\f247"; +} + + +.icon-tool-message-to-gate:before { + content:"\f248"; +} + + +.icon-tool-MMAddNodeLeft:before { + content:"\f249"; +} + + +.icon-tool-MMAddNodeRight:before { + content:"\f24a"; +} + + +.icon-tool-movedown:before { + content:"\f24b"; +} + + +.icon-tool-moveup:before { + content:"\f24c"; +} + + +.icon-tool-navigable:before { + content:"\f24d"; +} + + +.icon-tool-not-navigable:before { + content:"\f24e"; +} + + +.icon-tool-note:before { + content:"\f24f"; +} + + +.icon-tool-oblique:before { + content:"\f250"; +} + + +.icon-tool-operand:before { + content:"\f251"; +} + + +.icon-tool-operation:before { + content:"\f252"; +} + + +.icon-tool-outgoing-control-flow:before { + content:"\f253"; +} + + +.icon-tool-outgoing-datastore:before { + content:"\f254"; +} + + +.icon-tool-outgoing-object-flow:before { + content:"\f255"; +} + + +.icon-tool-outgoing-process:before { + content:"\f256"; +} + + +.icon-tool-outgoing-transition:before { + content:"\f257"; +} + + +.icon-tool-output-pin:before { + content:"\f258"; +} + + +.icon-tool-package:before { + content:"\f259"; +} + + +.icon-tool-parameter-property:before { + content:"\f25a"; +} + + +.icon-tool-part-property:before { + content:"\f25b"; +} + + +.icon-tool-part:before { + content:"\f25c"; +} + + +.icon-tool-port:before { + content:"\f25d"; +} + + +.icon-tool-private:before { + content:"\f25e"; +} + + +.icon-tool-property:before { + content:"\f25f"; +} + + +.icon-tool-protected:before { + content:"\f260"; +} + + +.icon-tool-public:before { + content:"\f261"; +} + + +.icon-tool-realizing-class:before { + content:"\f262"; +} + + +.icon-tool-reception:before { + content:"\f263"; +} + + +.icon-tool-rectilinear:before { + content:"\f264"; +} + + +.icon-tool-reference-property:before { + content:"\f265"; +} + + +.icon-tool-region:before { + content:"\f266"; +} + + +.icon-tool-reply-message:before { + content:"\f267"; +} + + +.icon-tool-reply:before { + content:"\f268"; +} + + +.icon-tool-required-interface:before { + content:"\f269"; +} + + +.icon-tool-reverse-message:before { + content:"\f26a"; +} + + +.icon-tool-rounded-rectilinear:before { + content:"\f26b"; +} + + +.icon-tool-search:before { + content:"\f26c"; +} + + +.icon-tool-select-block:before { + content:"\f26d"; +} + + +.icon-tool-select-constraint-block:before { + content:"\f26e"; +} + + +.icon-tool-select-item-flow:before { + content:"\f26f"; +} + + +.icon-tool-select-operation:before { + content:"\f270"; +} + + +.icon-tool-select-owner-attribute:before { + content:"\f271"; +} + + +.icon-tool-select-signal:before { + content:"\f272"; +} + + +.icon-tool-select-type:before { + content:"\f273"; +} + + +.icon-tool-select-value-type:before { + content:"\f274"; +} + + +.icon-tool-select:before { + content:"\f275"; +} + + +.icon-tool-self-connector:before { + content:"\f276"; +} + + +.icon-tool-self-message:before { + content:"\f277"; +} + + +.icon-tool-send-to-back:before { + content:"\f278"; +} + + +.icon-tool-set-height-equal:before { + content:"\f279"; +} + + +.icon-tool-set-size-equal:before { + content:"\f27a"; +} + + +.icon-tool-set-width-equal:before { + content:"\f27b"; +} + + +.icon-tool-shared:before { + content:"\f27c"; +} + + +.icon-tool-show-namespace:before { + content:"\f27d"; +} + + +.icon-tool-show-property:before { + content:"\f27e"; +} + + +.icon-tool-show-shadow:before { + content:"\f27f"; +} + + +.icon-tool-show-type:before { + content:"\f280"; +} + + +.icon-tool-show-visibility:before { + content:"\f281"; +} + + +.icon-tool-slot:before { + content:"\f282"; +} + + +.icon-tool-stereotype:before { + content:"\f283"; +} + + +.icon-tool-subactor:before { + content:"\f284"; +} + + +.icon-tool-subclass:before { + content:"\f285"; +} + + +.icon-tool-subinterface:before { + content:"\f286"; +} + + +.icon-tool-subpackage:before { + content:"\f287"; +} + + +.icon-tool-substereotype:before { + content:"\f288"; +} + + +.icon-tool-superactor:before { + content:"\f289"; +} + + +.icon-tool-superclass:before { + content:"\f28a"; +} + + +.icon-tool-superinterface:before { + content:"\f28b"; +} + + +.icon-tool-superstereotype:before { + content:"\f28c"; +} + + +.icon-tool-suppress-attributes:before { + content:"\f28d"; +} + + +.icon-tool-suppress-columns:before { + content:"\f28e"; +} + + +.icon-tool-suppress-literals:before { + content:"\f28f"; +} + + +.icon-tool-suppress-operations:before { + content:"\f290"; +} + + +.icon-tool-suppress-receptions:before { + content:"\f291"; +} + + +.icon-tool-synch-call:before { + content:"\f292"; +} + + +.icon-tool-tail-end-style-flat:before { + content:"\f293"; +} + + +.icon-tool-tail-end-style-solid:before { + content:"\f294"; +} + + +.icon-tool-tail-end-style-stick:before { + content:"\f295"; +} + + +.icon-tool-template-parameter-substitution:before { + content:"\f296"; +} + + +.icon-tool-template-parameter:before { + content:"\f297"; +} + + +.icon-tool-text-align-bottom:before { + content:"\f298"; +} + + +.icon-tool-text-align-center:before { + content:"\f299"; +} + + +.icon-tool-text-align-left:before { + content:"\f29a"; +} + + +.icon-tool-text-align-middle:before { + content:"\f29b"; +} + + +.icon-tool-text-align-right:before { + content:"\f29c"; +} + + +.icon-tool-text-align-top:before { + content:"\f29d"; +} + + +.icon-tool-time-segment:before { + content:"\f29e"; +} + + +.icon-tool-unspecified:before { + content:"\f29f"; +} + + +.icon-tool-validation-error:before { + content:"\f2a0"; +} + + +.icon-tool-validation-ok:before { + content:"\f2a1"; +} + + +.icon-tool-value-property:before { + content:"\f2a2"; +} + + +.icon-tool-WFAddTab:before { + content:"\f2a3"; +} + + +.icon-tool-wordwrap:before { + content:"\f2a4"; +} + + +.icon-UMLAcceptSignal:before { + content:"\f2a5"; +} + + +.icon-UMLAcceptTimeEvent:before { + content:"\f2a6"; +} + + +.icon-UMLAction:before { + content:"\f2a7"; +} + + +.icon-UMLActivity:before { + content:"\f2a8"; +} + + +.icon-UMLActivityDiagram:before { + content:"\f2a9"; +} + + +.icon-UMLActivityEdgeConnector:before { + content:"\f2aa"; +} + + +.icon-UMLActivityFinalNode:before { + content:"\f2ab"; +} + + +.icon-UMLActivityInterrupt:before { + content:"\f2ac"; +} + + +.icon-UMLActivityParameterNode:before { + content:"\f2ad"; +} + + +.icon-UMLActor:before { + content:"\f2ae"; +} + + +.icon-UMLAggregation:before { + content:"\f2af"; +} + + +.icon-UMLArtifact:before { + content:"\f2b0"; +} + + +.icon-UMLArtifactInstance:before { + content:"\f2b1"; +} + + +.icon-UMLAssociation:before { + content:"\f2b2"; +} + + +.icon-UMLAssociationClassLink:before { + content:"\f2b3"; +} + + +.icon-UMLAssociationEnd:before { + content:"\f2b4"; +} + + +.icon-UMLAsyncMessage:before { + content:"\f2b5"; +} + + +.icon-UMLAsyncSignalMessage:before { + content:"\f2b6"; +} + + +.icon-UMLAttribute:before { + content:"\f2b7"; +} + + +.icon-UMLBoundary:before { + content:"\f2b8"; +} + + +.icon-UMLCentralBufferNode:before { + content:"\f2b9"; +} + + +.icon-UMLChoice:before { + content:"\f2ba"; +} + + +.icon-UMLClass:before { + content:"\f2bb"; +} + + +.icon-UMLClassDiagram:before { + content:"\f2bc"; +} + + +.icon-UMLCollaboration:before { + content:"\f2bd"; +} + + +.icon-UMLCollaborationUse:before { + content:"\f2be"; +} + + +.icon-UMLCombinedFragment:before { + content:"\f2bf"; +} + + +.icon-UMLCommunicationDiagram:before { + content:"\f2c0"; +} + + +.icon-UMLCommunicationPath:before { + content:"\f2c1"; +} + + +.icon-UMLComponent:before { + content:"\f2c2"; +} + + +.icon-UMLComponentDiagram:before { + content:"\f2c3"; +} + + +.icon-UMLComponentInstance:before { + content:"\f2c4"; +} + + +.icon-UMLComponentRealization:before { + content:"\f2c5"; +} + + +.icon-UMLCompositeState:before { + content:"\f2c6"; +} + + +.icon-UMLCompositeStructureDiagram:before { + content:"\f2c7"; +} + + +.icon-UMLComposition:before { + content:"\f2c8"; +} + + +.icon-UMLConnectionPointReference:before { + content:"\f2c9"; +} + + +.icon-UMLConnector:before { + content:"\f2ca"; +} + + +.icon-UMLConnectorEnd:before { + content:"\f2cb"; +} + + +.icon-UMLConstraint:before { + content:"\f2cc"; +} + + +.icon-UMLContainment:before { + content:"\f2cd"; +} + + +.icon-UMLContinuation:before { + content:"\f2ce"; +} + + +.icon-UMLControl:before { + content:"\f2cf"; +} + + +.icon-UMLControlFlow:before { + content:"\f2d0"; +} + + +.icon-UMLCreateMessage:before { + content:"\f2d1"; +} + + +.icon-UMLDataStoreNode:before { + content:"\f2d2"; +} + + +.icon-UMLDataType:before { + content:"\f2d3"; +} + + +.icon-UMLDecisionNode:before { + content:"\f2d4"; +} + + +.icon-UMLDeepHistory:before { + content:"\f2d5"; +} + + +.icon-UMLDeleteMessage:before { + content:"\f2d6"; +} + + +.icon-UMLDependency:before { + content:"\f2d7"; +} + + +.icon-UMLDeployment:before { + content:"\f2d8"; +} + + +.icon-UMLDeploymentDiagram:before { + content:"\f2d9"; +} + + +.icon-UMLDirectedAssociation:before { + content:"\f2da"; +} + + +.icon-UMLDirectedLink:before { + content:"\f2db"; +} + + +.icon-UMLDoActivity:before { + content:"\f2dc"; +} + + +.icon-UMLDurationConstraint:before { + content:"\f2dd"; +} + + +.icon-UMLEffect:before { + content:"\f2de"; +} + + +.icon-UMLEndpoint:before { + content:"\f2df"; +} + + +.icon-UMLEntity:before { + content:"\f2e0"; +} + + +.icon-UMLEntryActivity:before { + content:"\f2e1"; +} + + +.icon-UMLEntryPoint:before { + content:"\f2e2"; +} + + +.icon-UMLEnumeration:before { + content:"\f2e3"; +} + + +.icon-UMLEnumerationLiteral:before { + content:"\f2e4"; +} + + +.icon-UMLEvent:before { + content:"\f2e5"; +} + + +.icon-UMLExceptionHandler:before { + content:"\f2e6"; +} + + +.icon-UMLExitActivity:before { + content:"\f2e7"; +} + + +.icon-UMLExitPoint:before { + content:"\f2e8"; +} + + +.icon-UMLExpansionNode:before { + content:"\f2e9"; +} + + +.icon-UMLExpansionRegion:before { + content:"\f2ea"; +} + + +.icon-UMLExtend:before { + content:"\f2eb"; +} + + +.icon-UMLExtension:before { + content:"\f2ec"; +} + + +.icon-UMLExtensionPoint:before { + content:"\f2ed"; +} + + +.icon-UMLFinalState:before { + content:"\f2ee"; +} + + +.icon-UMLFlowFinalNode:before { + content:"\f2ef"; +} + + +.icon-UMLFork:before { + content:"\f2f0"; +} + + +.icon-UMLForkNode:before { + content:"\f2f1"; +} + + +.icon-UMLForwardMessage:before { + content:"\f2f2"; +} + + +.icon-UMLFoundMessage:before { + content:"\f2f3"; +} + + +.icon-UMLFrame:before { + content:"\f2f4"; +} + + +.icon-UMLGate:before { + content:"\f2f5"; +} + + +.icon-UMLGeneralization:before { + content:"\f2f6"; +} + + +.icon-UMLImage:before { + content:"\f2f7"; +} + + +.icon-UMLInclude:before { + content:"\f2f8"; +} + + +.icon-UMLInformationFlow:before { + content:"\f2f9"; +} + + +.icon-UMLInformationFlowDiagram:before { + content:"\f2fa"; +} + + +.icon-UMLInformationItem:before { + content:"\f2fb"; +} + + +.icon-UMLInitialNode:before { + content:"\f2fc"; +} + + +.icon-UMLInitialState:before { + content:"\f2fd"; +} + + +.icon-UMLInputExpansionNode:before { + content:"\f2fe"; +} + + +.icon-UMLInputPin:before { + content:"\f2ff"; +} + + +.icon-UMLInteraction:before { + content:"\f300"; +} + + +.icon-UMLInteractionOperand:before { + content:"\f301"; +} + + +.icon-UMLInteractionOverviewDiagram:before { + content:"\f302"; +} + + +.icon-UMLInteractionUse:before { + content:"\f303"; +} + + +.icon-UMLInterface:before { + content:"\f304"; +} + + +.icon-UMLInterfaceRealization:before { + content:"\f305"; +} + + +.icon-UMLInterruptibleActivityRegion:before { + content:"\f306"; +} + + +.icon-UMLJoin:before { + content:"\f307"; +} + + +.icon-UMLJoinNode:before { + content:"\f308"; +} + + +.icon-UMLJunction:before { + content:"\f309"; +} + + +.icon-UMLLifeline:before { + content:"\f30a"; +} + + +.icon-UMLLink:before { + content:"\f30b"; +} + + +.icon-UMLLinkEnd:before { + content:"\f30c"; +} + + +.icon-UMLLinkObjectLink:before { + content:"\f30d"; +} + + +.icon-UMLLostMessage:before { + content:"\f30e"; +} + + +.icon-UMLMergeNode:before { + content:"\f30f"; +} + + +.icon-UMLMessage:before { + content:"\f310"; +} + + +.icon-UMLMetaClass:before { + content:"\f311"; +} + + +.icon-UMLModel:before { + content:"\f312"; +} + + +.icon-UMLNaryAssociationNode:before { + content:"\f313"; +} + + +.icon-UMLNode:before { + content:"\f314"; +} + + +.icon-UMLNodeInstance:before { + content:"\f315"; +} + + +.icon-UMLNote:before { + content:"\f316"; +} + + +.icon-UMLNoteLink:before { + content:"\f317"; +} + + +.icon-UMLObject:before { + content:"\f318"; +} + + +.icon-UMLObjectDiagram:before { + content:"\f319"; +} + + +.icon-UMLObjectFlow:before { + content:"\f31a"; +} + + +.icon-UMLObjectNode:before { + content:"\f31b"; +} + + +.icon-UMLOpaqueBehavior:before { + content:"\f31c"; +} + + +.icon-UMLOperation:before { + content:"\f31d"; +} + + +.icon-UMLOrthogonalState:before { + content:"\f31e"; +} + + +.icon-UMLOutputExpansionNode:before { + content:"\f31f"; +} + + +.icon-UMLOutputPin:before { + content:"\f320"; +} + + +.icon-UMLPackage:before { + content:"\f321"; +} + + +.icon-UMLPackageDiagram:before { + content:"\f322"; +} + + +.icon-UMLParameter:before { + content:"\f323"; +} + + +.icon-UMLPart:before { + content:"\f324"; +} + + +.icon-UMLPort:before { + content:"\f325"; +} + + +.icon-UMLPrimitiveType:before { + content:"\f326"; +} + + +.icon-UMLProfile:before { + content:"\f327"; +} + + +.icon-UMLProfileDiagram:before { + content:"\f328"; +} + + +.icon-UMLRealization:before { + content:"\f329"; +} + + +.icon-UMLReception:before { + content:"\f32a"; +} + + +.icon-UMLRegion:before { + content:"\f32b"; +} + + +.icon-UMLReplyMessage:before { + content:"\f32c"; +} + + +.icon-UMLReverseMessage:before { + content:"\f32d"; +} + + +.icon-UMLRoleBinding:before { + content:"\f32e"; +} + + +.icon-UMLSelfConnector:before { + content:"\f32f"; +} + + +.icon-UMLSelfLink:before { + content:"\f330"; +} + + +.icon-UMLSelfMessage:before { + content:"\f331"; +} + + +.icon-UMLSelfTransition:before { + content:"\f332"; +} + + +.icon-UMLSendSignal:before { + content:"\f333"; +} + + +.icon-UMLSequenceDiagram:before { + content:"\f334"; +} + + +.icon-UMLShallowHistory:before { + content:"\f335"; +} + + +.icon-UMLSignal:before { + content:"\f336"; +} + + +.icon-UMLSlot:before { + content:"\f337"; +} + + +.icon-UMLStandardProfile-boundary:before { + content:"\f338"; +} + + +.icon-UMLStandardProfile-control:before { + content:"\f339"; +} + + +.icon-UMLStandardProfile-entity:before { + content:"\f33a"; +} + + +.icon-UMLState:before { + content:"\f33b"; +} + + +.icon-UMLStatechartDiagram:before { + content:"\f33c"; +} + + +.icon-UMLStateCondition:before { + content:"\f33d"; +} + + +.icon-UMLStateInvariant:before { + content:"\f33e"; +} + + +.icon-UMLStateMachine:before { + content:"\f33f"; +} + + +.icon-UMLStereotype:before { + content:"\f340"; +} + + +.icon-UMLStructuredActivityNode:before { + content:"\f341"; +} + + +.icon-UMLSubmachineState:before { + content:"\f342"; +} + + +.icon-UMLSubsystem:before { + content:"\f343"; +} + + +.icon-UMLSwimlaneHorz:before { + content:"\f344"; +} + + +.icon-UMLSwimlaneVert:before { + content:"\f345"; +} + + +.icon-UMLTemplateBinding:before { + content:"\f346"; +} + + +.icon-UMLTemplateParameter:before { + content:"\f347"; +} + + +.icon-UMLTemplateParameterSubstitution:before { + content:"\f348"; +} + + +.icon-UMLTerminate:before { + content:"\f349"; +} + + +.icon-UMLText:before { + content:"\f34a"; +} + + +.icon-UMLTextBox:before { + content:"\f34b"; +} + + +.icon-UMLTimeConstraint:before { + content:"\f34c"; +} + + +.icon-UMLTimeSegment:before { + content:"\f34d"; +} + + +.icon-UMLTimeTick:before { + content:"\f34e"; +} + + +.icon-UMLTimingDiagram:before { + content:"\f34f"; +} + + +.icon-UMLTimingLifeline:before { + content:"\f350"; +} + + +.icon-UMLTransition:before { + content:"\f351"; +} + + +.icon-UMLUseCase:before { + content:"\f352"; +} + + +.icon-UMLUseCaseDiagram:before { + content:"\f353"; +} + + +.icon-UMLUseCaseSubject:before { + content:"\f354"; +} + + +.icon-WFAvatar:before { + content:"\f355"; +} + + +.icon-WFButton:before { + content:"\f356"; +} + + +.icon-WFCheckbox:before { + content:"\f357"; +} + + +.icon-WFDesktopFrame:before { + content:"\f358"; +} + + +.icon-WFDropdown:before { + content:"\f359"; +} + + +.icon-WFFrame:before { + content:"\f35a"; +} + + +.icon-WFImage:before { + content:"\f35b"; +} + + +.icon-WFInput:before { + content:"\f35c"; +} + + +.icon-WFLink:before { + content:"\f35d"; +} + + +.icon-WFMobileFrame:before { + content:"\f35e"; +} + + +.icon-WFPanel:before { + content:"\f35f"; +} + + +.icon-WFRadio:before { + content:"\f360"; +} + + +.icon-WFSeparator:before { + content:"\f361"; +} + + +.icon-WFSlider:before { + content:"\f362"; +} + + +.icon-WFSwitch:before { + content:"\f363"; +} + + +.icon-WFTab:before { + content:"\f364"; +} + + +.icon-WFTabList:before { + content:"\f365"; +} + + +.icon-WFText:before { + content:"\f366"; +} + + +.icon-WFWebFrame:before { + content:"\f367"; +} + + +.icon-WFWireframe:before { + content:"\f368"; +} + + +.icon-WFWireframeDiagram:before { + content:"\f369"; +} diff --git a/docs/UML/html/index.html/assets/icon-font/icons.eot b/docs/UML/html/index.html/assets/icon-font/icons.eot new file mode 100755 index 0000000..a0b84d1 Binary files /dev/null and b/docs/UML/html/index.html/assets/icon-font/icons.eot differ diff --git a/docs/UML/html/index.html/assets/icon-font/icons.html b/docs/UML/html/index.html/assets/icon-font/icons.html new file mode 100755 index 0000000..e095e29 --- /dev/null +++ b/docs/UML/html/index.html/assets/icon-font/icons.html @@ -0,0 +1,4438 @@ + + + + + icons + + + +

icons

+ +
+ +
icon-AWSArrow
+ +
icon-AWSAvailabilityZone
+ +
icon-AWSCallout
+ +
icon-AWSDiagram
+ +
icon-AWSGeneralResource
+ +
icon-AWSGenericGroup
+ +
icon-AWSGroup
+ +
icon-AWSModel
+ +
icon-AWSResource
+ +
icon-AWSSecurityGroup
+ +
icon-AWSService
+ +
icon-AzureCallout
+ +
icon-AzureConnector
+ +
icon-AzureDiagram
+ +
icon-AzureGroup
+ +
icon-AzureModel
+ +
icon-AzureService
+ +
icon-BPMNAdHocSubProcess
+ +
icon-BPMNAssociation
+ +
icon-BPMNBoundaryEvent
+ +
icon-BPMNBusinessRuleTask
+ +
icon-BPMNCallActivity
+ +
icon-BPMNCallConversation
+ +
icon-BPMNCancelEventDefinition
+ +
icon-BPMNChoreography
+ +
icon-BPMNChoreographyTask
+ +
icon-BPMNCollaboration
+ +
icon-BPMNCompensateEventDefinition
+ +
icon-BPMNComplexGateway
+ +
icon-BPMNConditionalEventDefinition
+ +
icon-BPMNConversation
+ +
icon-BPMNConversationLink
+ +
icon-BPMNDataAssociation
+ +
icon-BPMNDataInput
+ +
icon-BPMNDataObject
+ +
icon-BPMNDataOutput
+ +
icon-BPMNDataStore
+ +
icon-BPMNDiagram
+ +
icon-BPMNEndEvent
+ +
icon-BPMNErrorEventDefinition
+ +
icon-BPMNEscalationEventDefinition
+ +
icon-BPMNEvent
+ +
icon-BPMNEventBasedGateway
+ +
icon-BPMNExclusiveGateway
+ +
icon-BPMNGateway
+ +
icon-BPMNGlobalConversation
+ +
icon-BPMNGroup
+ +
icon-BPMNInclusiveGateway
+ +
icon-BPMNIntermediateCatchEvent
+ +
icon-BPMNIntermediateEvent
+ +
icon-BPMNIntermediateThrowEvent
+ +
icon-BPMNLane
+ +
icon-BPMNLaneVert
+ +
icon-BPMNLinkEventDefinition
+ +
icon-BPMNManualTask
+ +
icon-BPMNMessage
+ +
icon-BPMNMessageEventDefinition
+ +
icon-BPMNMessageFlow
+ +
icon-BPMNMessageLink
+ +
icon-BPMNParallelGateway
+ +
icon-BPMNParticipant
+ +
icon-BPMNParticipantVert
+ +
icon-BPMNProcess
+ +
icon-BPMNReceiveTask
+ +
icon-BPMNScriptTask
+ +
icon-BPMNSendTask
+ +
icon-BPMNSequenceFlow
+ +
icon-BPMNServiceTask
+ +
icon-BPMNSignalEventDefinition
+ +
icon-BPMNStartEvent
+ +
icon-BPMNSubChoreography
+ +
icon-BPMNSubConversation
+ +
icon-BPMNSubProcess
+ +
icon-BPMNTask
+ +
icon-BPMNTerminateEventDefinition
+ +
icon-BPMNTextAnnotation
+ +
icon-BPMNTimerEventDefinition
+ +
icon-BPMNTransaction
+ +
icon-BPMNUserTask
+ +
icon-C4Component
+ +
icon-C4Container
+ +
icon-C4Diagram
+ +
icon-C4Element
+ +
icon-C4Model
+ +
icon-C4Person
+ +
icon-C4Relationship
+ +
icon-C4SoftwareSystem
+ +
icon-DFDDataFlow
+ +
icon-DFDDataFlowModel
+ +
icon-DFDDataStore
+ +
icon-DFDDiagram
+ +
icon-DFDExternalEntity
+ +
icon-DFDProcess
+ +
icon-Ellipse
+ +
icon-ERDColumn
+ +
icon-ERDDataModel
+ +
icon-ERDDiagram
+ +
icon-ERDEntity
+ +
icon-ERDManyToMany
+ +
icon-ERDOneToMany
+ +
icon-ERDOneToOne
+ +
icon-ERDRelationship
+ +
icon-ERDRelationshipEnd
+ +
icon-FCAlternateProcess
+ +
icon-FCCard
+ +
icon-FCCollate
+ +
icon-FCConnector
+ +
icon-FCData
+ +
icon-FCDatabase
+ +
icon-FCDecision
+ +
icon-FCDelay
+ +
icon-FCDirectAccessStorage
+ +
icon-FCDisplay
+ +
icon-FCDocument
+ +
icon-FCExtract
+ +
icon-FCFlow
+ +
icon-FCFlowchart
+ +
icon-FCFlowchartDiagram
+ +
icon-FCInternalStorage
+ +
icon-FCManualInput
+ +
icon-FCManualOperation
+ +
icon-FCMerge
+ +
icon-FCMultiDocument
+ +
icon-FCOffPageConnector
+ +
icon-FCOr
+ +
icon-FCPredefinedProcess
+ +
icon-FCPreparation
+ +
icon-FCProcess
+ +
icon-FCPunchedTape
+ +
icon-FCSort
+ +
icon-FCStoredData
+ +
icon-FCSummingJunction
+ +
icon-FCTerminator
+ +
icon-FreeLine
+ +
icon-GCPDiagram
+ +
icon-GCPModel
+ +
icon-GCPPath
+ +
icon-GCPProduct
+ +
icon-GCPService
+ +
icon-GCPUser
+ +
icon-GCPZone
+ +
icon-Hyperlink
+ +
icon-Image
+ +
icon-MMEdge
+ +
icon-MMMindmap
+ +
icon-MMMindmapDiagram
+ +
icon-MMNode
+ +
icon-Project
+ +
icon-Rectangle
+ +
icon-RoundedRectangle
+ +
icon-SysMLBlock
+ +
icon-SysMLBlockDefinitionDiagram
+ +
icon-SysMLConnector
+ +
icon-SysMLConstraintBlock
+ +
icon-SysMLConstraintParameter
+ +
icon-SysMLConstraintProperty
+ +
icon-SysMLFlowProperty
+ +
icon-SysMLInterfaceBlock
+ +
icon-SysMLInternalBlockDiagram
+ +
icon-SysMLItemFlow
+ +
icon-SysMLParametricDiagram
+ +
icon-SysMLPart
+ +
icon-SysMLPort
+ +
icon-SysMLProperty
+ +
icon-SysMLReference
+ +
icon-SysMLRequirement
+ +
icon-SysMLRequirementDiagram
+ +
icon-SysMLValue
+ +
icon-SysMLValueType
+ +
icon-Tag
+ +
icon-tool-add-sub-requirement
+ +
icon-tool-add
+ +
icon-tool-aggregation
+ +
icon-tool-align-bottom
+ +
icon-tool-align-center
+ +
icon-tool-align-left
+ +
icon-tool-align-middle
+ +
icon-tool-align-right
+ +
icon-tool-align-space-even-horz
+ +
icon-tool-align-space-even-vert
+ +
icon-tool-align-top
+ +
icon-tool-associate
+ +
icon-tool-associated-actor
+ +
icon-tool-associated-usecase
+ +
icon-tool-association
+ +
icon-tool-asynch-call
+ +
icon-tool-asynch-signal
+ +
icon-tool-attribute
+ +
icon-tool-auto-resize
+ +
icon-tool-aws-icon
+ +
icon-tool-azure-dashed
+ +
icon-tool-azure-icon
+ +
icon-tool-azure-rect
+ +
icon-tool-azure-rounded
+ +
icon-tool-azure-solid
+ +
icon-tool-bpmn-add-annotation
+ +
icon-tool-bpmn-choreography-add-initiating-message
+ +
icon-tool-bpmn-choreography-add-participant-lower
+ +
icon-tool-bpmn-choreography-add-participant-upper
+ +
icon-tool-bpmn-choreography-add-return-message
+ +
icon-tool-bpmn-choreography-create-participant-lower
+ +
icon-tool-bpmn-choreography-create-participant-upper
+ +
icon-tool-bpmn-choreography-initiating-participant
+ +
icon-tool-BPMNBoundaryEvent
+ +
icon-tool-BPMNCancelEventDefinition
+ +
icon-tool-BPMNCompensateEventDefinition
+ +
icon-tool-BPMNConditionalEventDefinition
+ +
icon-tool-BPMNErrorEventDefinition
+ +
icon-tool-BPMNEscalationEventDefinition
+ +
icon-tool-BPMNLane
+ +
icon-tool-BPMNLinkEventDefinition
+ +
icon-tool-BPMNMessageEventDefinition
+ +
icon-tool-BPMNSignalEventDefinition
+ +
icon-tool-BPMNTerminateEventDefinition
+ +
icon-tool-BPMNTimerEventDefinition
+ +
icon-tool-bring-to-front
+ +
icon-tool-choice
+ +
icon-tool-communicating-node
+ +
icon-tool-composite
+ +
icon-tool-composition
+ +
icon-tool-connected-lifeline
+ +
icon-tool-connected-part
+ +
icon-tool-connection-point-reference
+ +
icon-tool-constraint-parameter
+ +
icon-tool-constraint-property
+ +
icon-tool-constraint
+ +
icon-tool-create-block
+ +
icon-tool-create-constraint-block
+ +
icon-tool-create-item-flow
+ +
icon-tool-create-message-lifeline
+ +
icon-tool-create-message
+ +
icon-tool-create-operation
+ +
icon-tool-create-signal
+ +
icon-tool-create-state-condition
+ +
icon-tool-create-type
+ +
icon-tool-create-value-type
+ +
icon-tool-curve
+ +
icon-tool-decision
+ +
icon-tool-delete-item-flow
+ +
icon-tool-delete-message
+ +
icon-tool-delete
+ +
icon-tool-dependant-package
+ +
icon-tool-depending-package
+ +
icon-tool-deployed-artifact
+ +
icon-tool-deployed-component
+ +
icon-tool-do-activity
+ +
icon-tool-edit
+ +
icon-tool-effect
+ +
icon-tool-end-order-backward
+ +
icon-tool-end-order-forward
+ +
icon-tool-end-order-hide
+ +
icon-tool-entry-activity
+ +
icon-tool-enumeration-literal
+ +
icon-tool-erd-column-key
+ +
icon-tool-erd-column-non-key
+ +
icon-tool-erd-column
+ +
icon-tool-erd-identifying
+ +
icon-tool-erd-many-to-many
+ +
icon-tool-erd-many
+ +
icon-tool-erd-non-identifying
+ +
icon-tool-erd-one-to-many
+ +
icon-tool-erd-one-to-one
+ +
icon-tool-erd-one
+ +
icon-tool-erd-zero-many
+ +
icon-tool-erd-zero-one
+ +
icon-tool-event
+ +
icon-tool-exit-activity
+ +
icon-tool-extended-usecase
+ +
icon-tool-extension-point
+ +
icon-tool-fc-incoming-decision
+ +
icon-tool-fc-incoming-process
+ +
icon-tool-fc-outgoing-decision
+ +
icon-tool-fc-outgoing-process
+ +
icon-tool-fill-color
+ +
icon-tool-final-node
+ +
icon-tool-final-state
+ +
icon-tool-flow-property
+ +
icon-tool-font-color
+ +
icon-tool-fork
+ +
icon-tool-forward-message
+ +
icon-tool-found-message
+ +
icon-tool-gcp-icon-zone-account
+ +
icon-tool-gcp-icon-zone-external-data-sources
+ +
icon-tool-gcp-icon-zone-external-firstparty-infrastructure
+ +
icon-tool-gcp-icon-zone-external-saas-providers
+ +
icon-tool-gcp-icon-zone-external-thirdparty-infrastructure
+ +
icon-tool-gcp-icon-zone-firewall
+ +
icon-tool-gcp-icon-zone-infrastructure-system
+ +
icon-tool-gcp-icon-zone-instance-group
+ +
icon-tool-gcp-icon-zone-kubernetes-cluster
+ +
icon-tool-gcp-icon-zone-logical-group
+ +
icon-tool-gcp-icon-zone-on-premises
+ +
icon-tool-gcp-icon-zone-optional
+ +
icon-tool-gcp-icon-zone-pod
+ +
icon-tool-gcp-icon-zone-project
+ +
icon-tool-gcp-icon-zone-region
+ +
icon-tool-gcp-icon-zone-replica-pool
+ +
icon-tool-gcp-icon-zone-sub-network
+ +
icon-tool-gcp-icon-zone-system
+ +
icon-tool-gcp-icon-zone-user
+ +
icon-tool-gcp-icon-zone-zone
+ +
icon-tool-gcp-icon
+ +
icon-tool-head-end-style-flat
+ +
icon-tool-head-end-style-solid
+ +
icon-tool-head-end-style-stick
+ +
icon-tool-included-usecase
+ +
icon-tool-incoming-control-flow
+ +
icon-tool-incoming-external-entity
+ +
icon-tool-incoming-object-flow
+ +
icon-tool-incoming-process
+ +
icon-tool-incoming-transition
+ +
icon-tool-initial-node
+ +
icon-tool-initial-state
+ +
icon-tool-input-pin
+ +
icon-tool-interface
+ +
icon-tool-internal-transition
+ +
icon-tool-join
+ +
icon-tool-line-color
+ +
icon-tool-linemode-dashed
+ +
icon-tool-linemode-dotted
+ +
icon-tool-linemode-solid
+ +
icon-tool-linked-object
+ +
icon-tool-lock
+ +
icon-tool-lost-message
+ +
icon-tool-merge
+ +
icon-tool-message-from-gate
+ +
icon-tool-message-lifeline
+ +
icon-tool-message-to-gate
+ +
icon-tool-MMAddNodeLeft
+ +
icon-tool-MMAddNodeRight
+ +
icon-tool-movedown
+ +
icon-tool-moveup
+ +
icon-tool-navigable
+ +
icon-tool-not-navigable
+ +
icon-tool-note
+ +
icon-tool-oblique
+ +
icon-tool-operand
+ +
icon-tool-operation
+ +
icon-tool-outgoing-control-flow
+ +
icon-tool-outgoing-datastore
+ +
icon-tool-outgoing-object-flow
+ +
icon-tool-outgoing-process
+ +
icon-tool-outgoing-transition
+ +
icon-tool-output-pin
+ +
icon-tool-package
+ +
icon-tool-parameter-property
+ +
icon-tool-part-property
+ +
icon-tool-part
+ +
icon-tool-port
+ +
icon-tool-private
+ +
icon-tool-property
+ +
icon-tool-protected
+ +
icon-tool-public
+ +
icon-tool-realizing-class
+ +
icon-tool-reception
+ +
icon-tool-rectilinear
+ +
icon-tool-reference-property
+ +
icon-tool-region
+ +
icon-tool-reply-message
+ +
icon-tool-reply
+ +
icon-tool-required-interface
+ +
icon-tool-reverse-message
+ +
icon-tool-rounded-rectilinear
+ +
icon-tool-search
+ +
icon-tool-select-block
+ +
icon-tool-select-constraint-block
+ +
icon-tool-select-item-flow
+ +
icon-tool-select-operation
+ +
icon-tool-select-owner-attribute
+ +
icon-tool-select-signal
+ +
icon-tool-select-type
+ +
icon-tool-select-value-type
+ +
icon-tool-select
+ +
icon-tool-self-connector
+ +
icon-tool-self-message
+ +
icon-tool-send-to-back
+ +
icon-tool-set-height-equal
+ +
icon-tool-set-size-equal
+ +
icon-tool-set-width-equal
+ +
icon-tool-shared
+ +
icon-tool-show-namespace
+ +
icon-tool-show-property
+ +
icon-tool-show-shadow
+ +
icon-tool-show-type
+ +
icon-tool-show-visibility
+ +
icon-tool-slot
+ +
icon-tool-stereotype
+ +
icon-tool-subactor
+ +
icon-tool-subclass
+ +
icon-tool-subinterface
+ +
icon-tool-subpackage
+ +
icon-tool-substereotype
+ +
icon-tool-superactor
+ +
icon-tool-superclass
+ +
icon-tool-superinterface
+ +
icon-tool-superstereotype
+ +
icon-tool-suppress-attributes
+ +
icon-tool-suppress-columns
+ +
icon-tool-suppress-literals
+ +
icon-tool-suppress-operations
+ +
icon-tool-suppress-receptions
+ +
icon-tool-synch-call
+ +
icon-tool-tail-end-style-flat
+ +
icon-tool-tail-end-style-solid
+ +
icon-tool-tail-end-style-stick
+ +
icon-tool-template-parameter-substitution
+ +
icon-tool-template-parameter
+ +
icon-tool-text-align-bottom
+ +
icon-tool-text-align-center
+ +
icon-tool-text-align-left
+ +
icon-tool-text-align-middle
+ +
icon-tool-text-align-right
+ +
icon-tool-text-align-top
+ +
icon-tool-time-segment
+ +
icon-tool-unspecified
+ +
icon-tool-validation-error
+ +
icon-tool-validation-ok
+ +
icon-tool-value-property
+ +
icon-tool-WFAddTab
+ +
icon-tool-wordwrap
+ +
icon-UMLAcceptSignal
+ +
icon-UMLAcceptTimeEvent
+ +
icon-UMLAction
+ +
icon-UMLActivity
+ +
icon-UMLActivityDiagram
+ +
icon-UMLActivityEdgeConnector
+ +
icon-UMLActivityFinalNode
+ +
icon-UMLActivityInterrupt
+ +
icon-UMLActivityParameterNode
+ +
icon-UMLActor
+ +
icon-UMLAggregation
+ +
icon-UMLArtifact
+ +
icon-UMLArtifactInstance
+ +
icon-UMLAssociation
+ +
icon-UMLAssociationClassLink
+ +
icon-UMLAssociationEnd
+ +
icon-UMLAsyncMessage
+ +
icon-UMLAsyncSignalMessage
+ +
icon-UMLAttribute
+ +
icon-UMLBoundary
+ +
icon-UMLCentralBufferNode
+ +
icon-UMLChoice
+ +
icon-UMLClass
+ +
icon-UMLClassDiagram
+ +
icon-UMLCollaboration
+ +
icon-UMLCollaborationUse
+ +
icon-UMLCombinedFragment
+ +
icon-UMLCommunicationDiagram
+ +
icon-UMLCommunicationPath
+ +
icon-UMLComponent
+ +
icon-UMLComponentDiagram
+ +
icon-UMLComponentInstance
+ +
icon-UMLComponentRealization
+ +
icon-UMLCompositeState
+ +
icon-UMLCompositeStructureDiagram
+ +
icon-UMLComposition
+ +
icon-UMLConnectionPointReference
+ +
icon-UMLConnector
+ +
icon-UMLConnectorEnd
+ +
icon-UMLConstraint
+ +
icon-UMLContainment
+ +
icon-UMLContinuation
+ +
icon-UMLControl
+ +
icon-UMLControlFlow
+ +
icon-UMLCreateMessage
+ +
icon-UMLDataStoreNode
+ +
icon-UMLDataType
+ +
icon-UMLDecisionNode
+ +
icon-UMLDeepHistory
+ +
icon-UMLDeleteMessage
+ +
icon-UMLDependency
+ +
icon-UMLDeployment
+ +
icon-UMLDeploymentDiagram
+ +
icon-UMLDirectedAssociation
+ +
icon-UMLDirectedLink
+ +
icon-UMLDoActivity
+ +
icon-UMLDurationConstraint
+ +
icon-UMLEffect
+ +
icon-UMLEndpoint
+ +
icon-UMLEntity
+ +
icon-UMLEntryActivity
+ +
icon-UMLEntryPoint
+ +
icon-UMLEnumeration
+ +
icon-UMLEnumerationLiteral
+ +
icon-UMLEvent
+ +
icon-UMLExceptionHandler
+ +
icon-UMLExitActivity
+ +
icon-UMLExitPoint
+ +
icon-UMLExpansionNode
+ +
icon-UMLExpansionRegion
+ +
icon-UMLExtend
+ +
icon-UMLExtension
+ +
icon-UMLExtensionPoint
+ +
icon-UMLFinalState
+ +
icon-UMLFlowFinalNode
+ +
icon-UMLFork
+ +
icon-UMLForkNode
+ +
icon-UMLForwardMessage
+ +
icon-UMLFoundMessage
+ +
icon-UMLFrame
+ +
icon-UMLGate
+ +
icon-UMLGeneralization
+ +
icon-UMLImage
+ +
icon-UMLInclude
+ +
icon-UMLInformationFlow
+ +
icon-UMLInformationFlowDiagram
+ +
icon-UMLInformationItem
+ +
icon-UMLInitialNode
+ +
icon-UMLInitialState
+ +
icon-UMLInputExpansionNode
+ +
icon-UMLInputPin
+ +
icon-UMLInteraction
+ +
icon-UMLInteractionOperand
+ +
icon-UMLInteractionOverviewDiagram
+ +
icon-UMLInteractionUse
+ +
icon-UMLInterface
+ +
icon-UMLInterfaceRealization
+ +
icon-UMLInterruptibleActivityRegion
+ +
icon-UMLJoin
+ +
icon-UMLJoinNode
+ +
icon-UMLJunction
+ +
icon-UMLLifeline
+ +
icon-UMLLink
+ +
icon-UMLLinkEnd
+ +
icon-UMLLinkObjectLink
+ +
icon-UMLLostMessage
+ +
icon-UMLMergeNode
+ +
icon-UMLMessage
+ +
icon-UMLMetaClass
+ +
icon-UMLModel
+ +
icon-UMLNaryAssociationNode
+ +
icon-UMLNode
+ +
icon-UMLNodeInstance
+ +
icon-UMLNote
+ +
icon-UMLNoteLink
+ +
icon-UMLObject
+ +
icon-UMLObjectDiagram
+ +
icon-UMLObjectFlow
+ +
icon-UMLObjectNode
+ +
icon-UMLOpaqueBehavior
+ +
icon-UMLOperation
+ +
icon-UMLOrthogonalState
+ +
icon-UMLOutputExpansionNode
+ +
icon-UMLOutputPin
+ +
icon-UMLPackage
+ +
icon-UMLPackageDiagram
+ +
icon-UMLParameter
+ +
icon-UMLPart
+ +
icon-UMLPort
+ +
icon-UMLPrimitiveType
+ +
icon-UMLProfile
+ +
icon-UMLProfileDiagram
+ +
icon-UMLRealization
+ +
icon-UMLReception
+ +
icon-UMLRegion
+ +
icon-UMLReplyMessage
+ +
icon-UMLReverseMessage
+ +
icon-UMLRoleBinding
+ +
icon-UMLSelfConnector
+ +
icon-UMLSelfLink
+ +
icon-UMLSelfMessage
+ +
icon-UMLSelfTransition
+ +
icon-UMLSendSignal
+ +
icon-UMLSequenceDiagram
+ +
icon-UMLShallowHistory
+ +
icon-UMLSignal
+ +
icon-UMLSlot
+ +
icon-UMLStandardProfile-boundary
+ +
icon-UMLStandardProfile-control
+ +
icon-UMLStandardProfile-entity
+ +
icon-UMLState
+ +
icon-UMLStatechartDiagram
+ +
icon-UMLStateCondition
+ +
icon-UMLStateInvariant
+ +
icon-UMLStateMachine
+ +
icon-UMLStereotype
+ +
icon-UMLStructuredActivityNode
+ +
icon-UMLSubmachineState
+ +
icon-UMLSubsystem
+ +
icon-UMLSwimlaneHorz
+ +
icon-UMLSwimlaneVert
+ +
icon-UMLTemplateBinding
+ +
icon-UMLTemplateParameter
+ +
icon-UMLTemplateParameterSubstitution
+ +
icon-UMLTerminate
+ +
icon-UMLText
+ +
icon-UMLTextBox
+ +
icon-UMLTimeConstraint
+ +
icon-UMLTimeSegment
+ +
icon-UMLTimeTick
+ +
icon-UMLTimingDiagram
+ +
icon-UMLTimingLifeline
+ +
icon-UMLTransition
+ +
icon-UMLUseCase
+ +
icon-UMLUseCaseDiagram
+ +
icon-UMLUseCaseSubject
+ +
icon-WFAvatar
+ +
icon-WFButton
+ +
icon-WFCheckbox
+ +
icon-WFDesktopFrame
+ +
icon-WFDropdown
+ +
icon-WFFrame
+ +
icon-WFImage
+ +
icon-WFInput
+ +
icon-WFLink
+ +
icon-WFMobileFrame
+ +
icon-WFPanel
+ +
icon-WFRadio
+ +
icon-WFSeparator
+ +
icon-WFSlider
+ +
icon-WFSwitch
+ +
icon-WFTab
+ +
icon-WFTabList
+ +
icon-WFText
+ +
icon-WFWebFrame
+ +
icon-WFWireframe
+ +
icon-WFWireframeDiagram
+ +
+ + + +

Usage

+
<i class="staruml-icon icon-name"></i>
+ + + + + + + diff --git a/docs/UML/html/index.html/assets/icon-font/icons.ttf b/docs/UML/html/index.html/assets/icon-font/icons.ttf new file mode 100755 index 0000000..00198f0 Binary files /dev/null and b/docs/UML/html/index.html/assets/icon-font/icons.ttf differ diff --git a/docs/UML/html/index.html/assets/icon-font/icons.woff b/docs/UML/html/index.html/assets/icon-font/icons.woff new file mode 100755 index 0000000..f42f5ea Binary files /dev/null and b/docs/UML/html/index.html/assets/icon-font/icons.woff differ diff --git a/docs/UML/html/index.html/assets/img/glyphicons-halflings-white.png b/docs/UML/html/index.html/assets/img/glyphicons-halflings-white.png new file mode 100755 index 0000000..3bf6484 Binary files /dev/null and b/docs/UML/html/index.html/assets/img/glyphicons-halflings-white.png differ diff --git a/docs/UML/html/index.html/assets/img/glyphicons-halflings.png b/docs/UML/html/index.html/assets/img/glyphicons-halflings.png new file mode 100755 index 0000000..a996999 Binary files /dev/null and b/docs/UML/html/index.html/assets/img/glyphicons-halflings.png differ diff --git a/docs/UML/html/index.html/assets/js/bootstrap.js b/docs/UML/html/index.html/assets/js/bootstrap.js new file mode 100755 index 0000000..c298ee4 --- /dev/null +++ b/docs/UML/html/index.html/assets/js/bootstrap.js @@ -0,0 +1,2276 @@ +/* =================================================== + * bootstrap-transition.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#transitions + * =================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) + * ======================================================= */ + + $(function () { + + $.support.transition = (function () { + + var transitionEnd = (function () { + + var el = document.createElement('bootstrap') + , transEndEventNames = { + 'WebkitTransition' : 'webkitTransitionEnd' + , 'MozTransition' : 'transitionend' + , 'OTransition' : 'oTransitionEnd otransitionend' + , 'transition' : 'transitionend' + } + , name + + for (name in transEndEventNames){ + if (el.style[name] !== undefined) { + return transEndEventNames[name] + } + } + + }()) + + return transitionEnd && { + end: transitionEnd + } + + })() + + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-alert.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#alerts + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* ALERT CLASS DEFINITION + * ====================== */ + + var dismiss = '[data-dismiss="alert"]' + , Alert = function (el) { + $(el).on('click', dismiss, this.close) + } + + Alert.prototype.close = function (e) { + var $this = $(this) + , selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = $(selector) + + e && e.preventDefault() + + $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent()) + + $parent.trigger(e = $.Event('close')) + + if (e.isDefaultPrevented()) return + + $parent.removeClass('in') + + function removeElement() { + $parent + .trigger('closed') + .remove() + } + + $.support.transition && $parent.hasClass('fade') ? + $parent.on($.support.transition.end, removeElement) : + removeElement() + } + + + /* ALERT PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.alert + + $.fn.alert = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('alert') + if (!data) $this.data('alert', (data = new Alert(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.alert.Constructor = Alert + + + /* ALERT NO CONFLICT + * ================= */ + + $.fn.alert.noConflict = function () { + $.fn.alert = old + return this + } + + + /* ALERT DATA-API + * ============== */ + + $(document).on('click.alert.data-api', dismiss, Alert.prototype.close) + +}(window.jQuery);/* ============================================================ + * bootstrap-button.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#buttons + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* BUTTON PUBLIC CLASS DEFINITION + * ============================== */ + + var Button = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.button.defaults, options) + } + + Button.prototype.setState = function (state) { + var d = 'disabled' + , $el = this.$element + , data = $el.data() + , val = $el.is('input') ? 'val' : 'html' + + state = state + 'Text' + data.resetText || $el.data('resetText', $el[val]()) + + $el[val](data[state] || this.options[state]) + + // push to event loop to allow forms to submit + setTimeout(function () { + state == 'loadingText' ? + $el.addClass(d).attr(d, d) : + $el.removeClass(d).removeAttr(d) + }, 0) + } + + Button.prototype.toggle = function () { + var $parent = this.$element.closest('[data-toggle="buttons-radio"]') + + $parent && $parent + .find('.active') + .removeClass('active') + + this.$element.toggleClass('active') + } + + + /* BUTTON PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.button + + $.fn.button = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('button') + , options = typeof option == 'object' && option + if (!data) $this.data('button', (data = new Button(this, options))) + if (option == 'toggle') data.toggle() + else if (option) data.setState(option) + }) + } + + $.fn.button.defaults = { + loadingText: 'loading...' + } + + $.fn.button.Constructor = Button + + + /* BUTTON NO CONFLICT + * ================== */ + + $.fn.button.noConflict = function () { + $.fn.button = old + return this + } + + + /* BUTTON DATA-API + * =============== */ + + $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) { + var $btn = $(e.target) + if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn') + $btn.button('toggle') + }) + +}(window.jQuery);/* ========================================================== + * bootstrap-carousel.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#carousel + * ========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* CAROUSEL CLASS DEFINITION + * ========================= */ + + var Carousel = function (element, options) { + this.$element = $(element) + this.$indicators = this.$element.find('.carousel-indicators') + this.options = options + this.options.pause == 'hover' && this.$element + .on('mouseenter', $.proxy(this.pause, this)) + .on('mouseleave', $.proxy(this.cycle, this)) + } + + Carousel.prototype = { + + cycle: function (e) { + if (!e) this.paused = false + if (this.interval) clearInterval(this.interval); + this.options.interval + && !this.paused + && (this.interval = setInterval($.proxy(this.next, this), this.options.interval)) + return this + } + + , getActiveIndex: function () { + this.$active = this.$element.find('.item.active') + this.$items = this.$active.parent().children() + return this.$items.index(this.$active) + } + + , to: function (pos) { + var activeIndex = this.getActiveIndex() + , that = this + + if (pos > (this.$items.length - 1) || pos < 0) return + + if (this.sliding) { + return this.$element.one('slid', function () { + that.to(pos) + }) + } + + if (activeIndex == pos) { + return this.pause().cycle() + } + + return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos])) + } + + , pause: function (e) { + if (!e) this.paused = true + if (this.$element.find('.next, .prev').length && $.support.transition.end) { + this.$element.trigger($.support.transition.end) + this.cycle(true) + } + clearInterval(this.interval) + this.interval = null + return this + } + + , next: function () { + if (this.sliding) return + return this.slide('next') + } + + , prev: function () { + if (this.sliding) return + return this.slide('prev') + } + + , slide: function (type, next) { + var $active = this.$element.find('.item.active') + , $next = next || $active[type]() + , isCycling = this.interval + , direction = type == 'next' ? 'left' : 'right' + , fallback = type == 'next' ? 'first' : 'last' + , that = this + , e + + this.sliding = true + + isCycling && this.pause() + + $next = $next.length ? $next : this.$element.find('.item')[fallback]() + + e = $.Event('slide', { + relatedTarget: $next[0] + , direction: direction + }) + + if ($next.hasClass('active')) return + + if (this.$indicators.length) { + this.$indicators.find('.active').removeClass('active') + this.$element.one('slid', function () { + var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()]) + $nextIndicator && $nextIndicator.addClass('active') + }) + } + + if ($.support.transition && this.$element.hasClass('slide')) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $next.addClass(type) + $next[0].offsetWidth // force reflow + $active.addClass(direction) + $next.addClass(direction) + this.$element.one($.support.transition.end, function () { + $next.removeClass([type, direction].join(' ')).addClass('active') + $active.removeClass(['active', direction].join(' ')) + that.sliding = false + setTimeout(function () { that.$element.trigger('slid') }, 0) + }) + } else { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $active.removeClass('active') + $next.addClass('active') + this.sliding = false + this.$element.trigger('slid') + } + + isCycling && this.cycle() + + return this + } + + } + + + /* CAROUSEL PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.carousel + + $.fn.carousel = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('carousel') + , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option) + , action = typeof option == 'string' ? option : options.slide + if (!data) $this.data('carousel', (data = new Carousel(this, options))) + if (typeof option == 'number') data.to(option) + else if (action) data[action]() + else if (options.interval) data.pause().cycle() + }) + } + + $.fn.carousel.defaults = { + interval: 5000 + , pause: 'hover' + } + + $.fn.carousel.Constructor = Carousel + + + /* CAROUSEL NO CONFLICT + * ==================== */ + + $.fn.carousel.noConflict = function () { + $.fn.carousel = old + return this + } + + /* CAROUSEL DATA-API + * ================= */ + + $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) { + var $this = $(this), href + , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7 + , options = $.extend({}, $target.data(), $this.data()) + , slideIndex + + $target.carousel(options) + + if (slideIndex = $this.attr('data-slide-to')) { + $target.data('carousel').pause().to(slideIndex).cycle() + } + + e.preventDefault() + }) + +}(window.jQuery);/* ============================================================= + * bootstrap-collapse.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#collapse + * ============================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* COLLAPSE PUBLIC CLASS DEFINITION + * ================================ */ + + var Collapse = function (element, options) { + this.$element = $(element) + this.options = $.extend({}, $.fn.collapse.defaults, options) + + if (this.options.parent) { + this.$parent = $(this.options.parent) + } + + this.options.toggle && this.toggle() + } + + Collapse.prototype = { + + constructor: Collapse + + , dimension: function () { + var hasWidth = this.$element.hasClass('width') + return hasWidth ? 'width' : 'height' + } + + , show: function () { + var dimension + , scroll + , actives + , hasData + + if (this.transitioning || this.$element.hasClass('in')) return + + dimension = this.dimension() + scroll = $.camelCase(['scroll', dimension].join('-')) + actives = this.$parent && this.$parent.find('> .accordion-group > .in') + + if (actives && actives.length) { + hasData = actives.data('collapse') + if (hasData && hasData.transitioning) return + actives.collapse('hide') + hasData || actives.data('collapse', null) + } + + this.$element[dimension](0) + this.transition('addClass', $.Event('show'), 'shown') + $.support.transition && this.$element[dimension](this.$element[0][scroll]) + } + + , hide: function () { + var dimension + if (this.transitioning || !this.$element.hasClass('in')) return + dimension = this.dimension() + this.reset(this.$element[dimension]()) + this.transition('removeClass', $.Event('hide'), 'hidden') + this.$element[dimension](0) + } + + , reset: function (size) { + var dimension = this.dimension() + + this.$element + .removeClass('collapse') + [dimension](size || 'auto') + [0].offsetWidth + + this.$element[size !== null ? 'addClass' : 'removeClass']('collapse') + + return this + } + + , transition: function (method, startEvent, completeEvent) { + var that = this + , complete = function () { + if (startEvent.type == 'show') that.reset() + that.transitioning = 0 + that.$element.trigger(completeEvent) + } + + this.$element.trigger(startEvent) + + if (startEvent.isDefaultPrevented()) return + + this.transitioning = 1 + + this.$element[method]('in') + + $.support.transition && this.$element.hasClass('collapse') ? + this.$element.one($.support.transition.end, complete) : + complete() + } + + , toggle: function () { + this[this.$element.hasClass('in') ? 'hide' : 'show']() + } + + } + + + /* COLLAPSE PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.collapse + + $.fn.collapse = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('collapse') + , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option) + if (!data) $this.data('collapse', (data = new Collapse(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.collapse.defaults = { + toggle: true + } + + $.fn.collapse.Constructor = Collapse + + + /* COLLAPSE NO CONFLICT + * ==================== */ + + $.fn.collapse.noConflict = function () { + $.fn.collapse = old + return this + } + + + /* COLLAPSE DATA-API + * ================= */ + + $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) { + var $this = $(this), href + , target = $this.attr('data-target') + || e.preventDefault() + || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7 + , option = $(target).data('collapse') ? 'toggle' : $this.data() + $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed') + $(target).collapse(option) + }) + +}(window.jQuery);/* ============================================================ + * bootstrap-dropdown.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#dropdowns + * ============================================================ + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============================================================ */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* DROPDOWN CLASS DEFINITION + * ========================= */ + + var toggle = '[data-toggle=dropdown]' + , Dropdown = function (element) { + var $el = $(element).on('click.dropdown.data-api', this.toggle) + $('html').on('click.dropdown.data-api', function () { + $el.parent().removeClass('open') + }) + } + + Dropdown.prototype = { + + constructor: Dropdown + + , toggle: function (e) { + var $this = $(this) + , $parent + , isActive + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + clearMenus() + + if (!isActive) { + $parent.toggleClass('open') + } + + $this.focus() + + return false + } + + , keydown: function (e) { + var $this + , $items + , $active + , $parent + , isActive + , index + + if (!/(38|40|27)/.test(e.keyCode)) return + + $this = $(this) + + e.preventDefault() + e.stopPropagation() + + if ($this.is('.disabled, :disabled')) return + + $parent = getParent($this) + + isActive = $parent.hasClass('open') + + if (!isActive || (isActive && e.keyCode == 27)) { + if (e.which == 27) $parent.find(toggle).focus() + return $this.click() + } + + $items = $('[role=menu] li:not(.divider):visible a', $parent) + + if (!$items.length) return + + index = $items.index($items.filter(':focus')) + + if (e.keyCode == 38 && index > 0) index-- // up + if (e.keyCode == 40 && index < $items.length - 1) index++ // down + if (!~index) index = 0 + + $items + .eq(index) + .focus() + } + + } + + function clearMenus() { + $(toggle).each(function () { + getParent($(this)).removeClass('open') + }) + } + + function getParent($this) { + var selector = $this.attr('data-target') + , $parent + + if (!selector) { + selector = $this.attr('href') + selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 + } + + $parent = selector && $(selector) + + if (!$parent || !$parent.length) $parent = $this.parent() + + return $parent + } + + + /* DROPDOWN PLUGIN DEFINITION + * ========================== */ + + var old = $.fn.dropdown + + $.fn.dropdown = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('dropdown') + if (!data) $this.data('dropdown', (data = new Dropdown(this))) + if (typeof option == 'string') data[option].call($this) + }) + } + + $.fn.dropdown.Constructor = Dropdown + + + /* DROPDOWN NO CONFLICT + * ==================== */ + + $.fn.dropdown.noConflict = function () { + $.fn.dropdown = old + return this + } + + + /* APPLY TO STANDARD DROPDOWN ELEMENTS + * =================================== */ + + $(document) + .on('click.dropdown.data-api', clearMenus) + .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() }) + .on('click.dropdown-menu', function (e) { e.stopPropagation() }) + .on('click.dropdown.data-api' , toggle, Dropdown.prototype.toggle) + .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown) + +}(window.jQuery); +/* ========================================================= + * bootstrap-modal.js v2.3.1 + * http://twitter.github.com/bootstrap/javascript.html#modals + * ========================================================= + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================= */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* MODAL CLASS DEFINITION + * ====================== */ + + var Modal = function (element, options) { + this.options = options + this.$element = $(element) + .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)) + this.options.remote && this.$element.find('.modal-body').load(this.options.remote) + } + + Modal.prototype = { + + constructor: Modal + + , toggle: function () { + return this[!this.isShown ? 'show' : 'hide']() + } + + , show: function () { + var that = this + , e = $.Event('show') + + this.$element.trigger(e) + + if (this.isShown || e.isDefaultPrevented()) return + + this.isShown = true + + this.escape() + + this.backdrop(function () { + var transition = $.support.transition && that.$element.hasClass('fade') + + if (!that.$element.parent().length) { + that.$element.appendTo(document.body) //don't move modals dom position + } + + that.$element.show() + + if (transition) { + that.$element[0].offsetWidth // force reflow + } + + that.$element + .addClass('in') + .attr('aria-hidden', false) + + that.enforceFocus() + + transition ? + that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) : + that.$element.focus().trigger('shown') + + }) + } + + , hide: function (e) { + e && e.preventDefault() + + var that = this + + e = $.Event('hide') + + this.$element.trigger(e) + + if (!this.isShown || e.isDefaultPrevented()) return + + this.isShown = false + + this.escape() + + $(document).off('focusin.modal') + + this.$element + .removeClass('in') + .attr('aria-hidden', true) + + $.support.transition && this.$element.hasClass('fade') ? + this.hideWithTransition() : + this.hideModal() + } + + , enforceFocus: function () { + var that = this + $(document).on('focusin.modal', function (e) { + if (that.$element[0] !== e.target && !that.$element.has(e.target).length) { + that.$element.focus() + } + }) + } + + , escape: function () { + var that = this + if (this.isShown && this.options.keyboard) { + this.$element.on('keyup.dismiss.modal', function ( e ) { + e.which == 27 && that.hide() + }) + } else if (!this.isShown) { + this.$element.off('keyup.dismiss.modal') + } + } + + , hideWithTransition: function () { + var that = this + , timeout = setTimeout(function () { + that.$element.off($.support.transition.end) + that.hideModal() + }, 500) + + this.$element.one($.support.transition.end, function () { + clearTimeout(timeout) + that.hideModal() + }) + } + + , hideModal: function () { + var that = this + this.$element.hide() + this.backdrop(function () { + that.removeBackdrop() + that.$element.trigger('hidden') + }) + } + + , removeBackdrop: function () { + this.$backdrop && this.$backdrop.remove() + this.$backdrop = null + } + + , backdrop: function (callback) { + var that = this + , animate = this.$element.hasClass('fade') ? 'fade' : '' + + if (this.isShown && this.options.backdrop) { + var doAnimate = $.support.transition && animate + + this.$backdrop = $('