Trust and build
Trust and security
Understand installation evidence, provenance and safe defaults.
CANONICAL SOURCEView this guide in GitHub ↗
Trust and Security for Consumers
This guide explains what agent-toolkit installs on your machine, how to verify it, and where to report security concerns. For vulnerability disclosure, see SECURITY.md.
What gets installed
Depending on your install method, agent-toolkit may deploy:
| Artifact | Typical location | Contains secrets? |
|---|---|---|
| Skill instructions | Tool-specific skills/rules dirs | No |
| Agent personas | ~/.claude/agents/, .cursor/rules/, etc. |
No |
| Plugin manifests | Marketplace-managed | No |
| MCP templates | Referenced from docs; you add credentials locally | Placeholders only |
| CLI metadata | ~/.config/agent-toolkit/ |
No |
Credentials never ship in the repository. MCP templates use ${ENV_VAR}
placeholders. You provide tokens via your shell or tool config.
Verify your install
# Detect installed profiles and tools
agent-toolkit doctor
# List canonical capabilities (skills, agents, products)
agent-toolkit inventory
# Validate skill definitions from a git checkout
./scripts/validate-skills.vsh
After marketplace or CLI install, open your AI tool and confirm loaded skills match what you expect. Unrecognized rules or agents may indicate a partial install or conflicting older profile.
Installation receipts
The installer receipt module (agent_toolkit.installer.receipt / V
agent_toolkit_core) records what was installed. The compatibility schema
is published at schemas/install-receipt.schema.json
(issue #511):
- Location:
~/.config/agent-toolkit/receipts/<target>-<product>.json - schemaVersion:
1only - Fields: product, target, scope, version, installedAt, sourceDigest, artifacts, configPatches, secrets
- Secrets: always empty (
secrets: []) - Ownership:
created(uninstall removes) ormerged(preserved) - Safety: artifact paths must not contain
..segments
Receipts are written by agent-toolkit install / update and consumed by
agent-toolkit uninstall / rollback. Lifecycle tests cover create, save, load,
and uninstall-by-receipt; schema tests live in tests/test_install_receipt_schema.py.
Example shape (illustrative):
{
"schemaVersion": 1,
"product": "agent-toolkit-core",
"target": "cursor",
"version": "1.2.0",
"artifacts": [
{ "path": "/home/user/.cursor/rules/code-reviewer.mdc", "digest": "deadbeefcafebabe", "ownership": "created" }
],
"configPatches": [],
"secrets": []
}
Safe defaults
agent-toolkit follows these principles (see also docs/security/threat-model.md):
- No API keys, tokens, or passwords in source files
- No private hostnames in distributed configs
- No permission-bypass flags (e.g. skip dangerous-mode prompts) in shipped artifacts
- MCP credentials via environment variables only
- Secret scanning (Gitleaks) and CodeQL Python analysis in CI (
.github/workflows/codeql.yml— PRs andmain); Trivy Planned (see #260)
Supply chain
Canonical artifact: the native V binary from a GitHub Release (
agent-toolkit-<os>-<arch>, plusSHA256SUMS+manifest.jsonper ADR-018/ADR-022). All other channels are distribution adapters or downstream packages that fetch or wrap that canonical artifact. V is canonical; Python (agent-toolkit-clion PyPI) is a thin launcher (ADR-021) — this repository does not treat Python or shell scripts as the core runtime.
Installation channels
| Channel | Artifact | Build / Sign | Support level | Trust anchor | Verify |
|---|---|---|---|---|---|
| GitHub Releases | native V binary (agent-toolkit-<os>-<arch>, SHA256SUMS, manifest.json, sbom.cyclonedx.json) |
.github/workflows/release.yml (OIDC, SHA256SUMS + manifest.json per ADR-022) |
officially supported · security-supported | GitHub Release assets + SHA256SUMS; see docs/RELEASING.md |
curl -fsSL -O https://github.com/ulises-jeremias/agent-toolkit/releases/download/<tag>/SHA256SUMS && sha256sum -c SHA256SUMS --ignore-missing |
PyPI agent-toolkit-cli |
launcher wheel (packages/pypi/agent-toolkit-cli, ADR-021) |
release.yml publish-pypi via PyPI Trusted Publishing (OIDC env pypi) |
officially supported · security-supported | PyPI OIDC + uv/pip metadata |
uv tool install agent-toolkit-cli && agent-toolkit --version · pip show agent-toolkit-cli |
npm agent-toolkit-cli |
packages/npm/* wrappers (agent-toolkit-cli, agent-toolkit-cli-<platform>, ADR-025) |
publish-npm.yml via npm Trusted Publishing (OIDC id-token: write) |
officially supported | npm registry OIDC + optionalDependencies pins |
npm view agent-toolkit-cli version && npm view agent-toolkit-cli optionalDependencies |
Homebrew homebrew-tap |
Formula agent-toolkit.rb fetching GitHub Release V binary (ADR-018 floating names) |
ulises-jeremias/homebrew-tap (Formula url + sha256, built from Release) |
downstream maintained · best effort | Homebrew Formula signature; maintainer HOMEBREW_TAP_TOKEN |
brew info agent-toolkit && gh run list --repo ulises-jeremias/homebrew-tap --limit 3 |
AUR agent-toolkit-bin |
PKGBUILD sourcing GitHub Release V binary + SHA256SUMS |
ulises-jeremias/aur-packages (PKGBUILD) |
downstream maintained · best effort | AUR package metadata | yay -Si agent-toolkit-bin && gh run list --repo ulises-jeremias/aur-packages --limit 3 |
GHCR ghcr.io/ulises-jeremias/agent-toolkit |
container image wrapping GitHub Release V binary | .github/workflows/docker.yml (reusable job on Release) |
officially supported · best effort (experimental) | GHCR signature + Docker metadata | docker pull ghcr.io/ulises-jeremias/agent-toolkit:<tag> && docker run --rm ghcr.io/ulises-jeremias/agent-toolkit:<tag> agent-toolkit --version |
| Claude marketplace | plugins/*/plugin.json (agent-toolkit-core, agent-toolkit-agents, agent-toolkit-forge) |
.github/workflows/release.yml + plugins/* compiler output |
officially supported | Claude marketplace manifest (plugin.json) + GitHub repo |
/plugin marketplace add ulises-jeremias/agent-toolkit → /plugin install agent-toolkit-core@agent-toolkit |
| Cursor marketplace | plugins/*/plugin.json + .cursor-plugin/marketplace.json (Cursor plugin) |
release.yml + plugins/* |
officially supported | Cursor marketplace manifest | cursor-agent → /plugin → install agent-toolkit-core |
| Agent Plugins artifacts | portable plugin.json + skills/ + mcp.json (Agent Plugins 1.0) |
agent_toolkit.compiler.targets.agent_plugins (build → plugins/*) |
officially supported | agent-plugins.org schema + schemas/agent-plugins/1.0.0/*.schema.json |
agent-toolkit build && ./scripts/validate-agent-plugins.vsh --check |
Adapters vs downstream: PyPI/npm/marketplaces/Agent Plugins are distribution adapters that wrap the canonical artifact; Homebrew/AUR are downstream packages that fetch the canonical artifact from the Release. Never publish an adapter without a published canonical artifact.
Prefer tagged releases or marketplace installs over unreviewed forks. Single matrix source: this section. See also SECURITY.md#Supported Versions, docs/RELEASING.md (canonical artifact), distribution/README.md, and docs/INSTALLATION.md.
Legacy table (kept for compatibility)
| Install method | Trust anchor |
|---|---|
uvx --from agent-toolkit-cli |
PyPI package + CHANGELOG |
| Claude/Cursor marketplace | GitHub repo ulises-jeremias/agent-toolkit |
git clone + manual copy |
Pin a commit; review diff before copying |
| Homebrew/AUR | Tap/package maintainer signatures |
Provenance & third-party capabilities (per #364) — P0 foundation
Architecture per ADR-0001 (PR #403 — external provenance lock, accepted 2026-08-11):
CAPABILITY DECLARATION — “What is this capability and what external sources does it intend to use?”
↓ resolution SKILL.md frontmatter (origin, sources/upstream, trust, maintenance, distribution, security)
EXTERNAL PROVENANCE LOCK — “What exact immutable external artifacts were resolved?”
↓ integrity verification capabilities/upstream.lock v2: capability ID → source ID → {requested, resolved {commit, content_checksum, body_checksum, license, resolved_at}, provenance_digest}
VENDORED / EXTERNAL STATE — “What bytes/package/plugin actually correspond to that resolution?”
↓ generation skills/<domain>/<name>/SKILL.md (Toolkit frontmatter + **literal upstream body**) + LICENSE (+ siblings)
TARGET SURFACES — “How Claude/Cursor/Copilot/OpenCode/etc. consume the capability”
plugins/*, catalogs/*, docs/UPSTREAM.md (generated from declaration+lock)
Lock is a resolution artifact, not a second capability catalog. It is sparse — only
origin: upstreamcapabilities with external content appear;first-partynever appears. Runtime package resolution (uv.lock,pnpm-lock.yaml, Docker digest) stays in ecosystem locks, notupstream.lock. Seedocs/adrs/0001-capability-declaration-and-external-provenance-lock.mdandschemas/upstream-lock.schema.json.
Validation is offline/deterministic: SKILL.md + committed capabilities/upstream.lock + vendored bytes are enough for python3 scripts/provenance.py check (schema, SHA40, SPDX, content_checksum vs bytes, body_checksum fidelity, provenance_digest, orphan/missing, review binding). Network is only for scheduled/manual updates / updates --apply; normal PR CI never requires network.
Fidelity invariant (vendored): Local SKILL.md body (everything after the closing ---) must be byte-identical to upstream at the resolved commit. Only Toolkit overlay keys differ in frontmatter (origin, sources/upstream, trust, maintenance, distribution, security, updates). Sibling files from the upstream skill path are copied verbatim. Lock field resolved.body_checksum proves body identity offline.
Implemented now (in #399): Explicit origin classification + immutable provenance in SKILL.md frontmatter, validated via scripts/validate-upstream.py (origin.type required, 40-char SHA, SPDX subset — schemas/upstream.schema.json).
Implemented now (in #403): capabilities/upstream.lock v2 as external provenance lock (separate schema schemas/upstream-lock.schema.json, deterministic scripts/provenance.py lock / check / docs). Validation is in .github/workflows/validate.yml (validate-upstream + provenance check + lock --check + docs --check).
Implemented now (closes #428): Path-scoped / semver-tag discovery via scripts/provenance.py updates; --apply rewrites vendored skills to literal upstream bodies + Toolkit frontmatter, regenerates lock + docs/UPSTREAM.md, and sets trust.tier: experimental (drops reviewed_provenance) until human re-binds. Weekly .github/workflows/update-upstream.yml opens a draft PR (never auto-merges).
AGPL note: MegaLinter coding-agent skills are vendored under AGPL-3.0 with per-skill LICENSE (aggregation). See docs/megalinter/AGPL-VENDING.md.
Planned in #387: agent-toolkit inventory and doctor provenance wiring (display sources/provenance_digest, warn on stale pins, missing provenance). Until #387, provenance is visible via scripts/provenance.py check and frontmatter inspection only.
Canonical source table
| Data | Canonical source |
|---|---|
| Capability behavior | SKILL.md / capability declaration |
| Capability ID | declaration / catalog identity (design/frontend-design) |
| Origin | declaration (origin.type) |
Source intent (requested ref) |
declaration (upstream/sources) |
| Trust status | declaration (trust) |
| Security declaration | declaration (security) |
| Distribution policy | declaration (distribution) |
| Requested upstream version/ref | declaration (upstream.ref / sources[].ref) |
| Resolved commit | capabilities/upstream.lock (resolved.commit) |
| Content checksum | capabilities/upstream.lock (resolved.content_checksum) |
| Body checksum (fidelity) | capabilities/upstream.lock (resolved.body_checksum) |
| Observed resolved license | capabilities/upstream.lock (resolved.license) |
| Resolution timestamp | capabilities/upstream.lock (resolved.resolved_at) |
| Provenance digest | capabilities/upstream.lock (provenance_digest) + declaration trust.reviewed_provenance binding |
| Product membership | distributions/products.yaml |
| Generated catalogs | catalogs/* generator output |
| Target plugin copies | agent-toolkit build / plugin sync output |
| Runtime package versions | ecosystem-specific lock (uv.lock, etc.) |
Review lifecycle: provenance_digest = hash(source IDs + resolved commits + content_checksum + license spdx). Human review sets trust.reviewed_provenance = provenance_digest. Updating capabilities/upstream.lock to new commit/checksum/license changes the digest → existing reviewed_provenance mismatch → provenance.py check fails with review binding invalid until declaration is re-audited and trust.reviewed_provenance (and reviewed_at/reviewed_by) are updated. This elegantly separates lock resolution from human trust state (see ADR-0001 §13-14).
Security lifecycle: Declarations keep security: {scripts, shell, network, mcp, hooks, dangerous_permissions, cve_policy} as enforceable policy. Update tooling recomputes detected signals (scripts/audit-capability.vsh) and compares to declarations; a PR that introduces shell: true where declaration said shell: false fails or requires explicit declaration change + review. License policy vs observed: declaration upstream.license is expected spdx: Apache-2.0; lock resolved.license.spdx is observed. CI detects expected vs observed drift.
Every SKILL.md must have an explicit origin — no inference from path or absence (gate 2):
origin:
type: first-party # or upstream
For first-party, no provenance is allowed. For upstream, one or more sources are required (gate 9).
inspired_by vs vendored lock
First-party skills may record upstream inspiration without vendoring:
origin:
type: first-party
metadata:
inspired_by:
- repository: cursor/plugins
path: fix-ci/skills/fix-ci
ref: 60c641e4fad674784b30abcf9f8915dea39df38d
note: CI log triage patterns absorbed into gh-fix-ci
| Mechanism | When | Provenance lock | Body fidelity |
|---|---|---|---|
| Vendored upstream | Literal copy of portable third-party skill | Required in capabilities/upstream.lock |
Body byte-identical to upstream |
| inspired_by | First-party skill enhanced with third-party ideas | Not in lock | First-party body; attribution in frontmatter only |
See UPSTREAM_VS_FIRST_PARTY.md for the decision matrix.
First-party example
---
name: assistant
description: Assistant — scan README→docs→AGENTS before code; cite sources.
origin:
type: first-party
---
Single-source upstream (Anthropic frontend-design — Apache-2.0 verified 2026-08-11)
---
name: frontend-design
description: Distinctive, intentional visual design (Anthropic).
origin:
type: upstream
upstream:
repository: anthropics/skills
path: skills/frontend-design
ref: f17010c9bb483898c1d9c9f42dde2b3a98889434 # full 40-char SHA, never short SHA (gate 1)
license: Apache-2.0 # SPDX subset (gate 6) — verified 2026-08-11: LICENSE.txt Apache-2.0, not MIT
trust:
tier: reviewed # gate 5: 'reviewed' replaces 'verified' (verified is deprecated alias)
reviewed_at: "2026-08-11"
reviewed_by: ulises-jeremias
maintenance:
status: active # gate 4: independent of trust tier
last_activity: "2026-08-07"
distribution:
mode: vendored # gate 8: mutually exclusive delivery channel (see semantics below)
redistribution_allowed: true
security:
scripts: false
shell: false
network: false
cve_policy: not-applicable # gate 4: for pure instruction assets, not package CVE
---
Multi-source upstream (Vercel web-design-guidelines — gate 9)
One capability may derive from multiple artifacts. Use sources with role:
origin:
type: upstream
sources:
- role: wrapper
repository: vercel-labs/agent-skills
path: skills/web-design-guidelines
ref: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a