From 971a297db37b1ef0d90ca1d0a435e99a31e01d30 Mon Sep 17 00:00:00 2001 From: Florian BRUNIAUX Date: Wed, 11 Feb 2026 16:12:36 +0100 Subject: [PATCH] feat(security): add threat intelligence DB, security commands, and cheatsheet audit fixes (v3.26.0) - Add threat-db.yaml v2.0.0 with 63 malicious skills, 22 CVEs, 4 campaigns - Add /security-check, /security-audit, /update-threat-db slash commands - Add Snyk ToxicSkills evaluation (58th resource evaluation) - Fix cheatsheet: add Alt+T to keyboard shortcuts table, add /fast and /debug commands - Update Features Meconnues table with Agent Teams and Auto-Memories - Clean up cheatsheet.md.bak - Bump version to 3.26.0 Co-Authored-By: Claude Sonnet 4.5 --- CHANGELOG.md | 62 ++- CLAUDE.md | 6 + README.md | 11 +- VERSION | 2 +- cheatsheet.pdf | Bin 165651 -> 164342 bytes docs/resource-evaluations/README.md | 3 +- .../snyk-toxicskills-evaluation.md | 73 +++ examples/commands/security-audit.md | 243 +++++++++ examples/commands/security-check.md | 172 +++++++ examples/commands/update-threat-db.md | 164 ++++++ guide/cheatsheet.md | 13 +- guide/ultimate-guide.md | 6 +- machine-readable/reference.yaml | 26 +- tools/audit-cheatsheet-prompt.md | 474 ++++++++++++++++++ 14 files changed, 1209 insertions(+), 46 deletions(-) create mode 100644 docs/resource-evaluations/snyk-toxicskills-evaluation.md create mode 100644 examples/commands/security-audit.md create mode 100644 examples/commands/security-check.md create mode 100644 examples/commands/update-threat-db.md create mode 100644 tools/audit-cheatsheet-prompt.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4dbd028..539aa7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,41 +8,55 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [3.26.0] - 2026-02-11 + ### Added +- **Security Threat Intelligence Database** (`examples/commands/resources/threat-db.yaml` v2.0.0) + - Comprehensive threat DB compiled from Perplexity Deep Research across 15 sources + - **63 malicious skills** catalogued (ClawHavoc 341 skills, Snyk ToxicSkills, PyPI supply chain) + - **22 CVEs** tracked with component, severity, fixed_in version, and mitigation + - **4 campaigns** documented: ClawHavoc (AMOS), ToxicSkills, PyPI MCP reverse shell, Postmark npm squatter + - **IOCs**: 6 C2 IPs, exfiltration endpoints, malicious GitHub repos, malware hashes + - **17 malicious skill patterns** for wildcard matching (prefix-based scanning) + - **10 minimum safe versions** quick reference for MCP servers + - **8 attack techniques** taxonomy (T001-T008) mapped to campaigns + - **6 scanning tools** documented (mcp-scan, skills-ref, Garak, MCP Fortress, SafeDep vet, Koi Clawdex) + - **5 defensive resources** (SAFE-MCP framework, VirusTotal integration, Docker MCP Gateway, Snyk AI-BOM, Bitsight TRACE) + - Sources: Koi Security, Snyk, JFrog, Flatt Security, SentinelOne, Cymulate, Checkpoint, Bitsight, SafeDep, SAFE-MCP + +- **New Slash Command**: `/security-check` (`examples/commands/security-check.md`) + - Quick (~30s) configuration security check against known threats database + - 7 phases: Load threat DB → MCP audit → Skills/agents audit → Hook security → Memory poisoning → Permissions → Exposed secrets + - Outputs CRITICAL/HIGH/MEDIUM/LOW findings with exact fix commands + +- **New Slash Command**: `/security-audit` (`examples/commands/security-audit.md`) + - Full 6-phase security audit with scored posture assessment (/100, grades A-F) + - Phases: Config (via /security-check) → Secrets scan → Injection surface → Dependencies → Hook security → Posture score + - Includes benchmark against security-hardening.md recommendations + +- **New Slash Command**: `/update-threat-db` (`examples/commands/update-threat-db.md`) + - Research & update the threat intelligence database via Perplexity searches + - 6 phases: Assess current state → 4 targeted searches → Deduplicate → Update YAML → Cascade to guides → Summary report + - Designed for monthly maintenance or post-advisory updates + +- **Threat DB Badge** in README: red badge linking to security-hardening.md showing CVE and malicious skill counts + - **Resource Evaluation**: "AI Fatigue is Real" by Siddhant Khare (`docs/resource-evaluations/siddhant-khare-ai-fatigue.md`) - - Evaluated blog post on AI-induced exhaustion and productivity paradoxes - - Score: 3/5 (Pertinent — complément utile) - - 90% content overlap with existing `learning-with-ai.md`, but identified session time-boxing gap - - Technical-writer challenge downgraded from initial 4/5 to 3/5 - - Fact-check confirmed: 0 research citations (anecdotal only) vs guide's peer-reviewed RCTs - - Extracted: Time-boxing tactics (30 min limit, 3 attempts max), nondeterminism stress recognition + - Score: 3/5 — Time-boxing tactics, nondeterminism stress recognition ### Changed +- **README**: Commands count updated 18→22, 3 new security commands listed in examples library +- **CLAUDE.md**: Slash commands table updated with `/security-check`, `/security-audit`, `/update-threat-db` +- **reference.yaml**: 4 new entries (security_check_command, security_audit_command, security_threat_db, security_update_threat_db) - **Learning Guide Enhancement**: AI fatigue symptom recognition integrated into `guide/learning-with-ai.md` - - **Red Flags Checklist** (line 869): Added "Prolonged sessions without breaks" with time-boxing mitigation (30 min limit, max 3 attempts before manual implementation) - - **Productivity Reality** (line 115): Added paragraph on nondeterminism stress (identical prompts → varying outputs causes "AI fatigue") - - **UVAL Protocol** (line 247): Added "Step 2.5: Recognize Fatigue Signals" checkpoint (session duration, retry count, frustration assessment) - - **Total footprint**: ~200 words across 3 locations (minimal integration) - - **Rationale**: Addresses session-level time-boxing gap (distinct from existing weekly 70/30 split) + - Red Flags Checklist, Productivity Reality, UVAL Protocol sections updated ### Fixed - **Extended Thinking Documentation**: Corrected `effort` parameter documentation based on [official Anthropic docs](https://platform.claude.com/docs/en/build-with-claude/effort) - - **API Syntax** (line 10408-10416): `thinking={"type": "adaptive", "effort": "high"}` → `output_config={"effort": "medium"}` (correct parameter name) - - **Scope Clarification** (line 10398-10400): `effort` controls **entire response** (text, tool calls, thinking), not just thinking tokens - - **Official Descriptions** (line 10402-10406): Replaced generic descriptions with official Anthropic definitions - - `max`: Maximum capability, no constraints (Opus 4.6 only — errors on other models) - - `high`: Complex reasoning, coding, agentic tasks (default) - - `medium`: Balance speed/cost/performance - - `low`: Most efficient for classification, lookups, sub-agents - - **Control Table** (line 10441): Opus 4.5 supports `low|medium|high`, Opus 4.6 adds `max` - - **New Subsection**: "Effort and Tool Use" (line 10418-10425) — explains impact on tool call behavior - - **Relationship Clarification** (line 10427-10431): - - Opus 4.6: `effort` recommended, `budget_tokens` deprecated - - Opus 4.5: both `effort` and `budget_tokens` work in parallel - - Without thinking: `effort` still controls text + tools + - API syntax, scope clarification, official descriptions, control table, effort and tool use subsection ## [3.25.0] - 2026-02-10 diff --git a/CLAUDE.md b/CLAUDE.md index 937f151..de9f160 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -83,6 +83,9 @@ Custom slash commands available in this project: | `/changelog [count]` | View recent CHANGELOG entries (default: 5) | | `/sync` | Check guide/landing synchronization status | | `/audit-agents-skills [path]` | Audit quality of agents, skills, and commands in .claude/ config | +| `/security-check` | Quick config check against known threats database (~30s) | +| `/security-audit` | Full 6-phase security audit with score /100 (2-5min) | +| `/update-threat-db` | Research & update threat intelligence database | **Examples:** ``` @@ -97,6 +100,9 @@ Custom slash commands available in this project: /audit-agents-skills # Audit current project /audit-agents-skills --fix # Audit + fix suggestions /audit-agents-skills ~/other # Audit another project +/security-check # Quick scan config vs known threats +/security-audit # Full audit with posture score /100 +/update-threat-db # Research + update threat-db.yaml ``` These commands are defined in `.claude/commands/` and automate: diff --git a/README.md b/README.md index c0ff9f6..2c6572e 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,10 @@

Stars - Last Update + Last Update Quiz Templates + Threat Database

@@ -99,7 +100,7 @@ graph LR │ ├─ 📋 examples/ 111 Production Templates │ ├─ agents/ 6 custom AI personas -│ ├─ commands/ 18 slash commands +│ ├─ commands/ 22 slash commands │ ├─ hooks/ 18 security hooks (bash + PowerShell) │ ├─ skills/ 1 meta-skill (Claudeception) │ └─ scripts/ Utility scripts (audit, search) @@ -167,7 +168,7 @@ Complete guides with rationale and examples: ### 📚 106 Annotated Templates Educational templates with explanations: -- Agents (6), Commands (18), Hooks (18), Skills +- Agents (6), Commands (22), Hooks (18), Skills - Comments explaining **why** each pattern works - Gradual complexity progression @@ -406,7 +407,7 @@ Claude Code sends your prompts, file contents, and MCP results to Anthropic serv **Agents** (6): [code-reviewer](./examples/agents/code-reviewer.md), [test-writer](./examples/agents/test-writer.md), [security-auditor](./examples/agents/security-auditor.md), [refactoring-specialist](./examples/agents/refactoring-specialist.md), [output-evaluator](./examples/agents/output-evaluator.md), [devops-sre](./examples/agents/devops-sre.md) ⭐ -**Slash Commands** (18): [/pr](./examples/commands/pr.md), [/commit](./examples/commands/commit.md), [/release-notes](./examples/commands/release-notes.md), [/diagnose](./examples/commands/diagnose.md), [/security](./examples/commands/security.md), [/refactor](./examples/commands/refactor.md), [/explain](./examples/commands/explain.md), [/optimize](./examples/commands/optimize.md), [/ship](./examples/commands/ship.md)... +**Slash Commands** (22): [/pr](./examples/commands/pr.md), [/commit](./examples/commands/commit.md), [/release-notes](./examples/commands/release-notes.md), [/diagnose](./examples/commands/diagnose.md), [/security](./examples/commands/security.md), [/security-check](./examples/commands/security-check.md) **, [/security-audit](./examples/commands/security-audit.md) **, [/update-threat-db](./examples/commands/update-threat-db.md) **, [/refactor](./examples/commands/refactor.md), [/explain](./examples/commands/explain.md), [/optimize](./examples/commands/optimize.md), [/ship](./examples/commands/ship.md)... **Security Hooks** (18): [dangerous-actions-blocker](./examples/hooks/bash/dangerous-actions-blocker.sh), [prompt-injection-detector](./examples/hooks/bash/prompt-injection-detector.sh), [unicode-injection-scanner](./examples/hooks/bash/unicode-injection-scanner.sh), [output-secrets-scanner](./examples/hooks/bash/output-secrets-scanner.sh)... @@ -510,7 +511,7 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines. --- -*Version 3.24.0 | Updated daily · Feb 10, 2026 | Crafted with Claude* +*Version 3.26.0 | Updated daily · Feb 11, 2026 | Crafted with Claude* cf7e^BYO^rK>2SxtZJ!(xYjw8Y$z?^L2^ribn>sn6C7@PThCbwO?OyKR;ULfI0pp8j`)M z#-dP%vU0X-)D6U|XLX>~wrd;bErl+1asDd)7&Sjde#v@Rna>5l>3$@YHb#DA=IZYJlfqfM%B54p3}OuRRGi$9 zzTsA^;^`EGH#8f|J|dIKz65#9`QVRT_E={H&l8}Q8*z}W(er5bL5%8UjwwOg;^YfE zo3Xs6p>AVttiUCb-8kaRkIK=Q5PDPMs6{0*2v?6;G7AbUmFQL>!%=U4cKq|*iV`!y z(MsFSamZ0UoIpxoj*D|~D6^!sTKu_ry|dpZg(s^)``aUf4zBH$EFdApW>VjN-r`za zuPe-AqQYBFJm;PA!kdn+_w)5kc^$(Yq%w_jF8fd~v_0V~ zXQu^&q$(f-G35pk@vihOH?Zof`x&wJQ1+_%ESyoM6!hrIDRj@a}E}uIHBxXe0R;1xXnhfH2GwRTl2a>LSZ`XO9mn z(f2v>M1z0WrZFZEjjng$} zC`AYt6gSLiEhv~nMgtyiA?`I!xj{WG-WRx&>Ky05IG>Pz zW}-mDb%QI`0Ucrw(5H~!d_PfFV?L1atggi`6S#i1gyiOM^MpI@bZny{d zlDW3HQO!GWCwJgF)&J>8{5z^4+1xfa=o}^Gor=2A7uJMgrTB?-eeIVhUpw#H>#Pq& zI@NOIKE+ID+Y_l^%3CgLY!;#Ybi4HzYXt3@VAn`}F`#rOe47`7EDX^qnwgEq&Bsqe zZ1_Y}wDfB9mvMk<{K36CHoVxSj$^&-=Y-pqH#*#gt6qo^pE9GKQo3q#>l8igx-iJrmA}Cteh?d8Tl^R-NTy7t;GBGkij` zHQ~ZDCe~?gA&QWfQ2@l7RPnw~O@J37;yDf$A>MgX&uImH*Qwv~urJW*X7xidr|ysK z2s@6%mkRqIZ$x*U4Z~Sn3Gtq=TaLo(Yf4E|2EfG{PMBlhaN+zsjcn&b?WX$Qkc1v` zdS%iIFP!b1@20|s(r%;tR|hhsjouSS0UT`8&mIv9YkF(m@|wa{?zj8cgS>=xgz3|& z@QsN5xRlH3o=2~$N$2!58^4vA)neGpqZ>ttZ;9%^waSc0sYjpFO%;E8^4r=f%=MMrBh4yM74;$f0 zaufP#4Q8nySc~nE{W*0~QUPB9s&Lj2{1Lg!=_X^tj`YXcS4U;*Uy5hQrcGJl>_XivA^Fha$u5tT-nf-S zl2G^YCVIrB!knSCtCiJEQQqYmHJ* zag~k?k$EG<7YWwDol_)GHBvdp0{z07W7-hNgs48!hn+%0hs~}t)wkHz-S(==A(KTy zG{vz%>Onb{gg))QOB$9nY}Y}Jw|x7cQGg#lev<5NCX0DbuYpFuJY;u3pQ>tK1q1{> zkIMI?HMg0fK;stbxt?uiE>|G~9>2O~eQ8)F!~0-|UOCPOuo1??)Ug#Fw?xve?~qij>a znNPse<(|*$`mQX%@RUv<25(=QS0HQl>RNyE8SFKBm2xIdMtEJy%et}iNW6RB;Htvp zik>R^e6mqh0AHHcdK3*&5Mn|4cgS*i3d<3PxAs~-cTqfTlFq~I%kTmQ!&(?MhHs`X z$7|ijn_BDhlyk+G=31>}T1vW4924+Bp6BchHr!UVcFt;8LASX=MWAPGt@V^2!0mmu zx+P9%8kR2}WMy7hG?A~LcYktnw4O6elR!UMnmGiWGDk-pM6T4Q!Y&d_A}f^^sib)$ zB&3NM`5Ab`DXvJdx^@&LX!W;r=l?1;eqO#qb_E0(geAW_abh)XVKZa_j~iQ53x=IJ$COI9DZaE;6q;$P8Y1IQ5!iE<6$(@u zZH^ngaj6SJRqI#TqP3}L8-KEHZzBaPCORx;1Vz)OLO#U=yNNG9Ybo(vsYvU4nYg(d z{(Pjaczvz7T1<^J5;T6dj<%3>u0J>bBre`fvp0HopRZMnB52Vq^#ly%j92F5RE`t7 z2$*=I8%8l~lhQkW<%y|huEcv}w^2LOMb&pBZuO_TY4$nTx>CnVgXSrHFzqV*5_U&- zrQbrMrPaolKo1gshKg}jvwlTt|NFO{s$O@{t$spG0bB3DF2hRpUER|{A9&|i3;jjw z1C_>;OlqvjTNqzr&j_3)idue6>nutqqvPp!+401vnmnYc-Y5OYE8^=Y%ve0%SSP!MB5|SwQEvdsrR$ zCpl?vUr|X>PfJ(r)O9y$C*_Yztz!BkO zDw%agC6nLDj2n10vZG;RnHJq;@GjCn!Ff!nMUnqeQj{NgNV~F37^vGVzjd@2r(H&B zcqKUpK<_Alz91$eqWlOfvt(nuaIX7vnius;#%S1baA;M8W8*U)kLcRB_#P77^{Loe z5VjIt0p=+-cilUh&0BsRL+O$p0wRZaY_TbL&B=y4|P%NMNh*A z52V{I<6#&%gmJPCj1SFAcI}@kni5h73g4O6lwG*S zDv^MpGArd9cn|m@?tC+KM^;<1)7)5>XM_$@p+*yJwu4l4?HB}|T-ifHgEp**S6xyH z6tDili;zcvJ~m=@w3~z#))HKAg*>K>oaeB*gubhU8CjV^QzVWCob>QoCB>Ik5=fPU zLjt{yug~58U`9fIVsgVCLBhZdymj_ic?YyxUdCU&mJPE%=h=$W0z#ee$)EH zvrQ`oaMIa5LF!ftW+}vfAr{tL*H)O+j?O11-w2Vvpnv!*=6jDs6IUzZiqJ9WTdtC^ zqxk1cmYVr40yp{R)05y@TPcnx;S;vRHzyDO{xn806 z4(Y44K!md0`!hU-X$!LssC_u&^!Z1Se7YvuwcfeEZ^@~P_ z{TkyR7J*2m1W=%ExydVd9*-P`wQb77vHqFqFSf&%@3`3mvIyztqI4(UbiV|NkN5Kjt858nA9 zchg*VpXy)fJq@-5V>5R1Er4aQrM89~;_#KhRmSeg*16wZ~lb$JmR1tax{G zZZ)xnrW=f_Q4^+R*im+#o&kikQQBrLWePxZ(Dyp>j=#_``8mdViAzsVAZP|qpBld$ zzA@wfmU*Gt38VQb26SxjF!zge(q~3x_ z7oi{&8FF{!4h@rcy@~fl7{VnCzlgh1GJBF9d1RakK1BD`)}&4`_YFcL7_va5_{58l zXyx|6HrIu9Xe=PaA~A&Id|$MY7m~bR+5gmXz*;l6QG_A6_j%4prw&KaydPat%Is>- zQ-trD^AeTu^$R;d4v3vc6hIt#3>c6Cx0{&!R}n*P;~Vk3mxN1ZuQ!B9S;|@BXYW2d ztBI;2MKW3+0U+kOcY?p5ukSw3%lO?igw)UHh{SU7R8aNPVc^y*IZ2R-R8rW(;)>f; zE;wh@iS1fzvERmhE98WJ2>lTKA-Gf;-TGAfRi4AjrQ8Qf3aAPm=+6+<{Ej`pj+DDv z)Fr!|Fy@BP7j^|X3^v><UK$`JVbFE6ne`BieHvydU*G{s8f}weZ`FaUo&q z`nQ2Gq+eMqoj+hSqBR*bI!rw{iYWFq#s?hr#yuE0GQI51ik$R^UJKYaw2bhp8MHf1 zUUTRd8b`j_c+pppoNKIKKlVK`?!D6q*iZVPfFDbAc>KC};LB^vF z!H#k z?uFz3b_HycdnvMp>@#>X#z9vr{oxUm%d`E=C!g&;gmokzpZ6zi>(y%rn>QxgHqKb> z+98E$;>WZg&PCb)75rcLG>Y2;mv}t!)2O=Dat7A(#uX)W;T7I~f#62b^1{r|HMwTJ z2Cb8%-sujLIL4vHGMT-6-|&4B(+)cT30|%YVm$~NLRkO!Vqq%;sV@J}PQ`9S&J|iO zCP5EilM7mcLrEEi@y5=R)P7mwK;1SZl<_65HS@^FQksey9s7pzbJf+bLPl;(W5d-b z2jiEp9_D?dXoS*${1|x5xnA@#B+4CWPFw56z!%;jY3~q5pIJkJoS=rJ=QOCUqz22_An7xl2Zb> zy>>kA2*(?c%AR2xgKjERCPVuFhQBCev`^essMOu>%ZOAE`M^v_p_e_C!o=mu`C8DL z*%kV|4mBHhBj$`L*ig+M+pteeH9(=Q_0WPJw&s4^qvwot=N(LcU^C=D&ei`ItN#bE zEd2i)tJ(g?Se-BuBl%xd)oknu{xSccnt307YNUFm1hzP-gwRaHgmqY`x`epFPoMr( zyVlt!V8JEu#A1DrqCL?64<4GJn1GcK{TVai9Rd|nT~by`K{VmL1}|YE>%ViM>`VzJ zS^wce|Bu=Ebw9w_{^dep{s#+9=&Zr|=Pf|6af}R)jk?xv1kP} zVsg5YYs*>^kxS63H8S;dV_6YV5)lppU4&{^TFtb7g0^hU+zX}00PSBSzw4i-6;Z|3 z*S(`-7+yI57(Xi7>@U`t@5@c`@+!Yz_=85fp^Bsxo9$Z?M35xz=5H)y86%a^L7OMu zJWF4xNGamqDU(3cHvHd~4OA~8e)1Mu(C49?NFm;-;m&=ZfI5cglRh{>6YYCI_q18m zA2X)kMbMRy@ImLgUFb#Vq^AueL-eldrzZAFl#A*G9)9jvky^lMhDunAj>KovJfic| z%~o=a&by9*{${fl~%O@yiJA5p>lUCVbMc&93J3p|z82#40 z{SS6)f0K41$y*kjY(1dfC$!XH4Lp}62({?G?QeKIKXNWt0AP?<%g+CxxlYcGriM1K zrU{^EC~$V>e-PcztSoH*Qj36wt~H+elJCUm*~#+dyQkZX_426McGO?c+QWwJ$?tUR zsH8Cx+aE1Xu|og=VU0?2xRV*|2Wt;0~X_ zOE`2CzM|MmehppbJs+)fSk5m-XS+j#y{z#S2s`@8=4 z_lbjZuBPg?+&2a9XsT&{-<3zWB*)D>n)&dPtv4YL(-OJ*m^^{Vjt&jIRF3y}fpFhA zi7y#XN+s1ue%Pi#Na@zIKX<0p5-O|kNEk!j0c-VP^IPPuVr)}OvD;hA+d zlCq?fM>hq8T$3|cpN?ikOPmvduZ2viH2u~jX^ATFCb)mC$OZw|@<_D8Sr99BNvhbi zgjv4jkyF#$9hGKdApT7K-hQySu&iNh;fLCF8b*Ev8}_I&xi zV<#QkX2(Xywr$(a4LY{%bZk2vTOFfg+s3>7`_F%7*1UOdRpp#ryXu_W+;!K@`tI8M ze3VKSxkU@JYxaJoe53fes+hsA3l89_)0#KU|DuR!!!=>is`6Vm7a@|HxctFoWpek= zM5i{@N!XB;X6k)#0a*By@qH8|HUc+Hi3$z*SNatLbuw8@a#<#>a6cm{{-L9~vYTv- za>iY`I5X*=!2PTUmok<6yrSt|!hRZ4lbLx#!MsBFTp_o7D&Y|F{*YjJg9t!kd8{`fhf8<7xYgdDMA4g-3$Qhm|*`Y6c| z3SMeCH8wW0X?C_A>7cwbmTo_@0z-&u%Gen;H4URkNIP@=)cndSMJsxqX1019SIGdH z`Fcb1hE9bw36H%iIR~71rY8VE%=T0f#wt_0-ClU89?eX-0LMh^%P>)!x^6;As~6O(}~ zZpAF_V>ndF5z?H_KQ3jHe(guiO)E-C^eY($^r64&*Udhxdvnp4_Jq!<&~yJ`e6WBB?goYMd0!jhM#0bkCdmx)Gm%^*kP&kmNv4`+orTu3DQ!2#Z+tX z($nJVKIpYuNr+hV@$vRj`N>h)f5DnoX+=}8woSAN>T=7QD*`I*r?1O1c z9`0?{psqaxGy`h0j5e>U6L*b=YS+FMoShQwfIt!02(U|ga*~El*!ZxLhJK==2kU~o zI~Ii*;d`m&?vaAz^L4g!TgvRfQ}6VJDr2e_84?$qhh2eW=`vwM(fjW<_7}Dxn2g%G zdHJzfAH5vWEaJ807Ms7{7ny0WH8bGzD?3p}w19aj$OG09ivoG1FmfC3IU5n|LzuQD zCjBnmT%Q_mYotKd(uEaw3L>`sb>+VB`26m2m%}dJe&e8sGX}$;x1ujc~POmOpe)2jCeCR`xd{Aq&fzfJp-zp18|o4HP3hf?=W*!!%fBP`@$)A zdw`0F6-xeLF$6qS?Gtj%@>Q;Iu&3|s7|E2gxRR97RyySyHX&P#LSOG&_%6h1`$;vq z!gT%ih;OLrC|60Hpr1;q3B{eG3e&_}?_qR2tY^9HoCL>>{pHiGMNq#$eCgf#(MG{L z$_ntO&v19IY{d_$l-#YVhruooUV4vbI#F?(z`k{x?`GV z5c}L+89eGV$1H>Z4kCdw3`9ePnJ_wl8!u+4Cr3g8(9RLTM=uPoREMf6rxf3jEKI(b zQYQxEo8C!PUNBmQtkomnGDcui@rQ*l8r#P4j;56oB6To&OyJ{ZA z8bow*Hy>u$U{q@Ss#E0=P0b4P6h5axo|xs-BSl5Bko#oR^psH)+2f2{lzgAAOsI4^ zp*-Rc?E4ONfrA8GU`;b*lSg|E+sZ0&Lc9qu`7QchJ-F?o!p)Gzz9&;lL2N@;RZIbs zi?_>-=5mGsXB5GBC9fP@A5d)Y9RX5rCwaUyyv`U6T0v9znpbcb;#`Io#opS|suF3A zp^jDsQyR*>L&Zvc}yZuSR!H=V zd$TGC?p_#O8h*7wSh%4%eKO-zK=yJox0y!R2S7{(BH&IV&>MaF9Z;RBBI-*XW~H)K zSrCOsDoaWUo=ISyxvGVO+q|$;_X*M$WQCJ)2gmT)nbKAS%}tYte+PTkpbgD#fX?ZP%IpC6J4f9na3x|tx`nHcYhrD*7=K%Uf%2W|uXmANd3w8x* zEn{I_=zL3LdO-n0uqxlG^DH7eHbcFqi7N94Q@bve9w#}p#XpDM^*d#*&wZ3{Iy!;A z0@bVP!w-W{kWhvOR+nFx32c`b>MZqrccYU(?R&hu&f6;DwaapQC-k=h?yI7`cRrKs zI{6}$DV7E)JOQq*M_4p6)KKwLlu5hM2!SM32-ia%R1#|g>0N?vEFlp7AIx%LF_v}_ds6L-JYVHWkbhjm&2p|-x# z1_I}iRqev3LC(wcy}qH-^`$XxNwRxaaeh$ZM7l$T_gUd25*QB&d(PVwCp1s?QaxP1t`IkWoJXso(=+e|-!b zp1stTe|!TD#CJe>_wQ4>G<1py7(=g5hwY)Q0Z0Z-ARUyVg8fE~-<6Ep3A;7ran^s=wBsK~ZtwxIc#BQaXI|C>(hg zYIAH!e0A^JgM+qLUhkrNF?=#rF~1NqEoT3ft0OGvsf4}A-Gtu@OqR#5yN-bOfk6W7 zwgfrjMDJEz_I$Y%NFDxLi3Rd69sQqzwB-NR(QN;vqp#}!cjOZrTVhH5Khicaq2Vv< z38_))U-X{_yT(G0M9oI@28w14)I{ZmzZx1Vv3j)o|1Ps+`_D2nCrIa7CG zSy@9D3wj}Yduw`06H_}EOBYXiiNx741`y7KaWoLdMBA~yzZs5<5tfMPn~C@x@Q1#+gCfHwr*7l>H` zQkj6A1&E+x(g6aQfcz*R3W^E1;xCK}IL-RE|GgCxa0T$@K#CF*&D$L#rU_ga&Y{uC{2vt{3mn(3RI~MjRJr~S^Gl9uOUG4QbVZ3 zF>xe9fM01uk`SrmQD}zMqs*Bk2KDktn()W_3!IK>Q_`8dc0 zX2_)7JX3Ra0d0UUlfym;r@Vr*a_53N5eLN{Qh9#z4oE5TbYN>dawyD%gTwqHftsVCZTOAtePh@iATg9Z zx5b?0YFUPC>F@QPSg#*}i)3HL6&>7VZEkC1L*ssgnBxH2!Et5}n})Ca_bwy%67x1l zSWJ#^L&}lOb$C%4ny*?ptgUJN*5t$Gd2*I}#M-XRQRO7G?6PUH+7Tjfl2Nogni?W9 zz)S3+%P;CXX&Ry_k7d})NLeFIE{!kD6Hw*LC4?3!60Y`2BswvrNZTHNh}7R|zDfuQ z%*yL|I$;V(I;2e(K_iY!lv2(D6C;Kwzt zL2D^}m>BC>gjkB>hfIg7zuCE52mV@J%ZeASJ$p0iQp|p;4Q;cU8Xei45GZ(Rs2(&( zyU+{SS9#(eUx>dG-PIDL&}k>^4>_LP7wS>E?r_VNbd0iI7AI0b9hO@nrOXYxaCc3t z!=-vpKLe)RKR!1f>ohCW>XvODgkOu=@x320l+jOHXwm8?scP$<@Cm zg^qH3p;VStUUbsku-maSDR1)u{C=rqicczsta%xiP^y|`~PmZ9al6vls z#-)~hh72zEF~;^3>8kVE$G#t$us(Ia*mU>sy|}=iKIgexhm?{JA4j8cEK8!Pu2i!( zr~_OW*J-}-^osxPLAQYX%>$}|xRFmM_Pb3ht?Q&V(7h)p6`>QVxE^Z#4=@L_C1^O) z%V2EQ`qFLr91-eL5E0uSFHi=B@EH7Pf-JfysEI8xu|{A5#iaNNQw{qR^&$CHC@ULp zrJSwepiSP zxN(HQJG;)tPH$I47@ zKT?A@ti>*U%zyBGW;Q;9O=a`0Q-H4Q`W4N|C)HyiXpIMHC`Uv~c_m6G91Qh~g zQcmKwzwQw)^6;F#OudOlG~x9uX_ic7j-MzHPAFeADCx!=Bk;)uwR^|k z8>t{88H0ORP6|O3kU?{PORw5Upw$bQm-WuawaIQ~m_Kjk;>mum5vSOhLAsz&5Hj}W z(+y2~O?h;XRmHdc>3g7jl7 z;f1;t6jKbNdh(sj38K39v&+F5j>tONfLX=)JNVe5lQHtWucuzHj&=>lu^=LVJD150 zcFxZsUzBd&4e3riWQ1}R6(mX7RHlgIxE%$Fa>&eXx!Uj(`m^c|O^?=L?vGeLj74Nq z_~M*b?L!Fr(8zo9>icy#+KjAI{8oW#Dl%a44hYfMaEiKagG41UseK>!$99UMGr7%?O6q^MOFbcCBp0hKoZFXKRhTJVXm zPtoPQGAOqBbl3YNHNC|&B=Nky%{U3y0pmC!#UOc2IbZ^=U(<=|wk)SW95=qeF>V0a zgoSc~LzDWsO(XG#Ir@bYE{vTe@jXgbU~6y5??y#01>&kDEM&w-B!oz(w6&)IYD5g= zpr@=y83RXb_!MsnhYVl90Qji^3SpK>>^3FW6H{g$Ap^4QQ|~berF%vH4E3eW&DYV^ zKlujCe%zcpxZhjp;pnnu*`u91y1*@pmeL}C0BPaKpbKQgzSCww=w1ZtBYB((RO-C$ z$mZE*cK1-ib9umM6C{tWmPJU4S|kV)A;V{swsWP3=FB3nhDaDd8kgTW10~(eZ-koF zO)SCu*+1f+*>7`YaeaEpg?c7}7wb16c`0QMCnst24K`f5bgVCBbZomXO5fyj=379N zKAJ&ZGCfMt@KLLpur>Wm-fi=bQBWTOb7%6F`a$vxg zR@EmMG5Qb6Hvhg1yMveaCGbL^*dDqbHHX=Yv6hn0Te{-1>*)An=ufk3$Lzw|oJpTv zy5U0Vc9T%ok(fCsBCE$zJR(jc#Y+f|2S$jt6ERr;_c1G2SzMU z9*pvP!J6I;fF5;04J!JmXLx)H*4&T|M;Bhsb7xB!8&LySc9P7sJ9*2K@TqV_L+3KDhLXML)Xe6ke`gu&1dk+;o?6jx9L&FsC31qhU$_OM(B(X;n~ zo!jJH2(mz_&kuK#Bq? zl_8sDc%A4vVe7jY!`VzthzYopCbA@9)Susa!K1)YjDx~|#c|j@x^Y48jL^~hPs~WQ zVAHlp0LUN|a`Q=G@+zh`LhZJWTLN&M-4NoaL`3XO>=tErNr zKq|s3fB3?!P>u!DsYyISUSq_~^ zXFksp)MroWh_QqVBLWGDT6W!?UbEg12%scS9BdlFeaJM$Pl;i-n2uunqUW%ZCD+q4 zcN|t2*&1wpdoKp5JX%&Z^QL~8deSUCFyQM&(i)g3GIMmND;j#S`mK1C|LRWlDS$ZeA;($ebu1^}L7 zB$rMv&=ZRX^TWkdg~UK<-Br5`g*?y8*>lhbJO%^>I#Jcs zl!`1}gXh;Q%)Y7LiT>#BHK=Tmgtl#*QVGd1vU7?abRjR@8f`o8XQb!n11g2gIaFK zJi$`%#_&@-L3{b>b9#LbumdpfCf@>h>@+^$Z)2yOr$o$)e9Ilqo}a`1P9M;nb?YksCv9O_ogsG*ug$ocu%#tWS zh64wr3jZ4yoj3)QDF5CQml0IZ5&}x~P3**lF=|kD7NA~-X8VtaD0VYKgZN*%7wG#(?S3BqYoi>fga2-nClXAe11!E! zhx(PObQ~HWRgxQNH#=`_)|@*Ym6!kY;bk%IsX52~^x%=<5F&KcdZ*jQ&%U4^wtQdD znDyvf=)6>T#uN!K8fk}ORC5j`I5AtJIu^DpeENyWIq#!>^TWK1AFcp$zU#IfZWQVG z8!>187c%*oFd~L`^sx?w8{DcyEdbvaxLW0cMP1fIG0{c;9r`eWz#~Z-!v++*!i%uU z?-Ca*KRGV@7LbJM01KcT>(mNRD`$~`Z1^Nc z>SDr-qR5v~R3Y(=Y<*5`7N)uhv7hafHptD7t?2FietoDJ34*1$N4z65J_~3*i7Fgs zj$-4z=+_V*{N~wQU^$HXxwfkEL7SAiU#Ua6`t>}lIlMf}o5UzwLzJ~}9hd`M9*!aM zD)NX+l42pprADDOld&IVA;(Iog-jn_-vBY26V^%Bkm^lx(um_ zLvcN0WWR0~{<~Q%chkszUYaeo9E4X{1m~hnsMv81ZO#;4CW{ zfTq}vEV@>GV*Msw{un8+5iW+tH!8BoaO*X2Ij%(%3$PoncLUSPgE{F-Y219gR#I%Y zIVG&~9dYit>^RK1ea&|6zWh!0HD0PkqTp`*zDZ%c0&vF?<%7SI+vDZg7H9RzdldEMieIAY#+?@EdBo0?k+^^UB%sv~rSjQxAJaINDETupMyA58{%}kI0o9DG)W|p+aoiz<*%30Ki^8X* zsf)t>`N1pFxK2=?Ln5xe+~})$EXt8jygcX|Q~>#wi?W5|;Do`JpPQQ?WMYKRAe?A?z1f8LO?zmI(6l#>w@E)ZGF-%LT7C z{?k&JNkbXQEVUr0bEl^-$yjjq>zexZy5eL$WGEYG5`^E2Y@+9x8mW`yugjds*2f@8 zwgD1YelqF?YiU?KENtNNeG`erpSVh{0!0+9B~B8V0;Cd?J+MV7`Y=kTCBjxg(`t}q zzDU2FP9e_)abWD%U&y~714KRS^WLcAHp>P5PL+w=&w}tY>6KC>p1iN|RZ2m$mNDFx z``EV^vQvND_GU}(jIZf`?P>lK3PCm_xemBe9|3@Q!cb=m#RyV0i89;3uzNFQ!@waE zlZfI8NqE$?-$rmU^L+C&e-(A~>_`=;v3w-mrYwjSLMstiF9Pr3l2O9bv>jv{aKQxa z@AVFk@j!T;n{b~Zzi<@r)jF0S$9~|J(L&04N!Ox^KhaH+kdk5D92>nr6@>QASJc3xM z_3dsYYNwG44monpig|2G%z1aK&Ho4;x0$eW(`^7(2Fp~?LkBI?Tg|}jk^gD~d?WOz zi9Qc`#}E?P3A3$r!xTc}Gb)l$c);0z9eNOs>kGAz7|~pu=!kRNX2=`U-ZX&N{(Coq zC4UP9wC;Q`nSlmrl()9UJ2C7HGCJwAHx@)s=%phC_d}Y(6;?5A8X4V5E%VJBHgT$a zgew6r$ml+6WK@Wd$l*_@TP>xN(Z}82^b@j;m?4F;`5U$3<4>LG8j%%U;|m$b4&mm) z!Pghd8q|v@#w;1b*k>*-slkB#3y{f!v!lpn@;-Xm^8P<34p4Z}vILX4e7`Ll1`&tB z{ut)2?m4`k$<>G+Q^a43e#UScud5VUrOB;Ted>ImL8bNVe=AH%RXc1_wK@ zA=P?^nXJ7_um&RGiXIWNQ^V?T6DeBrNn3AofI#-Obg6;4&HLlC8HfWAmKFbP{}1!Q z>mP?6m~8Dq&v4sAkToFNTA&qp7Ld3C9{#cZ$3Z5jhmq~dqkpR=oma=+Y@tCMp@s;l zgo0?XG;#&hx5PQQM9f$ngH}G)5_RLuf+7K6-QvX}uG~MoA)8GX;ziiQU)#FQjhRf8h;1#`*cs(0JCV?emkDxLqVP%AR9KS5 z>L_vN@{ZWAP@GoR%SP18kl@Bh3(&s}(*#5_&}GxJz3|ct$7|>%m~O|1g9z`=#&1Lt z&yJ0$K!Zoh>3bLTZ{4)wxOdZ91n8|Pv~|3KkCW_$lKG+X0vbitx^y)`>M<>Ux!BX| zL0r?^d!X}s`(q{qdY}(f5dHOpsS9?(?x=pP0lM^RG~EbmrfeeCCi={p?N|VCnVQQ$ z6N9~>Ha&Qf&c@7;<-c5b{fy-sNHzWIc7zo!=!aAXtr0{8^ON_b$xUzprzWN?L{8lR zPI&K?K3HAH)6t@PX)h^kC-|q;f=BxN0Gk=yZ=xMuV6uHt4#wBGH*UzydLk!Ue8()*_D)FfpA=VswWbdZd?j9FsydKM>?PT_a5t|oIasr!<=_1TlfWanmz zPU3Aw&s|Ep%_p0~5jIUK*C*rzp23@puf(X6y$aXdfdFbmvrPSH*o`-Bf6~xWcWkI} zuF}k?1vJAps^(RJ+M-)jeAkBfZ?47Jzmp1{`*!(q*4~<=jK>ZlWN5TbaDNEIe|det zwB&O2 zhGq9>O&ggwc1yeff>4v*S}kJ@h<>YVLv;8G1E58NrPf;u8=}fs8Tj8^o=^nhQ>}5~ z4B)6={%E4jVjya3DtQK{TCHe;>XC1${yz`pyMO0eTSd|Ta0BYCz+Xv)ZNW8FXE@3O zlexAEkv}vD*Ay=6(KF}6FXe_Ds@>8Kye+yqz2OKJ@4TVF-44Vwg^e?<&&iIC?5Xx9 z0tF3~QR}~@Sk<|LXQe0<^L-3>46Uic3pkalCKV#HEzehKpeO{FL;+dIOIIvky^Oj zg(vz+TMJi2-Cq;O00Rl(_PkgdoMN=J`NDgajb!f&IhAe(4P7bMO(B!>+O6UB zcHK$7y0~XwpC*)|z>VQ0<6~4p2_fAB5eP^4mc73UEPQMc9NW(dz9T#`0_wKG)*ty+ zKZmJ(Bs3jk)hxrTPK4azy(t zd`G4oZF_y~4d21KbMI%h@07P`JqokXHjy{u{p7tQz0^OPgv$);w_W$igGL!`S__Bw zMa*#PA|ut^88st^AO- z5TwKt)x9icwgdo7OBm+JI+~XE@rQOtb9CzzMvl;H(sxj8@t%A`6;CE9Il%x3w@=fks^e+?3UT)7bM>|s_#m!}-tvz-wspe3G4y4Fv^rJz zRNPm(g&e13@wOpjgO4AaMv=TRzxrx# zYbGzZM67tqJw}@@4)Rq#82>Uda_6fUPMzV>7%V5Z%ja*OxYPvfrC*OGJ8QJnhsq-y zvgMdhGe z`cPgaaqR0Av)1g5h<>Alhj5$K4o4}8CvmR8y7~!4EmNWdPICFUS zHC474q027)bhz(8z$eEsB#-hP_=64}Nyg4HK=YAf5W-F3AT{lV!s~?Se(P}L%LDis z+%?Db_;10j%>d`_5P zPmM1xe}fAk?5Wq}plFFTn|P4_8C5F&uX>H#9m2$%EyqNdV~oVAZPrB1ZT{3J7!b_F z>TRb~Gz1Wg#GW0NM9ZD;sZmrQ=!xAsE{Wk=i2sDM)OT4@^(jDM5)*eF033glMU?)= z!c^>4?JSM$O-zBYuz&mhW}p0xnK@ZHxY#=p0kcH@W3jM>p_77>y|FV9FE8+7;N|8v zo(>j_L>&K$p8c1Li3phB@vp1?y$YC(!tx(3!hic%h&WjP$1+x68cJgRo_A`U5(s(& z(>^^YH>)r|EH5JyKM^l82P4~GoB6NJF39-TW&zqFoGc%NrA7d$PGtiFMQb@l0LjBiC4~pY zXvwDn$%aVP)dNLJMKT73N>yP1sRrd_X#xKRfB9l6# z1X2Ua$=2eo46;}PH2zs*{0f2ul`5wK%9`5w6%+=ag_WIwnTeAT7~Ev%WMF3I04CM2 zuy8RjasY#zsasz`dx4*w96nI?R3BB)zn`NxRZuQ4Hb(Zut10qSSrkw>fSQYkYoiCp z8dsJ^9U(lKzhRf>dt7`2BD|%4B_{OErE;exZ@V`l46X;c#r!03q{+gtQC-B|Ou(;A zbu|9Qyu!r>f(_s0u8;eN!}qI;C4B7g`3%QVD32_dZ1mYHiR84cOwXtLKZcJlxXg^q zon0%w_io}~qUEEdd#sZ|0F_dRw~VU z0t*re%=n$ysH4*fmkBZmHSn>}aM06s($aiG8hMts0uhDp9@21J0d00?hql+*eP~BN zs6#KYsc%AEmKwATiXSFA+nAR{0gV~01L4)XK4G>zH*CGRVzYfOwyz zi4+7Fr>td}XI3&NC+2h`-HUttykC4>n}bq1prfT<^#?ot^tf?Uc(8O87qZ?WCp~}7 zL1!fR3h@hMLk_S`VL4SQYuu2MILS^;(e|T!!v6pVtKfQ|R4;*G87n8if;B(>9gfz1$C1;}e3@Fn*vLycp zY`@@~?@NOB)1giMwhhp*tqc~e`~a_^XRGBV8Y;op27N?~9?;bDHk`BNmI&IeM=@9PDG0K9sn zlUvaefPZMvsh`zS`)Mrhf^q=OjT@>=h7j1#8XT7fGaT>iwRDum z-5y-MuxUH_qAiHwR zC*`sU=T?sDI5lteL+j^YhQM)f9;Jsn6C|y_BP`3_nHq&zT$Ik!0CN?T1ixtZN z%zQKE>gCa?!ZuY&D2RGV4YWUHqQq!ztI#ou8;lOsD<~R#)^w^M+vJR@R!y;<`$BMn zOVH^Ie?5~>J}k}Mlv>T6s9xr~#-H$Y$CPaZosld+72&J)gsz$5Y%#g3fbm}8nEt|Y zN$jZ20k=F8y)`*8ZD{=9(SQtqLdwDb$Uq(g{F6Jbr$jliFtf+EgR`BUekAorGVWi& zP=}^!jBTUVMPEsYPQZs^S@$xYK?vN!BdSfLxG^nM5^Pd;j$|LS4oJ=!6|e zeBz(6TPd$SYZzcKFJX3o=5|kE4-%F>JqNWh_dKttQ#co{l|Pqmq*Hb@chPEp9AOt7 zcL<^HSU>Kp+c>!CAI0VMR>~i18^aLcEM{e!Y-=XY*g;b^+z7V{NHT^T>Yi0e?T6=3 zZiGO9+Pv5k>~E8lZTr&^5bX^MXmzw#JPZFJ{Dai*GA>9R14PiUwj5p%LE^iGc!P~3 zH_@{p<^srg#x*RDB+~xIz`JW#Ct}7}s$GFFHIKCJSNtu1HyTka${r^a=H3dOl2-R1 z#7DH5?TrEpRG3&q>9>u7LfB(3$Fs-)KKfl#6jBF)h1>K*XN6gr{kqs*U`G|&PIY)I2o`19-ngt9anwf7mX;V zZ(!yjzeuOE0%LJR9_bhSaq7ge4CqB#vwC>YC1edq5FT1_sJRY^WGp6jpnke){uG6q zhX7VG6gN`^Z{4oLW5^*$02X+hX&TLc(v|1rML{>o%g@Erk)ED5vGH|W$fu*(pn+9G z(Y~perrJ-16aPkcxQ5xm$8MYMu!6MhXs2NuvO40Oo>v1U{O$6sUWr4tDz);aGGuru z`NMZ5B&o_ z^&XtB5^H+S$G3@+loy3`l7&SKVj_?4Tg&S^ z#5h7!bq|~i%Moba^G?!LU!F#qX?#ofCTN6NO^vhptDWqA^4}>XYKjKjyoOMRg>D>rLdP+gY z)wz%eYPW8fSq8!;T)fQfy%O4-PY+rz>*hDnZxR!TD4**Q_D^Rm$8aNbtMJM z_h)qQxa2Q%fbgAJ)4n7`xIa{;Rx-mpKm_FJnI$Dx$fEAlxOMV7WrX#I8z|DxLjvmf z;pg$hsgqy57EJZwm=*597S0^v$U2j6wci93XKq?{^E@I#8wfqz6}{v!A@o8h^vwgU zJq_)des%tSQi&gcDuXQJ*G{s+<`}?5L#%3xK;x-b1Qg*yJ=vvDL=|$->F_^1`X^A` zOk)}C%I+*4i3qb-3&N^{$i4@yLrGaW0f$_=ew{DEHLgV=6wp-LC&gPBDB6wsj{ z-n@2g3d-*goDM34za?g#=0+u8w)VaOK>zd|SUIuMEH?!|Z%6H#EWMNC7)y^v?GNpX z#1$WVT7~EX%k~|zDym!{iIHK^ekYC6?Z!j40c6J(q0xPK#^J2HO9}kgj0w7Ot|TRK z(RYcnMszK2BVS*Dv#&o6Bdr?6c`4slWTMKoX~N8^O5!TAF{ib?u)l6tuu*DQ8S7qK z8RH)Wo`0^;BwRHlllyHpqEAOd)1IXU6Scb|vu?+O52$oDn9X$wWbWp7az;zTMu{c^ zC^ApTx-c^}E0nv+l^l_l-gtFxZyhG52dke~N~hU%?wo^EKsI6tvb=(uWUpzsSB{x; zA+lvZ%31m1sOO&n6Z$#(drGGJ=a|>EGIhsotq=yWr>AUP*t!*$ZGx$v3LAEkb^Zg@ zp&Pmo=I^mjkE|6)m-l^m`Bn3Nx!ibw9W`?_yIrD(#X8op2UL(DejbF4zn+~Qd7Bykvy7+t)mNcG4wJ$RD=qj53Q+rr8{^3UYgV z4UsRyX|d-O43#{WmY?mgW(Ro9p4vbvkHHP9&*@Zo8sR+O9Hq?{lm=H2_G4B+`9kp< zMETF8Xc^m@rAoOXjT(>i{yNsWM_I|@y;WDlpWl_*=GqC4J%?J3?=!a{9O}%#1@YEm zh~gGP=%jxLl}TC~+2BdZ(m@X;>%>daps^?YOem=%RlGAgR?xACz?^`{L=kcJ(GGN2 zC6E16ysvrFTP@PcjIpb8mUfd3n67_HvYAV~lue-|+vlm#>A#iXryd6IS62VLsbCjH?YkPGk>D3jfvPe8ZGnhchNn$@ zfAbbayRFhReB{jQDvq1bd=B5jbxzX=7^KB{*1fce;Mok4RkL}mzRc1CYy(sW(XF`n z<8m9Y8VI4_>-_6Yml8pv3#2`Ie%oOUh#8}`Qh!y>At{@ZnH8fP({abQu3Dd72#PV{ z)Ov)T>s^z~DFo51+*@R@WEz^N#O)x-#S8+iT2#xvLyj?(e{q0^CGSp*>n2%5Y`{xA zV@5ik^;m}>{tbqRw}Kr5puBH^p<6KPO=e%xd6YiSJQczuAybWyR3)1`l_UyIkgx+1tYhc$zHa(B@0pIJp zgC2kMVQlU`1QXZCWJlfywXx-}S$Df?1aEl$+^3l@b<|5dP|;@q_)|xqur_O9CIw_F zHAbP~X~2(bwxFWV+2-9 z14axT!)h*Bk3eT%J{umozgr9}j%jjNm0OnZC;8gOvB9XX&ow)|X4cvd2u z^vlYqD|RXS?WUOo@QOcYM>&t-e9u#?iGkpnbQvE<@WvxDu|o1uGqW|+*zOqPq}UvS z!+XpkT1xOu?GZcuJDB7YTCJE*OuvkC68Z`xN~@txawkHwZRtb08#h+~cmQ@nKwbE=J+ei|I%{f^ zbjLs=KaO2$Ub^(ae5q|Tp_{?GQ1#UX9-O$|Ac2HR_AjX5P$A|@tPTYCUiC>|jI55K zoZX3@zT}&oBo12m=$zhwj)Chi+P-&bs8n=~l)KWPaUDWOhZU2M?`53(>o+Etr)=?J z!4zV0LV81hnES$Zr-1?MLrXn@s7#HoQd#rj;-ilZf@R80mzCcfeC#L1eC!}gR|pMw zi^eaEa(O(ibmJ3Wa3!7zmWtYwUl}@3@`uF<(_9z)mK9%v!0PZv&yOo4xqO7in2t$8 z?3!~i0)kOmOXt|Rb4OV z)e}=~#Le4TbS-pqMo5c`w_Tmxo+(8HoSTz=@w${4q1z(0+VOcQOG6CQfVg~@x8DoZ zcI8fWEw-?@UepUhlt_(g}M_U6zw|YHoFc0ljmsTFH(lyGbKVJ@d6b?#- z92H3aRS{cN6=am`%x~y)LVI770AL2EP4@CMy^9MBNU+=IJEUuijl3Md z{LZUg6-vdYQ{=DylNZEobelUPCqB@Ej;zT6Xgo4ucqR%;A=O0~@0j3Eq;(W>=EL69 zlQC=Rjbb#1W?^y?Q`b6kewFDSfsuW1@kxZ^77tyM4Abc^cSvC+GvO$#{rfJ9_V~s) z2W{Hm&^LVZogRr4J)e2C75yD%tIwu#r+bJw(K=`;z@0NWVhH8CmS7^%A|q*IipLL- zlj+zerS+?z#v-o*GfIiX?2+2%aCtnW9WZuTE`RLMk0LR*7#F(Uq6_8=`i%Y!0hKl5 zWF(W~7~=CN1lFnpzJ;NNi=d{B6m3S?y}E^7U|WM!6XF3Qo6q1o9!v1&SQNyp5&kgX zC=9VCL){x^gm<9-`vG}AGsYw48&*5u5hBTuO-O)SNcv0XD6*HcX^at(f5tA@7iDbH zDl#Y;$736G>R!tH*k^no(!m?8>NxU?sIkAq0yYtD3Y*eg{GR$e8cv7C5oTHMS+j#Hwy%+!Aet3A;Yi8D3vu4ejVfNnZH-AUez`QoJD1HY-HX~Ki?$%h{ z6puMPvv+{L>Ysmiej)m{aZRsfA?n=Z{BF>B>_|(AtE^C^NVl=W`J3&2m3Z?oW6E(kMHw(5ZL@{#D3n;KX`Amz1IS+k>-&tgE-~S7C0c6wtgl zy+LBGH7OHHx8N5)mbSiMyrPCF!Hn40+w8(AQX}ChA&Pr~gWo@#yvY(?l~%6{@@x9> z(F~R3C-k08%V#Oq%kziB6gr=5hEcIs)dt)syEg)#Z2xL*VW>mDKH4;gE}XP0zJ=?Q!@|r@~2!1gd3(BFWoSCbeFe2TX)64jD{}I#Emv z%=<GaAF z!FL!VGTz-E*@!h|cfd3Nv$9c(ayY1kgH@<4({b<>c0@Uv$Yzn)B!d^maR+(yL#*p^ zLL#imz%Izji&hCGy$zuqM#TptB~Ora2@7mmOz{{t>!a$vr-^0Gd+ zw50c`Hk|S{`?^9H&XtSDSOJTXy_X-$kJkstHF7m+;jQ%hY}NZ-`;78EN;&SIiQrLs z985ier85e~-ucesLwG9j5hcz;yJkA>B()arH2PH4C}b2;m+nSLCGKiuv5^EQ@YtS*9E`?{)JEkZT8$V#lQ-DrSVF!Yk$vO+y0tB_@iE`)D6k=J(&A)_QY=|M zpD!RVushvkXtTyw9ZWDEyJTiF3WGnWYe4<*JocW9iKbbreK?_S-lrBPYIHrl=jZDE z&E z`UoPLH)7x{K2GDVfohK&UY1quEy?m$?r%vRW#f$1Hiab4-MeabLK<7EpNyH>R{Y%i zE^LfGTZ|5%Wtcv5+V=ajaV$X#?_MC4^<|aN!(ugST9XORFgYC!>f~i3P12d&NuO=V z5Spx5(|yB9Y=wo2=}fl$ekqS8#}pYXnl_iA1{x)k&F-f7-&Ms>iLLb{LIDhl!%TGgf zHTa==w$J;p=+^db<-L6MVws1!AHtWB-0Lsf{=(g1h@wj-GQr9fuV}bn?-|Jy#OqFa zTnTZ7efEC;t6SSF=uKHWgn|KNSqIj`o~T{2Pd+k?RLK!N^xTbiu`G1IB1&ST+oJRq zjuvK(GEJ)qYV=z^kSNA1^);69yk<{My z3kfCHY;wcBb8b4pXYbmXpEn1BS$o`B;!+PNOR>_7om+2jq~AH@me4yrTt(1ku=bG9 z+v>Zub{(zAqb3=uA8OU7NR32dRie z37Sap(V}Shtqt6s&%r2RN^ zycq8Gqu-I=#NXO;^Se-|BezULe6V}YNddp@oFZ7R_*&ciZI)_Oqs{Zf6hrP}h{ZSq z(|!Lnd^-o>%51ZFk=l2xaK1+rIGCO`80KG6pGRNhoSkmSq>#Cj6i%u+mNA79AXmgo zv#}RT8>$zQFi9OeiiVHM4wTw6CdtUF1g_zy%^0F+w14U&EF=_|RvQQwk@n)q^J@?O z64M%$iXw&-NH5M|$Zb{7DT{GOA}#i_oYjIxyHr%)plFE&PY`jiF#KLjkWVp`X0`{c zhoVxXywUEa;X41!$Wq|BN%XMWgC`y$yFqG`pKaJ@ z&(gD3z1T1oB%Ymsjo_X5DWjj|X1Z4Ww)ammgWW&Lzj+M2mCqx8w#S||ASSmbw zOJ;?R5_D@y0_9!Ns4cSpyd{$}wCj`3JBn^sNvw=0Mq4%qIxf5cb^`wF4;j2%KMJep z9!=eQ`@=a@-9CW`?j*rdst}Y`_u9>l?$H2$fw;0rc$iR$f26-c%lz^*J7OSMH=vpT z+u0LFI(HkrDO=;Qcxi6~h912Gv3r$%};4X zHTKu}CByuh)ge$*81~P26V`1aa8UsYfJevKi#H0r!+UD!aHaS0u%N#30MAx}onXz7 zKfjtGerr*}>1p@Z?N6wxcPzu6G%@*&tbJZ6$*M0}O`azuS3kplFG`>T}9i^Dq)XC9euVmnow zwlk_$6SU!{vVc15pz5~eaWwZ6zmw>7JJ-*>B{gEr32d{V`<8EKOcy`Ko2HoeeXIyR zI##4HF=m5KXvm5Lm*&xnNtJAgElgw#^yh()H-$QbIsM=hq_xH?x;BX~T$LDbPU=lX zXWQp(=_c7)@+9exDQM@4@u>yz-f69LBikxyGXGy!?=tnam<`Zbda>>`YtEM*`bl3lrnAU>1p?)B zsg2|eI7eQZ&bnj9sdLR3uYo0ZL$Li$GrhAfjUhveB{H)^QJcW@h>{_OsG$MsLRxIS z)b6cM^h8}jOtVhabT4<-r6laAGNz8=U*(GL@fg312wquXzeAZpEB*9mCr>A;z@z02 zrv#eZdWvNfio2{S99q4&VX}5aU5(3MWqUi?TH&xgaL0+}Y(t!SXx z-x@r424-A04rXo-Mom_Dfd@g{yRRoGO;(_BKqK%Fz)O9A#ioHLiuw|;A?qoU9I?_c?5#v0Ot=!jw;sgOMyz(d037 zM2c=lo(V^q7ldlHsT<~r(y*Co;`;6-;f}SSWv{nqzUc~~N`<>@dvQRF*_?CVS*gZ% zO=~joXpcmiF^s-g2^sO`O8&YJlr7OxSnz0}0Im}{Gh$OstJ(I$V7ZZo1$FTNE%Sp& zznt*0?>}ako{I_wv-S*Jw)bAP?!74;Kd6{SQ1H$n$J)?u%w&{s5^|n4Rt{cj%WGtK zyu~~AtF=L4BV|%wU|wy0J|g>LCC~E^(XRQCRbIJh#icIq)##-Cu*;R%lZ|Kef!OfI zq3NoVt@bnbUKO12Lib)Q0cYh_%dK|@vF^Q$2mNSK!w^&VmsV&jX^Wx)rUKp}Z%Ozl zh-&)>*27Z01en&tf@&UldGi;ciQgvLux?np*E>qf?B!_fZn@Q$_C%t@I*(os?L-zW zyqBl`RW^#ib77BHbz!W>`^h$FQH=?3QW`p~sN=uMV$PMTlIY)Cp7XHZXFy+ zf6I`x;1r)!GTBMZ!D;JLF}AJVfa%Wim#>}o7|=&@+%Rtu4XZx=VfaPPm%@-bM#N2g zf{FL6H(t4MouA87g4sD=*`OSOO2<^MF=aWE$|IG{#IG7-X%l1XvNO;n^4RXJZ9b3L zn@1FUYXmcqpN02i_kxYILOD);n839l!w=09C%p|1X$qwZ#A46Q^MfaQ-U}uicQ|D? z6ja7ss1sz4RDRl^#uZuDvutLo(rNIcy-2kj&VXTmJ+GG4i2K+kc6fTRF@(`pn3aSV znO1yk6+0VuMCbJA4H?Ag_NtJ`=a(J2_}DF_2j4os4QPzjyc=G+46;Lqd9uRqYJKAz ze4L~~gLp$Vj=-H)+E%5?MX1a^+FPvUO~o+%*5;)X`lX|zPusFnB_0QDh&Ex|H|(jm zeb}L{A*L*PR%q=)j};rp#xy5k*Qjlkc;?X~q@zY8FKH`=5T5?BASB51GccnyeTeg? zU^Na3R2&Ly!+N~p6)7r=fFWdft&j3oaak&yZ1gO2=m}2pB9^iP#Vw5zGltDtN~~Dk zcR5-;vHkvOfw)+M4c`;v_!i$kbs{cod7!gfJo=5Dw>4=$(%&QD{j6D&Wl;Cstvrk! zv;N$z(twoP`IqnbMunz0` z?kZ1w?dvDF3g>x{%&RWR?YB&+>Jo7eXK@*))fTB-Cz3ZWSn1v*B`106+`4)uy<03F zZ1j;-rryoh$@nsLitaGn2w%~`jw7vK3qNLk%iUWlw2d*(GqwQE@me;|UJ!}QlD?Vf ziF*|>x$Mckx{`<9dn~Y&1Xp+)2~}FACu4-EO{K+rc(ppLCfr?mM<6Fyo8R}l2jf0( zL;zNH(#)r4Wc_>j>rZsFRi(D{Wv(>&!lc3{2n>;e{Z!Xf>qWkS?2(gm~{27l~X1ij=Ko9tn4Q~N;5VP zw4X5BXUpBs%IZv~>3nzR(sc$})_CQOq znBz(+t9dr`eRQZ|ypd*ENNQwG^PW85K7Q>tMOoNKi6$u$L6WYKCoH7?Wn9c`NlJor={wFeg`xiI#KcCV`S?V&kJE_KOBjh zPC2SSJPj~+PLbv}mS1M{Gk^bv=Jss=tmp5Vz$S}wRpQpx6IkFwYyU&&UILRdK+7~vD9&)@MiwAI=t!OA3Dta z;$#*ROWS6}9rte8-$`fj7QZL;fd>>e=VgVw-1t`PaC@GPM&f>SDD^lcj>$xgYBL+t z2c@*su$gu)%D%#tQC$CWjT@dY`SuAM*wX9(Wba#L$?3v%dCU&(kliC`ce+pl3K0K z57~BdH&hb3`Loo4H`rgd7b7i51LM%VNqP|v8D44Fi^zLeaRhpQdRdv+;eL=HqlU-I z*W^(|yB0c7V*Ucz@XmfSL(~^8t=#Ea8i~XGTK7n506eGFlqM!+DhwuKZ(;Mx84>db(KRFp8Rj{j)r3J@hJ? zZ|sa-w#hh}RL~2agU!4FUlciWp%a-?vAPee zSECkVY9sJ$*$!w>fqFo_TPGwFgfn>yuOz$0$EiX>zUCKT#Qp zBtkyTo>G~4oym-D!b$=0ap-vqmrzEhNwD-qt5I{f!vDzn_Vuq%q(#BWp{T@&YyuDi z3sexwCk(u$3Viks1-{OQ0B^7gfx&#jLf3Dwf`KpgMT8)T6#|eR;#?QRitv{NvHW#@ zEhHxT`z_^v9bo_SF0zcPtDCnMgNf*`SC6khrN7R1?q=d zE}xINhwAUPOXe7#J0;OBISkkHm8%wtDc(Qp-HWQC5#2I&(fj_4D-}*3Vw;SbnZ27q z%Nh86CDlI5nTSP(015diZwu%W&bdBJE&Aa0k6%aJD=!aaUE`?~M2*}k*tL=1CX_Y7 zt!HE3zF*)|gQKSdOBA~v!H1QRaMstgj5pRM8ZXu_4z}l8H0Pc9Z#xGEWiULt3moyi zJ=hwapzrP^lI^+u7;Z5T(a1SF*u7ZXr~((dyx<~z?PHZkR353qpQ;3B4VQT4?WARr zmImdeeZ;;$nAeP0by+cW4aUBDv!K0UX&FaimrRyS9$lv_DyZ`C5S~svP5O~bGH!!q z==s-hE#JVCye#}I19#iz>+IANTc-RzmR%$Up%-4{-?<ue8>c932*(vV+~{(^uqm3E`!4_4-7$>v zVqFsr-dN8QTKRG~%Qtw6=ZC^V(3+A{#ZynViV6lgWi!2rV@)G8clxF~(KV~c@)$Jl z{B4k)zA4JYAu6;0Mpz9UJ&WZTx$(srKD^%3e5Akm=m$plgq6JwWzT?9^J$#u9=H4_}n;c0E!^Uad#WGzsnlTm%gg zxve5YP1IuABO6a%PRvwS^Up(dsKRYBqN}%jS;b-(8cpm#w+OPN$*pien2;oU%g1=6 zI9Vd)=n~R{GSs~AiJc1ehZt02L#HxmILN#|rvv5;nwhIYDx8&^IB4jc4QYkJ>ygS_ z_)wh+jrE`qYWh{T?eQ#iWGXNDPzIvSldLN&=it=K2uaO{Lpb(NzC|q8?_$lK;KBKl zhmuw}6ug?r$962E9>OJ zJujtBO%e#G6biP~2XqJD}Xa3R7vi59-zT z_nNq$RJ!*%OLgU~bV7paC7r7IVwdX5Qa(;@?dB^fQGL8JUzDMzx^~9LJ;@9$DNh`; zvrnNKch&61$p{E{2~YdYP8&dpthILaX{tMiC&DS*aQTAEZ3gbc5N@q6KU{25$@Fcr zD&c&C6e&!jyC!M=c+UiWNY^3j?-gLekQtyo(I!Ru#b^Cw)04F zNKFlQ&o2V8|B*`rk2ncb7pMQFEh=ofij(CiTN{4~Cv~M+gt!E%6`yoe{cVZ4Jg7F0 zC#~n?xWXy`% ze&2ZqjoGr-lq#c^Q?b)*(5wx;i+Pg;Kl$<&TV*+0eypVXo6p;rO`?y`JC6yo{KBK( zzef47H^9vv+D0lA0o67R5X93iG!tY!K;j`PFGfN>qbGZOr~^{wm3-ZpRxgjHIIjLM zHz*hWOecp;q2;kaasm@^#xp%^SY6K0(<#F{IsNIJeqxdq;28ArJq+_KSr)~> z$&^!GcCOIZ$t`1ud1q}3Zo(!C$^>=kYqPZIeWS>>biuG47#Z%y%pRb8Au4k9d4ULH zm2&2)@(sNJACiHRAtw3KST|EIU7xGDDIB{Q)tyx9r`IWt7S?;FA7~pWC!Xvsiibu9 z>Q}yu*>&4}MVO0355|qme2^8cc#h{}w>gVC(G)0SCG0>6E*r#4m0LSe{n~Rd)C(a> z6=F=w*2YVDmfH6B4@fut!__Cr67XraU!fy$)l@AzDelo5`4kQf-n%CnC(S8CUjaA6 zR4j1UI@4o(YW66y2;5^5v6oBoQI^SoZ4i1 z%St5~!b0_h1fFPvO9Y1-vR{p&L0IkZ7)3VM%aw1$ghd7JR}g#UX9DL=jk86;o-x5p zvBCB99Vb&7bh(hD;t}!;!HSq{rq{78&X0+6k99^vGDBfO*s^hDWrk}~yLnVUPLhl1 zBi&C*-%&SUf7QZjIa2m9qK?piAa_u@*Oy59R^dOG*AV)vy2AJMQgXD&Dg=A0?5 zkM?;e8I@6ym&Qelx|6@q*xpdd-b-tET=aEAXmru%%`+RC)6vpba6GopW#5RS?*zCQ!bj*jHeP|{WLpu#$eXg_^5*qE)|nTD%7ecMul_k9p^yG z?6BWvv4k~#u7R7 zB3&r_!f?GdSCg?-b1AdqaZ5vSJ`pke;&R)c<6@c`wVHpRIZrTgIa5&TXe`nKf{pjo zJx=T!1G#w9VskxnYpbMm772XOfV5Hn^ouOFF-2O%T0X>|XVYUiK>uw}&noABnPm~V z?O98+Ow`U24d;k31}2WZR(+Q)>ps^-VU=r|9@Eg^O#L%6vc_+$@9K>7QIdUQ>zmE= z@dHd#T--8o4<*c-)$`C3P#cmu>_-S+qkq1iHKowgV@+mD-LOF-0V;;?N7*amC~Ql1 z-ABmp%~pU#3G@Q=_9!&&>1!iBFpD>P6y%1{=A^{%U^xuQE=%*7hi0E~2Ob)6Esgs( zzA{bUaWE)>8#d}^csnuMmzc;# zsjHTDq6u2vZ+zAtK9{cxue{xLgon$Fd+Kt@q=;GJS#))wS!iS)FRx(g8?!_(DKh^8 z0WY==iNN$>+QWLSNzKk_j&(SACFJxk*F(u_OY&phs8_9X(W?Xco+M8i77d3~`jfO4H4E$!=ce~* z6Q5=`;unD`9&>Q(qOzSz-=2@8t0*2MF2953B=b-al2{G-3Ip#jDm_ zhmhp(hPYb%FVE_>__AD`vMnE9EuIPZhkEnN2;~s(pbN&jEVrexI>%y{hSH*9h{4>vj_!zl@Xi}7J z2VRVofnFeCZbS9!dn%0YOD57^-2bNfeUgJF;r;H^4*Yd4%F5Rf4$zN6#EQWn^UGb? z9h#=e?=@%ItTNMrVuij26jIgV#DlM5sAJ56zdL!n&JGxR3y<(=#_c7o`H9`NaX9N@ zp5kCUkL}QcUKv=|saYJD9i0OtmB7krwgQGN}VP^7!0zKS#e7agYVx5*`)Mb!` ztM5y>c7#o289YCFZonh67L&1x{(}Ps%-V#r?@w{V6*M?dAC%h?T)LA0Q!x>y8$m*ITo@l%7$z-komh zHk^9^U&)3B4EKqeEp>@Z*)_c4XnQHfcG%d!VKAJlS-RUPM+~Ya)>cT1cpHC$Dv_ILsA4;`LynGv9&7};n7+OXi?Vq7nm>j$9-et>4k>qIKlmcMVg2~{WICbjPV%B}>qP+n zTb{cXpUQelkRNMc?t~mUbk2X@t=W*8sUIfQTt$d$w66&Qc{M+7DJR(MpAxD&TwxKk z)(xL36NIlz@46bF4>?^ZKTRJ>&p(B(s#EK1=}1$`w`akS;39srxm1M<;&^DD=!=sqHxU4OQJnBq2ySMI6fi=JpNgaof` z2;eC8_is)LTCvM}TU6O1@j>t|{}6m%QDwj<=u!hsUGCgFG&!7d77<4Ca{nhce>x7m ze{a-zJh@tmM(5_oU2d6MC&&|BhMv<~BlJU88N6Yfh7CGTOp*glr7=TGO~QOeGq%>% zoJ2o476i6{JPTLj9Uqx>mXHk9G_S3?wJ~&w9GJgeStb<+;EBF}_J7)?F-`+lcxx@B zJQw!r=W@oZ6dHuTJbjeAFeEyb6$BTFbs~H)ez+>>ru&HVpe%wFW6rNFy#zOnnQ{Q> zK^VBvqX}~#3!^;kWSg&1tx)pQ!jxU|B{92JRMk}e`@Y=Zx5Nd*+j>IGwH7@7QnCtp zrBAT(lF-%oUPnb69~SQzZ>Unj#dI+f1i_`YY=a;+ZAYhdfZMqnI@{wR>HExNdg<6Dx@4cg zrqCx2gO;zN_aqkH`K+O&hKlvtms=LsIH+(6IoN0{6XNw&BTuFPi zY+OWl(Wf?(D7MH#Ae>uLegbFacC~iRmjCePC0}>W_m3uTOvPSX8pgSu;{FKwb}2!U^j7)WI8Z%JD)=%-MdhEML z%TtkB$;f)TuVRn$hUc2bz7ZdVPj=lC@SChGpU-6}ZvK_R0>DrKa$5ihD!}jmo;*Vk1(qNZ1dk;M8&Prn>#-$>OzIkM z_4;J`SJn)ELk(*uI~#8X(SI^z@M~Imd)s-s0=TFDoNnKF;H{|RZRKspAPPkYSb#|2 ze`TEo^!SAh^H2T_1pqlk`0qy7WdK0SKU}YGAq;~5E(MTU{#^=S!Th@vfQ0#XDUiVS zU!^<>0JiJDiskGD7-0XD18495K7JQMtXY865o}fijy*%u@#@|T^D%t2%vqQBYyw&OpF@&C(? zBERg2EQ+{g1)@WIv<2ZI4lF?AEvi-^W)uXbJ&2qb48Z67o$BPS-2-m``38bWwFT)S z5I`vkP>QIv2k{~J>_BRWVh0fEFH(mCh#%2y2Z8_}P>Aq>MMb~}=6fJE=0BPJ9zsn| zJ70jgAVSt2B#D@@1(74p?tv(g1rVzDK=g=@b_q_ zS^ag7m~;eDBTDaq*#E@_A^<$H5riR1fu=yOg%PBVAf@CB5H14W6@-IOyALA!WsEQP zLG(<&mHJx-03h_YRsWI!7PyvShzS!C;S+{J0B$4qL2N*KQG}rrNa+@UJH!VOfr1fc z&LFlw2L%j4AUlKT)9!;v&>7_I+`aE1LYzPhm=IwopAcYmVZ;ZZ-7j_UU4XGkz7OKZ zgoz08fd!yIt`xY---V^ug$&Lh7^V==J0S>=Tm^yc`gftAD^S?z4CHxuxlzs3nHgcx=KK@cu3AS@gq zAwfPtKsw;YW(aI|5Dnt469|*>x6%G`MIe9le_6l~I<7#vmtQOd1qJv-06zi5m?2{R zzbt-#5c0Pc!U#fV5Gmr+6~z3D4?b8J%m)FS?wSuUr4eJ^Aj)6b5dPNY@1`OMTQ?9G zG3xx6qhX-~`DsLeSe57i_*sA*=sM{TI^vBRhzJliyg|G-NN(OBdl2Lr zJd7Ce(HlerJea)j2FZZ{ACUC{Ng|6NLVQ5^V+z%xL5)B%$xvL7Q)sSqzv$`_61Q;{_+$Cj(cu? zyg)usM^`UzD`#h*mIz`MU_=fi4+q?Ufy2edo!86G)7Q=uU;!ACzz@Vo{mae_9PW0W zE{k1HrnjeS)i`Vvgx&Zfrh2;_!NKsiKM5W(dSV&}Zk1)vCez3Sdz0dxTo;13dq|H&PQ z;eS*Y7W`A9@bv$W5gINII|x{Ev#z>#f#*8^Z)4HyH}T0Nj8Z^#EP|5CRnd1K4)| zWb z4+EkCum-C<1Tn*fAi#O>4c0VStz4qzS>m08rqKwlH9fZqQ&r zrZhk<;EDfo7#IX{Gw=w&1OXf0Yz(-@%{~Es^@m_Ump_~m1_r|0Z+`Hu(HtEmY1deit{!9cM5qsJmpfg3{%%t#>s!4qf- z^#6Zai-=tB9d0lb{ga_6_@-lmg+w7Y7aV{F#GIS_L}C9~Gp_9qR1}8&;UJ=-e`pO8 zxCU|guYxcE;Qy&VXo5HAI~WFR9&Zi_OaP{Rb8Z6_g>SBiz;yUyr2}YyW8V}EfdKm^ z^H31I|E~i9Z8taIA1DYAd;UtLsqAX+2HXRE`1@X-!Gz=g-l9rMasu0}|8w^W6#Y6< b0QP;J-VZ$O?6JT=kP;NZVr9Lfq456z#uDWi diff --git a/docs/resource-evaluations/README.md b/docs/resource-evaluations/README.md index 602167f..266929a 100644 --- a/docs/resource-evaluations/README.md +++ b/docs/resource-evaluations/README.md @@ -65,7 +65,8 @@ Les documents de travail bruts (prompts Perplexity, audits clients) restent dans | **Awesome Claude Skills** (BehiSecc) | 3/5 | **3/5** | ✅ Mention spécialisée | [awesome-claude-skills-github.md](./awesome-claude-skills-github.md) | | **Wasp Fullstack Essentials** (Vinny @ Wasp) | 3/5 | **3/5** | ✅ Intégrer concepts framework-agnostiques | [wasp-fullstack-essentials-eval.md](./wasp-fullstack-essentials-eval.md) | | **Master Claude Code Infographic** (Rakesh Gohel / Aakash Gupta) | 2/5 | **2/5** | ❌ Ne pas intégrer (surface-level, erreur Cursor) | [rakesh-gohel-aakash-gupta-master-claude-code.md](./rakesh-gohel-aakash-gupta-master-claude-code.md) | +| **Snyk ToxicSkills** (Supply Chain Audit) | 4/5 | **4/5** | ✅ Intégré (security-hardening.md §1.1, §1.2, §1.5) | [snyk-toxicskills-evaluation.md](./snyk-toxicskills-evaluation.md) | --- -**Dernier update**: 2026-02-10 (57 évaluations) +**Dernier update**: 2026-02-11 (58 évaluations) diff --git a/docs/resource-evaluations/snyk-toxicskills-evaluation.md b/docs/resource-evaluations/snyk-toxicskills-evaluation.md new file mode 100644 index 0000000..9865fb0 --- /dev/null +++ b/docs/resource-evaluations/snyk-toxicskills-evaluation.md @@ -0,0 +1,73 @@ +# Resource Evaluation: Snyk ToxicSkills — Malicious AI Agent Skills Audit + +| Field | Value | +|-------|-------| +| **Resource** | [Snyk ToxicSkills Blog](https://snyk.io/fr/blog/toxicskills-malicious-ai-agent-skills-clawhub/) | +| **Type** | Security research + open-source tool | +| **Published** | 2026-02-05 | +| **Relayed by** | Victor Langlois (LinkedIn) | +| **Score** | **4/5** (High Value) | +| **Action** | Integrated — enriched security-hardening.md (CVE, stats, new section §1.5) | + +--- + +## Summary + +Snyk scanned **3,984 AI agent skills** across ClawHub and skills.sh marketplaces, finding: + +1. **36.82%** (1,467 skills) contain security flaws +2. **534 skills** flagged critical (malware, prompt injection, exposed secrets) +3. **76 malicious payloads** identified (credential theft, backdoors, data exfiltration — 8 still active on ClawHub at publication) +4. **10.9%** of ClawHub skills contain hardcoded secrets +5. **2.9%** fetch and execute remote content dynamically +6. **mcp-scan**: open-source tool achieving 90-100% recall on confirmed malicious skills, 0% false positives on top-100 legitimate skills + +## Gap Analysis + +| Topic | Before (guide) | After | +|-------|----------------|-------| +| Supply chain stats | 8-14% (SafeDep) | 36.82% (Snyk, 3,984 skills corpus) | +| Audit tools | skills-ref validate | + mcp-scan (Snyk) | +| Attack categories | Generic (injection, exfil, privesc) | 8 detailed policies (hardcoded secrets, remote prompt exec, malicious downloads) | +| .claude/ attack vector | 1-line mention (line 199) | Full section §1.5 with checklist | +| Malicious hooks/commands | Not covered | Documented with audit checklist | +| Recent CVEs | 5 CVEs (2025) | + CVE-2026-24052, CVE-2025-66032 | + +## Fact-Check + +| Claim | Verified | Source | +|-------|----------|--------| +| 3,984 skills scanned | Yes | Snyk blog | +| 36.82% with flaws (1,467/3,984) | Yes | Snyk blog | +| 534 critical | Yes | Snyk blog (13.4% of total) | +| 76 malicious payloads | Yes | Snyk blog (8 still active on ClawHub) | +| mcp-scan 90-100% recall | Yes | Snyk blog (0% FP on top-100 legit) | +| "91% combine injection + code" | Not verified | LinkedIn post stat, not in Snyk blog. Excluded from integration. | +| CVE-2026-24052 (SSRF Claude Code) | Yes | SentinelOne vulnerability database | +| CVE-2025-66032 (8 bypasses) | Yes | Flatt Security research | + +## Score Justification + +**4/5 (High Value)** — not 5/5 because: + +- The guide already covers ~70% of the scope (security-hardening.md §1.1-1.4) +- This is an enrichment (updated stats, new tool, new section), not a gap-from-scratch +- Snyk stats are more recent and larger corpus than existing SafeDep data +- mcp-scan fills a concrete tooling gap +- The .claude/ attack surface section addresses a real blind spot + +## Integration Plan + +1. **§1.1 CVE Summary**: +2 CVEs (CVE-2026-24052, CVE-2025-66032) +2. **§1.2 Supply Chain**: Replace SafeDep stats with Snyk (larger corpus), add mcp-scan +3. **MCP Safe List**: Add mcp-scan entry +4. **New §1.5**: Malicious Extensions (.claude/ Attack Surface) with audit checklist +5. **reference.yaml**: Add entries for new sections + +## References + +- **Snyk ToxicSkills**: [snyk.io/blog/toxicskills](https://snyk.io/fr/blog/toxicskills-malicious-ai-agent-skills-clawhub/) +- **mcp-scan**: [github.com/snyk/mcp-scan](https://github.com/snyk/mcp-scan) +- **CVE-2026-24052**: [SentinelOne](https://sentinelone.com/vulnerability-database/) +- **CVE-2025-66032**: [Flatt Security](https://flatt.tech/research/posts/) +- **SafeDep (previous source)**: [safedep.io/agent-skills-threat-model](https://safedep.io/agent-skills-threat-model) diff --git a/examples/commands/security-audit.md b/examples/commands/security-audit.md new file mode 100644 index 0000000..bebe619 --- /dev/null +++ b/examples/commands/security-audit.md @@ -0,0 +1,243 @@ +# Security Audit + +Comprehensive security audit of your project AND Claude Code configuration. Analyzes secrets exposure, injection surfaces, dependencies, hook security, and produces a scored security posture assessment. + +**Time**: 2-5 minutes | **Scope**: Full project + Claude Code config + +> For a quick config-only check, use `/security-check` instead. + +## Instructions + +You are a senior application security engineer. Perform a 6-phase security audit and produce a scored report with prioritized remediation plan. + +--- + +### Phase 1: Configuration Security (via /security-check) + +Execute all checks from `/security-check` (the `examples/commands/security-check.md` command). This covers: +- MCP server audit against CVE database +- Skills & agents against known malicious entries +- Hook exfiltration patterns +- Memory poisoning detection +- Permissions & settings review +- Exposed secrets in Claude Code config + +Record findings — they contribute to the final score. + +--- + +### Phase 2: Project Secrets Scan + +Scan the entire project for exposed secrets and credentials: + +```bash +# API keys and tokens +grep -rn --include="*.{js,ts,py,go,java,rb,php,yaml,yml,json,toml,env,cfg,ini,conf}" \ + -E '(?i)(api[_-]?key|apikey|secret|password|passwd|token|bearer|auth)\s*[=:]\s*["'\''"][^"'\'']{8,}["'\''"]\s' \ + --exclude-dir={node_modules,vendor,.git,dist,build,target,__pycache__,.venv} . 2>/dev/null | head -30 + +# Known provider key patterns +grep -rn -E 'sk-[a-zA-Z0-9]{20,}|sk-ant-[a-zA-Z0-9]{20,}|ghp_[a-zA-Z0-9]{36}|AKIA[A-Z0-9]{16}|xox[bps]-[a-zA-Z0-9\-]{20,}' \ + --exclude-dir={node_modules,vendor,.git,dist,build,target} . 2>/dev/null | head -20 + +# Private keys +grep -rn 'BEGIN.*PRIVATE KEY' --exclude-dir={node_modules,vendor,.git} . 2>/dev/null + +# .env files that might be committed +find . -name ".env*" -not -path "*/node_modules/*" -not -path "*/.git/*" -type f 2>/dev/null + +# Check .gitignore coverage +[ -f ".gitignore" ] && { + grep -q "\.env" .gitignore && echo "✅ .env in .gitignore" || echo "⚠️ .env NOT in .gitignore" + grep -q "\.pem" .gitignore && echo "✅ .pem in .gitignore" || echo "⚠️ .pem NOT in .gitignore" + grep -q "\.key" .gitignore && echo "✅ .key in .gitignore" || echo "⚠️ .key NOT in .gitignore" +} +``` + +**Scoring:** +- 0 secrets found → +20 points +- 1-3 secrets → +10 points +- 4+ secrets → 0 points +- Private key committed → -10 points + +--- + +### Phase 3: Prompt Injection Surface + +Analyze markdown and config files for injection vectors: + +```bash +# Zero-width characters (invisible instructions) +grep -rPn '[\x{200B}-\x{200D}\x{FEFF}]' --include="*.md" --include="*.yaml" --include="*.json" . 2>/dev/null + +# Hidden HTML comments with instructions +grep -rn '