@huddle-marketplace/skills 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +256 -0
- package/dist/adapters/openclaw.d.ts +42 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +94 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/base.d.ts +26 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +97 -0
- package/dist/base.js.map +1 -0
- package/dist/compose.d.ts +87 -0
- package/dist/compose.d.ts.map +1 -0
- package/dist/compose.js +119 -0
- package/dist/compose.js.map +1 -0
- package/dist/index.d.ts +104 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +167 -0
- package/dist/index.js.map +1 -0
- package/dist/jurisdictions/ca-bc/index.d.ts +49 -0
- package/dist/jurisdictions/ca-bc/index.d.ts.map +1 -0
- package/dist/jurisdictions/ca-bc/index.js +212 -0
- package/dist/jurisdictions/ca-bc/index.js.map +1 -0
- package/dist/jurisdictions/ca-ns/index.d.ts +27 -0
- package/dist/jurisdictions/ca-ns/index.d.ts.map +1 -0
- package/dist/jurisdictions/ca-ns/index.js +127 -0
- package/dist/jurisdictions/ca-ns/index.js.map +1 -0
- package/dist/jurisdictions/ca-on/index.d.ts +26 -0
- package/dist/jurisdictions/ca-on/index.d.ts.map +1 -0
- package/dist/jurisdictions/ca-on/index.js +109 -0
- package/dist/jurisdictions/ca-on/index.js.map +1 -0
- package/dist/jurisdictions/ca-qc/index.d.ts +75 -0
- package/dist/jurisdictions/ca-qc/index.d.ts.map +1 -0
- package/dist/jurisdictions/ca-qc/index.js +232 -0
- package/dist/jurisdictions/ca-qc/index.js.map +1 -0
- package/dist/jurisdictions/canadian-template.d.ts +49 -0
- package/dist/jurisdictions/canadian-template.d.ts.map +1 -0
- package/dist/jurisdictions/canadian-template.js +228 -0
- package/dist/jurisdictions/canadian-template.js.map +1 -0
- package/dist/jurisdictions/lifecycle/active-tenancy.d.ts +55 -0
- package/dist/jurisdictions/lifecycle/active-tenancy.d.ts.map +1 -0
- package/dist/jurisdictions/lifecycle/active-tenancy.js +227 -0
- package/dist/jurisdictions/lifecycle/active-tenancy.js.map +1 -0
- package/dist/jurisdictions/lifecycle/homeownership-readiness.d.ts +60 -0
- package/dist/jurisdictions/lifecycle/homeownership-readiness.d.ts.map +1 -0
- package/dist/jurisdictions/lifecycle/homeownership-readiness.js +401 -0
- package/dist/jurisdictions/lifecycle/homeownership-readiness.js.map +1 -0
- package/dist/jurisdictions/us-ca/index.d.ts +65 -0
- package/dist/jurisdictions/us-ca/index.d.ts.map +1 -0
- package/dist/jurisdictions/us-ca/index.js +265 -0
- package/dist/jurisdictions/us-ca/index.js.map +1 -0
- package/dist/jurisdictions/us-cftc/index.d.ts +48 -0
- package/dist/jurisdictions/us-cftc/index.d.ts.map +1 -0
- package/dist/jurisdictions/us-cftc/index.js +192 -0
- package/dist/jurisdictions/us-cftc/index.js.map +1 -0
- package/dist/jurisdictions/us-fl/index.d.ts +43 -0
- package/dist/jurisdictions/us-fl/index.d.ts.map +1 -0
- package/dist/jurisdictions/us-fl/index.js +129 -0
- package/dist/jurisdictions/us-fl/index.js.map +1 -0
- package/dist/jurisdictions/us-ny/index.d.ts +77 -0
- package/dist/jurisdictions/us-ny/index.d.ts.map +1 -0
- package/dist/jurisdictions/us-ny/index.js +344 -0
- package/dist/jurisdictions/us-ny/index.js.map +1 -0
- package/dist/jurisdictions/us-state-factory.d.ts +79 -0
- package/dist/jurisdictions/us-state-factory.d.ts.map +1 -0
- package/dist/jurisdictions/us-state-factory.js +425 -0
- package/dist/jurisdictions/us-state-factory.js.map +1 -0
- package/dist/jurisdictions/us-tx/index.d.ts +43 -0
- package/dist/jurisdictions/us-tx/index.d.ts.map +1 -0
- package/dist/jurisdictions/us-tx/index.js +160 -0
- package/dist/jurisdictions/us-tx/index.js.map +1 -0
- package/dist/mcp/index.d.ts +49 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +211 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/registry/index.d.ts +27 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +47 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/traiga/index.d.ts +24 -0
- package/dist/traiga/index.d.ts.map +1 -0
- package/dist/traiga/index.js +67 -0
- package/dist/traiga/index.js.map +1 -0
- package/dist/types/index.d.ts +814 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +150 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +77 -0
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# @huddle-marketplace/skills
|
|
2
|
+
|
|
3
|
+
**63-jurisdiction rental compliance skills for autonomous AI agents.**
|
|
4
|
+
|
|
5
|
+
Validates security deposits, rent payments, late fees, and deposit returns against real statutes across 50 US states, 13 Canadian provinces, and federal overlays. OpenClaw, MCP, LangChain, and CrewAI compatible.
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @huddle-marketplace/skills
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { validate, composeSkills, registry } from "@huddle-marketplace/skills";
|
|
17
|
+
|
|
18
|
+
// Single jurisdiction — wBTC bond in Texas
|
|
19
|
+
const result = await validate("US-TX", {
|
|
20
|
+
type: "deposit-validation",
|
|
21
|
+
depositAmountCents: 200000, // $2,000 — always in CENTS
|
|
22
|
+
monthlyRentCents: 200000, // $2,000
|
|
23
|
+
currency: "USDC",
|
|
24
|
+
collateralType: "wbtc",
|
|
25
|
+
instrumentType: "collateralized_lease_guarantee",
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
console.log(result.compliant); // true
|
|
29
|
+
console.log(result.confidence); // 0.9
|
|
30
|
+
console.log(result.citations); // [{ statute: "Texas SB-38", section: "Section 3", ... }]
|
|
31
|
+
|
|
32
|
+
// Stacked validation — CFTC federal preemption + state rules
|
|
33
|
+
const composed = await composeSkills(["US-CFTC", "US-TX"], {
|
|
34
|
+
type: "deposit-validation",
|
|
35
|
+
depositAmountCents: 200000,
|
|
36
|
+
monthlyRentCents: 200000,
|
|
37
|
+
currency: "USDC",
|
|
38
|
+
collateralType: "wbtc",
|
|
39
|
+
instrumentType: "collateralized_lease_guarantee",
|
|
40
|
+
wbtcUsdcRatio: 1.05,
|
|
41
|
+
custodyType: "smart_contract",
|
|
42
|
+
sentinelMonitoring: true,
|
|
43
|
+
sentinelMode: "CO_PILOT",
|
|
44
|
+
lastSentinelCheckMs: Date.now() - 60000,
|
|
45
|
+
auditLogEnabled: true,
|
|
46
|
+
lastDecisionReasoning: "LTV nominal",
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
console.log(composed.compliant); // true
|
|
50
|
+
console.log(composed.layers.length); // 2
|
|
51
|
+
console.log(composed.checks[0].name); // "[US-CFTC] federal-preemption"
|
|
52
|
+
console.log(composed.citations.length); // merged + deduplicated
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## API Reference
|
|
58
|
+
|
|
59
|
+
### `validate(jurisdiction, input)`
|
|
60
|
+
|
|
61
|
+
Run a single jurisdiction's skill against the input.
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
const result = await validate("US-CA", input);
|
|
65
|
+
// result: SkillResult
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### `composeSkills(jurisdictions, input, options?)`
|
|
69
|
+
|
|
70
|
+
Stack multiple jurisdictions into one layered compliance proof. Layers run in parallel.
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
const result = await composeSkills(["US-CFTC", "US-IL"], input);
|
|
74
|
+
// result: ComposedResult — { compliant, confidence, layers[], checks[], citations[], remediation[] }
|
|
75
|
+
|
|
76
|
+
// Advisory mode: only US-CFTC determines overall compliance
|
|
77
|
+
const result = await composeSkills(["US-CFTC", "US-TX"], input, {
|
|
78
|
+
mode: "advisory",
|
|
79
|
+
criticalJurisdictions: ["US-CFTC"],
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### `registry`
|
|
84
|
+
|
|
85
|
+
Pre-loaded registry with all 64 jurisdictions.
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
registry.get("US-TX") // HuddleSkill | undefined
|
|
89
|
+
registry.jurisdictions() // JurisdictionCode[]
|
|
90
|
+
registry.isSupported("US-TX") // boolean
|
|
91
|
+
registry.search(["deposit-validation"]) // HuddleSkill[]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `explain(jurisdiction, result)`
|
|
95
|
+
|
|
96
|
+
Human-readable explanation of a validation result.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const text = explain("US-TX", result);
|
|
100
|
+
// "This transaction PASSES Texas SB-38 & Property Code §92 compliance (confidence: 90%)..."
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## Jurisdictions
|
|
106
|
+
|
|
107
|
+
### US States (50)
|
|
108
|
+
|
|
109
|
+
| Tier | States | Capabilities |
|
|
110
|
+
|---|---|---|
|
|
111
|
+
| **Tier 1 — Full statute logic** | TX, FL, CA, NY | deposit-validation, deposit-return, federal-preemption |
|
|
112
|
+
| **Tier 2 — Real rules** | IL, WA, CO, MA, PA, OH, GA, NC, VA, MI | deposit-validation, payment-compliance, deposit-return, deposit-interest |
|
|
113
|
+
| **Tier 3 — Capped states** | 26 states with statutory caps | deposit-validation, federal-preemption |
|
|
114
|
+
| **Tier 4 — No-cap states** | Remaining states | deposit-validation, federal-preemption |
|
|
115
|
+
|
|
116
|
+
### Canadian Provinces (13)
|
|
117
|
+
|
|
118
|
+
| Tier | Provinces |
|
|
119
|
+
|---|---|
|
|
120
|
+
| **Full statute** | BC, ON, QC (bilingual), NS |
|
|
121
|
+
| **Template** | AB, MB, SK, NB, PE, NL, NT, YT, NU |
|
|
122
|
+
|
|
123
|
+
### Federal Overlays
|
|
124
|
+
|
|
125
|
+
| Code | Coverage |
|
|
126
|
+
|---|---|
|
|
127
|
+
| `US-CFTC` | CFTC 9180-26: wBTC bond federal preemption, 1:1 reserve ratio, Sentinel monitoring, TRAIGA |
|
|
128
|
+
| `CA-QC` | CCQ art. 1904 deposit prohibition, TAL jurisdiction, bilingual FR/EN citations |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Web3-Native Features
|
|
133
|
+
|
|
134
|
+
### wBTC Bond Recognition
|
|
135
|
+
|
|
136
|
+
When `collateralType: "wbtc"` is set, skills recognize that `HuddleDepositVaultV3`'s on-chain Golden Rule (wBTC value ≥ original principal, enforced by Solidity) structurally satisfies — and exceeds — statutory interest requirements:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// IL requires 5% annual interest on deposits
|
|
140
|
+
// wBTC bond → interest check returns confidence: 0.98 (higher than legacy 0.75)
|
|
141
|
+
const result = await validate("US-IL", {
|
|
142
|
+
type: "deposit-validation",
|
|
143
|
+
collateralType: "wbtc", // ← Web3 path
|
|
144
|
+
...
|
|
145
|
+
});
|
|
146
|
+
// check "deposit-interest-requirement": passed: true, confidence: 0.98
|
|
147
|
+
// note: "SATISFIED: wBTC bond appreciation via HuddleDepositVaultV3 structurally exceeds..."
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Composition Engine
|
|
151
|
+
|
|
152
|
+
Federal + state validation in one call:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
const result = await composeSkills(["US-CFTC", "US-TX", "US-IL"], input);
|
|
156
|
+
// Runs all 3 in parallel, merges checks, deduplicates citations
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Framework Adapters
|
|
162
|
+
|
|
163
|
+
### MCP (Model Context Protocol)
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { getMCPToolDefinitions, handleMCPRequest } from "@huddle-marketplace/skills/mcp";
|
|
167
|
+
|
|
168
|
+
const tools = getMCPToolDefinitions(); // Ready for Claude Desktop
|
|
169
|
+
const response = await handleMCPRequest(mcpRequest, registry);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### OpenClaw
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
import { toOpenClawSkill } from "@huddle-marketplace/skills/openclaw";
|
|
176
|
+
|
|
177
|
+
const openClawTool = toOpenClawSkill(usTxSkill);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### LangChain
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { registry } from "@huddle-marketplace/skills/langchain";
|
|
184
|
+
// DynamicStructuredTool instances for every jurisdiction
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### TRAIGA Audit Logging
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
import { withTraiga, ConsoleTraigaAdapter } from "@huddle-marketplace/skills/traiga";
|
|
191
|
+
|
|
192
|
+
const auditedSkill = withTraiga(usTxSkill, new ConsoleTraigaAdapter());
|
|
193
|
+
// Every validation is logged with inputHash, outputHash, decision, confidence
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Input Types
|
|
199
|
+
|
|
200
|
+
All monetary amounts are in **cents** (integer).
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
// Deposit validation
|
|
204
|
+
{ type: "deposit-validation", depositAmountCents, monthlyRentCents, currency, ... }
|
|
205
|
+
|
|
206
|
+
// Payment compliance
|
|
207
|
+
{ type: "payment-compliance", paymentAmountCents, monthlyRentCents, dueDate, paymentDate, ... }
|
|
208
|
+
|
|
209
|
+
// Rent increase
|
|
210
|
+
{ type: "rent-increase-validation", currentRentCents, proposedRentCents, noticeDateDays, ... }
|
|
211
|
+
|
|
212
|
+
// Deposit return
|
|
213
|
+
{ type: "deposit-return", originalDepositCents, proposedReturnCents, leaseEndDate, returnDate, ... }
|
|
214
|
+
|
|
215
|
+
// Homeownership readiness
|
|
216
|
+
{ type: "homeownership-readiness", annualIncomeCents, monthlyDebtCents, creditScore, ... }
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Publishing (Maintainers)
|
|
222
|
+
|
|
223
|
+
The CI/CD pipeline automatically publishes to npm when a commit on `main` starts with `release:`.
|
|
224
|
+
|
|
225
|
+
### Steps
|
|
226
|
+
|
|
227
|
+
1. Bump version in [package.json](./package.json)
|
|
228
|
+
2. Run prepublish gate locally:
|
|
229
|
+
```bash
|
|
230
|
+
npm run prepublishOnly # lint + test (146 tests) + build
|
|
231
|
+
```
|
|
232
|
+
3. Commit and push:
|
|
233
|
+
```bash
|
|
234
|
+
git add packages/huddle-skills/
|
|
235
|
+
git commit -m "release: v0.2.0"
|
|
236
|
+
git push origin main
|
|
237
|
+
```
|
|
238
|
+
4. GitHub Actions triggers `.github/workflows/huddle-skills-ci.yml`:
|
|
239
|
+
- `test` job: lint → 146 tests → build → verify dist
|
|
240
|
+
- `publish` job (only on `release:` prefix + `NPM_TOKEN` secret): `npm publish --access public`
|
|
241
|
+
|
|
242
|
+
### Required GitHub Secret
|
|
243
|
+
|
|
244
|
+
`NPM_TOKEN` — create at [npmjs.com/settings/tokens](https://www.npmjs.com/settings/tokens) (Automation token, read+write), add to repo secrets at Settings → Secrets → Actions.
|
|
245
|
+
|
|
246
|
+
### Package Size Budget
|
|
247
|
+
|
|
248
|
+
Target: < 500KB, tree-shakeable per jurisdiction via named exports.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## License
|
|
253
|
+
|
|
254
|
+
MIT — see [LICENSE](./LICENSE)
|
|
255
|
+
|
|
256
|
+
Built by [Huddle Protocol](https://github.com/huddle-protocol)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Adapter
|
|
3
|
+
*
|
|
4
|
+
* Wraps Huddle skills in OpenClaw-compatible format.
|
|
5
|
+
* Each skill becomes an OpenClaw skill with SKILL.md metadata.
|
|
6
|
+
*/
|
|
7
|
+
import type { HuddleSkill, SkillResult, SkillMetadata } from "../types/index.js";
|
|
8
|
+
/** OpenClaw skill manifest (SKILL.md frontmatter) */
|
|
9
|
+
export interface OpenClawManifest {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
description: string;
|
|
13
|
+
author: string;
|
|
14
|
+
capabilities: string[];
|
|
15
|
+
inputs: {
|
|
16
|
+
schema: string;
|
|
17
|
+
};
|
|
18
|
+
outputs: {
|
|
19
|
+
schema: string;
|
|
20
|
+
};
|
|
21
|
+
permissions: string[];
|
|
22
|
+
tags: string[];
|
|
23
|
+
}
|
|
24
|
+
/** OpenClaw-compatible skill wrapper */
|
|
25
|
+
export interface OpenClawSkill {
|
|
26
|
+
manifest: OpenClawManifest;
|
|
27
|
+
execute(input: Record<string, unknown>): Promise<SkillResult>;
|
|
28
|
+
metadata(): SkillMetadata;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Convert a HuddleSkill to an OpenClaw-compatible skill
|
|
32
|
+
*/
|
|
33
|
+
export declare function toOpenClawSkill(skill: HuddleSkill): OpenClawSkill;
|
|
34
|
+
/**
|
|
35
|
+
* Convert all skills to OpenClaw format
|
|
36
|
+
*/
|
|
37
|
+
export declare function toOpenClawSkills(skills: HuddleSkill[]): OpenClawSkill[];
|
|
38
|
+
/**
|
|
39
|
+
* Generate SKILL.md content for a skill (YAML frontmatter + markdown body)
|
|
40
|
+
*/
|
|
41
|
+
export declare function generateSkillMd(skill: HuddleSkill): string;
|
|
42
|
+
//# sourceMappingURL=openclaw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE7F,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,QAAQ,IAAI,aAAa,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAwBjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,aAAa,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAsD1D"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClaw Adapter
|
|
3
|
+
*
|
|
4
|
+
* Wraps Huddle skills in OpenClaw-compatible format.
|
|
5
|
+
* Each skill becomes an OpenClaw skill with SKILL.md metadata.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Convert a HuddleSkill to an OpenClaw-compatible skill
|
|
9
|
+
*/
|
|
10
|
+
export function toOpenClawSkill(skill) {
|
|
11
|
+
const meta = skill.getMetadata();
|
|
12
|
+
return {
|
|
13
|
+
manifest: {
|
|
14
|
+
name: meta.id,
|
|
15
|
+
version: meta.version,
|
|
16
|
+
description: meta.description,
|
|
17
|
+
author: meta.author,
|
|
18
|
+
capabilities: meta.capabilities,
|
|
19
|
+
inputs: { schema: "./schemas/input.json" },
|
|
20
|
+
outputs: { schema: "./schemas/output.json" },
|
|
21
|
+
permissions: meta.permissions,
|
|
22
|
+
tags: meta.tags,
|
|
23
|
+
},
|
|
24
|
+
async execute(input) {
|
|
25
|
+
return skill.validate(input);
|
|
26
|
+
},
|
|
27
|
+
metadata() {
|
|
28
|
+
return skill.getMetadata();
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert all skills to OpenClaw format
|
|
34
|
+
*/
|
|
35
|
+
export function toOpenClawSkills(skills) {
|
|
36
|
+
return skills.map(toOpenClawSkill);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate SKILL.md content for a skill (YAML frontmatter + markdown body)
|
|
40
|
+
*/
|
|
41
|
+
export function generateSkillMd(skill) {
|
|
42
|
+
const meta = skill.getMetadata();
|
|
43
|
+
const yaml = [
|
|
44
|
+
"---",
|
|
45
|
+
`name: ${meta.id}`,
|
|
46
|
+
`version: ${meta.version}`,
|
|
47
|
+
`description: ${meta.description}`,
|
|
48
|
+
`author: ${meta.author}`,
|
|
49
|
+
`jurisdiction: ${meta.jurisdiction}`,
|
|
50
|
+
`capabilities: [${meta.capabilities.join(", ")}]`,
|
|
51
|
+
`permissions: [${meta.permissions.join(", ")}]`,
|
|
52
|
+
`tags: [${meta.tags.join(", ")}]`,
|
|
53
|
+
meta.federalPreemption ? `federal_preemption: true` : null,
|
|
54
|
+
meta.effectiveDate ? `effective_date: ${meta.effectiveDate}` : null,
|
|
55
|
+
"---",
|
|
56
|
+
].filter(Boolean).join("\n");
|
|
57
|
+
const body = [
|
|
58
|
+
"",
|
|
59
|
+
`# ${meta.name}`,
|
|
60
|
+
"",
|
|
61
|
+
`## Jurisdiction: ${meta.jurisdiction}`,
|
|
62
|
+
"",
|
|
63
|
+
meta.description,
|
|
64
|
+
"",
|
|
65
|
+
"## Capabilities",
|
|
66
|
+
"",
|
|
67
|
+
...meta.capabilities.map((c) => `- ${c}`),
|
|
68
|
+
"",
|
|
69
|
+
"## Usage",
|
|
70
|
+
"",
|
|
71
|
+
"```typescript",
|
|
72
|
+
`import { registry } from "@huddle-marketplace/skills";`,
|
|
73
|
+
"",
|
|
74
|
+
`const skill = registry.get("${meta.jurisdiction}");`,
|
|
75
|
+
`const result = await skill.validate({`,
|
|
76
|
+
` type: "deposit-validation",`,
|
|
77
|
+
` depositAmountCents: 150000,`,
|
|
78
|
+
` monthlyRentCents: 200000,`,
|
|
79
|
+
` currency: "USD",`,
|
|
80
|
+
`});`,
|
|
81
|
+
"",
|
|
82
|
+
`console.log(result.compliant); // true/false`,
|
|
83
|
+
`console.log(skill.explain(result)); // human-readable explanation`,
|
|
84
|
+
"```",
|
|
85
|
+
"",
|
|
86
|
+
"## Permissions",
|
|
87
|
+
"",
|
|
88
|
+
"This skill requires **no network access** and **no filesystem access**.",
|
|
89
|
+
"It is a pure computation skill that evaluates inputs against legal rules.",
|
|
90
|
+
"",
|
|
91
|
+
].join("\n");
|
|
92
|
+
return yaml + body;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=openclaw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEjC,OAAO;QACL,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,EAAE;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,MAAM,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE;YAC1C,OAAO,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE;YAC5C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QAED,KAAK,CAAC,OAAO,CAAC,KAA8B;YAC1C,OAAO,KAAK,CAAC,QAAQ,CAAC,KAA8B,CAAC,CAAC;QACxD,CAAC;QAED,QAAQ;YACN,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IACpD,OAAO,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG;QACX,KAAK;QACL,SAAS,IAAI,CAAC,EAAE,EAAE;QAClB,YAAY,IAAI,CAAC,OAAO,EAAE;QAC1B,gBAAgB,IAAI,CAAC,WAAW,EAAE;QAClC,WAAW,IAAI,CAAC,MAAM,EAAE;QACxB,iBAAiB,IAAI,CAAC,YAAY,EAAE;QACpC,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACjD,iBAAiB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/C,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACjC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI;QAC1D,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI;QACnE,KAAK;KACN,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE7B,MAAM,IAAI,GAAG;QACX,EAAE;QACF,KAAK,IAAI,CAAC,IAAI,EAAE;QAChB,EAAE;QACF,oBAAoB,IAAI,CAAC,YAAY,EAAE;QACvC,EAAE;QACF,IAAI,CAAC,WAAW;QAChB,EAAE;QACF,iBAAiB;QACjB,EAAE;QACF,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,EAAE;QACF,UAAU;QACV,EAAE;QACF,eAAe;QACf,wDAAwD;QACxD,EAAE;QACF,+BAA+B,IAAI,CAAC,YAAY,KAAK;QACrD,uCAAuC;QACvC,+BAA+B;QAC/B,+BAA+B;QAC/B,6BAA6B;QAC7B,oBAAoB;QACpB,KAAK;QACL,EAAE;QACF,8CAA8C;QAC9C,mEAAmE;QACnE,KAAK;QACL,EAAE;QACF,gBAAgB;QAChB,EAAE;QACF,yEAAyE;QACzE,2EAA2E;QAC3E,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,IAAI,GAAG,IAAI,CAAC;AACrB,CAAC"}
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseSkill — Abstract base class for all Huddle compliance skills.
|
|
3
|
+
*
|
|
4
|
+
* Provides default implementations for explain() and remediate(),
|
|
5
|
+
* so jurisdiction skills only need to implement validate().
|
|
6
|
+
*/
|
|
7
|
+
import type { HuddleSkill, SkillInput, SkillResult, SkillMetadata, SkillCapability, JurisdictionCode, RemediationStep, SkillCheck } from "./types/index.js";
|
|
8
|
+
export declare abstract class BaseSkill implements HuddleSkill {
|
|
9
|
+
abstract readonly id: string;
|
|
10
|
+
abstract readonly name: string;
|
|
11
|
+
abstract readonly jurisdiction: JurisdictionCode;
|
|
12
|
+
abstract readonly version: string;
|
|
13
|
+
abstract readonly capabilities: SkillCapability[];
|
|
14
|
+
/** Subclasses implement this to run jurisdiction-specific rules */
|
|
15
|
+
abstract validate(input: SkillInput): Promise<SkillResult>;
|
|
16
|
+
/** Default explainability: build a human-readable summary from checks */
|
|
17
|
+
explain(result: SkillResult): string;
|
|
18
|
+
/** Default remediation: generate steps for each failed check */
|
|
19
|
+
remediate(result: SkillResult): RemediationStep[];
|
|
20
|
+
/** Convert a failed check into a remediation step. Override for custom logic. */
|
|
21
|
+
protected checkToRemediation(check: SkillCheck): RemediationStep;
|
|
22
|
+
/** Build a SkillResult from individual checks */
|
|
23
|
+
protected buildResult(checks: SkillCheck[], input: SkillInput): SkillResult;
|
|
24
|
+
getMetadata(): SkillMetadata;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=base.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACX,MAAM,kBAAkB,CAAC;AAE1B,8BAAsB,SAAU,YAAW,WAAW;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE,CAAC;IAElD,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAE1D,yEAAyE;IACzE,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IA4BpC,gEAAgE;IAChE,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,EAAE;IAMjD,iFAAiF;IACjF,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe;IAShE,iDAAiD;IACjD,SAAS,CAAC,WAAW,CACnB,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,EAAE,UAAU,GAChB,WAAW;IAmCd,WAAW,IAAI,aAAa;CAiB7B"}
|
package/dist/base.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseSkill — Abstract base class for all Huddle compliance skills.
|
|
3
|
+
*
|
|
4
|
+
* Provides default implementations for explain() and remediate(),
|
|
5
|
+
* so jurisdiction skills only need to implement validate().
|
|
6
|
+
*/
|
|
7
|
+
export class BaseSkill {
|
|
8
|
+
/** Default explainability: build a human-readable summary from checks */
|
|
9
|
+
explain(result) {
|
|
10
|
+
const status = result.compliant ? "PASSES" : "FAILS";
|
|
11
|
+
const failedChecks = result.checks.filter((c) => !c.passed);
|
|
12
|
+
const passedChecks = result.checks.filter((c) => c.passed);
|
|
13
|
+
let explanation = `This transaction ${status} ${this.name} compliance (confidence: ${(result.confidence * 100).toFixed(0)}%).\n\n`;
|
|
14
|
+
if (failedChecks.length > 0) {
|
|
15
|
+
explanation += "Failed checks:\n";
|
|
16
|
+
for (const check of failedChecks) {
|
|
17
|
+
explanation += ` - ${check.name}: ${check.note}`;
|
|
18
|
+
if (check.citation) {
|
|
19
|
+
explanation += ` (${check.citation.statute} ${check.citation.section})`;
|
|
20
|
+
}
|
|
21
|
+
explanation += "\n";
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (passedChecks.length > 0) {
|
|
25
|
+
explanation += "\nPassed checks:\n";
|
|
26
|
+
for (const check of passedChecks) {
|
|
27
|
+
explanation += ` - ${check.name}: ${check.note}\n`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return explanation;
|
|
31
|
+
}
|
|
32
|
+
/** Default remediation: generate steps for each failed check */
|
|
33
|
+
remediate(result) {
|
|
34
|
+
return result.checks
|
|
35
|
+
.filter((c) => !c.passed)
|
|
36
|
+
.map((check) => this.checkToRemediation(check));
|
|
37
|
+
}
|
|
38
|
+
/** Convert a failed check into a remediation step. Override for custom logic. */
|
|
39
|
+
checkToRemediation(check) {
|
|
40
|
+
return {
|
|
41
|
+
action: `fix_${check.name.toLowerCase().replace(/\s+/g, "_")}`,
|
|
42
|
+
description: `Address failed check: ${check.note}`,
|
|
43
|
+
urgency: "required",
|
|
44
|
+
automatable: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/** Build a SkillResult from individual checks */
|
|
48
|
+
buildResult(checks, input) {
|
|
49
|
+
const compliant = checks.every((c) => c.passed);
|
|
50
|
+
const confidence = checks.length > 0
|
|
51
|
+
? Math.min(...checks.map((c) => c.confidence))
|
|
52
|
+
: 0;
|
|
53
|
+
const citations = checks
|
|
54
|
+
.filter((c) => c.citation)
|
|
55
|
+
.map((c) => c.citation);
|
|
56
|
+
const remediation = compliant ? undefined : this.remediate({
|
|
57
|
+
compliant,
|
|
58
|
+
confidence,
|
|
59
|
+
jurisdiction: this.jurisdiction,
|
|
60
|
+
skillId: this.id,
|
|
61
|
+
skillVersion: this.version,
|
|
62
|
+
checks,
|
|
63
|
+
timestamp: Date.now(),
|
|
64
|
+
citations,
|
|
65
|
+
});
|
|
66
|
+
return {
|
|
67
|
+
compliant,
|
|
68
|
+
confidence,
|
|
69
|
+
jurisdiction: this.jurisdiction,
|
|
70
|
+
skillId: this.id,
|
|
71
|
+
skillVersion: this.version,
|
|
72
|
+
checks,
|
|
73
|
+
explanation: undefined, // Filled by caller if needed
|
|
74
|
+
remediation,
|
|
75
|
+
citations: citations.length > 0 ? citations : undefined,
|
|
76
|
+
timestamp: Date.now(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
getMetadata() {
|
|
80
|
+
return {
|
|
81
|
+
id: this.id,
|
|
82
|
+
name: this.name,
|
|
83
|
+
description: `${this.name} compliance skill for ${this.jurisdiction}`,
|
|
84
|
+
jurisdiction: this.jurisdiction,
|
|
85
|
+
version: this.version,
|
|
86
|
+
capabilities: this.capabilities,
|
|
87
|
+
permissions: ["network:none", "filesystem:none"],
|
|
88
|
+
tags: [
|
|
89
|
+
"rental",
|
|
90
|
+
"compliance",
|
|
91
|
+
this.jurisdiction.toLowerCase(),
|
|
92
|
+
],
|
|
93
|
+
author: "huddle-protocol",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=base.js.map
|
package/dist/base.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @huddle-marketplace/skills — Composition Engine
|
|
3
|
+
*
|
|
4
|
+
* Stack multiple jurisdiction skills for layered validation.
|
|
5
|
+
*
|
|
6
|
+
* Typical patterns:
|
|
7
|
+
* Federal + State: composeSkills(["US-CFTC", "US-TX"], input, registry)
|
|
8
|
+
* Multi-state: composeSkills(["US-CA", "US-NY"], input, registry)
|
|
9
|
+
* Cross-border: composeSkills(["US-CFTC", "CA-FINTRAC", "CA-ON"], input, registry)
|
|
10
|
+
*
|
|
11
|
+
* Architecture:
|
|
12
|
+
* - Layers run in PARALLEL (Promise.all) — O(1) latency regardless of layer count
|
|
13
|
+
* - Federal checks first in output by convention (pass them first in the array)
|
|
14
|
+
* - Each check is prefixed with its source jurisdiction for full traceability
|
|
15
|
+
* - Citations are deduplicated by statute+section across layers
|
|
16
|
+
* - compliant = ALL layers compliant (strict mode, default)
|
|
17
|
+
*
|
|
18
|
+
* Web3-native: When US-CFTC is composed with a state skill, the federal layer validates
|
|
19
|
+
* bond structure (wBTC reserve ratio, non-custodial architecture, TRAIGA logging).
|
|
20
|
+
* The state layer adds local statutory rules (deposit cap, return timeline, late fee limits).
|
|
21
|
+
* Together they form a complete, TRAIGA-ready compliance proof for any Huddle transaction.
|
|
22
|
+
*/
|
|
23
|
+
import type { SkillInput, SkillResult, SkillCheck, LegalCitation, RemediationStep, JurisdictionCode } from "./types/index.js";
|
|
24
|
+
/**
|
|
25
|
+
* The merged result of running multiple jurisdiction skills in sequence.
|
|
26
|
+
* Each layer's result is preserved in `layers[]` for full TRAIGA auditability.
|
|
27
|
+
*/
|
|
28
|
+
export interface ComposedResult {
|
|
29
|
+
/** true only when ALL jurisdiction layers are compliant (strict mode) */
|
|
30
|
+
compliant: boolean;
|
|
31
|
+
/** Minimum confidence across all layers — the weakest link determines overall confidence */
|
|
32
|
+
confidence: number;
|
|
33
|
+
/** Jurisdiction codes validated, in the order provided */
|
|
34
|
+
jurisdictions: string[];
|
|
35
|
+
/** Individual SkillResult per jurisdiction — full detail for TRAIGA logging */
|
|
36
|
+
layers: SkillResult[];
|
|
37
|
+
/** All checks from all layers, prefixed with source jurisdiction for traceability */
|
|
38
|
+
checks: SkillCheck[];
|
|
39
|
+
/** All citations merged and deduplicated by statute+section */
|
|
40
|
+
citations: LegalCitation[];
|
|
41
|
+
/** All remediation steps from all layers, consolidated */
|
|
42
|
+
remediation: RemediationStep[];
|
|
43
|
+
/** Unix timestamp (ms) when composition completed */
|
|
44
|
+
timestamp: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Minimal registry interface — avoids circular import from index.ts.
|
|
48
|
+
* The full SkillRegistry satisfies this interface automatically.
|
|
49
|
+
*/
|
|
50
|
+
export interface MinimalRegistry {
|
|
51
|
+
get(jurisdiction: JurisdictionCode): {
|
|
52
|
+
validate(input: SkillInput): Promise<SkillResult>;
|
|
53
|
+
} | undefined;
|
|
54
|
+
}
|
|
55
|
+
export interface ComposeOptions {
|
|
56
|
+
/**
|
|
57
|
+
* "strict" (default): ALL layers must be compliant for `compliant: true`.
|
|
58
|
+
* Use for production validation where every layer must pass.
|
|
59
|
+
*
|
|
60
|
+
* "advisory": only layers listed in `criticalJurisdictions` affect `compliant`.
|
|
61
|
+
* Use when some layers are informational overlays.
|
|
62
|
+
*/
|
|
63
|
+
mode?: "strict" | "advisory";
|
|
64
|
+
/**
|
|
65
|
+
* In "advisory" mode: only these jurisdictions determine `compliant`.
|
|
66
|
+
* Defaults to all jurisdictions when not provided (equivalent to strict mode).
|
|
67
|
+
*/
|
|
68
|
+
criticalJurisdictions?: string[];
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Compose multiple jurisdiction skills into a single layered validation result.
|
|
72
|
+
*
|
|
73
|
+
* Designed for Web3-native use: the federal CFTC layer validates the bond structure,
|
|
74
|
+
* the state layer validates local statutory rules — together they form a complete
|
|
75
|
+
* compliance proof anchored on-chain via TRAIGA.
|
|
76
|
+
*
|
|
77
|
+
* NOTE: This is the low-level function that requires an explicit registry.
|
|
78
|
+
* Use the `composeSkills()` export from the main package entry which uses the
|
|
79
|
+
* default registry automatically.
|
|
80
|
+
*
|
|
81
|
+
* @param jurisdictions - Ordered list of jurisdiction codes (federal first by convention)
|
|
82
|
+
* @param input - Skill input shared across all layers (amounts in CENTS)
|
|
83
|
+
* @param registry - Registry instance to resolve skills from
|
|
84
|
+
* @param options - Composition options
|
|
85
|
+
*/
|
|
86
|
+
export declare function composeSkillsWithRegistry(jurisdictions: (JurisdictionCode | string)[], input: SkillInput, registry: MinimalRegistry, options?: ComposeOptions): Promise<ComposedResult>;
|
|
87
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IAEnB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,CAAC;IAEnB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,+EAA+E;IAC/E,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB,qFAAqF;IACrF,MAAM,EAAE,UAAU,EAAE,CAAC;IAErB,+DAA+D;IAC/D,SAAS,EAAE,aAAa,EAAE,CAAC;IAE3B,0DAA0D;IAC1D,WAAW,EAAE,eAAe,EAAE,CAAC;IAE/B,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,YAAY,EAAE,gBAAgB,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;KAAE,GAAG,SAAS,CAAC;CACxG;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAE7B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,CAAC,gBAAgB,GAAG,MAAM,CAAC,EAAE,EAC5C,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,eAAe,EACzB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAsFzB"}
|