From bce2a5672c840ee021f2b3b8a6e9ac27927d0527 Mon Sep 17 00:00:00 2001 From: "qingjie.du" Date: Mon, 30 Mar 2026 17:39:13 +0900 Subject: [PATCH] First running version --- README.md | 125 + config/platform.example.yaml | 31 + dev/Flow.png | Bin 0 -> 210360 bytes dev/Platform.png | Bin 0 -> 260481 bytes dev/build-detail.md | 723 +++ dev/build.md | 18 + platform_impl/config/platform.yaml | 57 + platform_impl/package-lock.json | 5183 +++++++++++++++++ platform_impl/package.json | 30 + platform_impl/public/passkey/index.html | 117 + platform_impl/src/a2a/external-endpoint.ts | 125 + platform_impl/src/a2a/local-bus.ts | 74 + platform_impl/src/agents/base-agent.ts | 243 + platform_impl/src/agents/director-agent.ts | 206 + platform_impl/src/config/loader.ts | 49 + .../src/dashboard/dashboard-server.ts | 359 ++ platform_impl/src/dashboard/favicon.ico | Bin 0 -> 71870 bytes .../src/discovery/mcplet-discovery.ts | 101 + platform_impl/src/host/audit-log.ts | 34 + platform_impl/src/host/mcplet-host.ts | 168 + platform_impl/src/host/mcplet-router.ts | 39 + platform_impl/src/index.ts | 44 + platform_impl/src/llm/claude-adapter.ts | 83 + platform_impl/src/llm/llm-adapter.ts | 39 + platform_impl/src/llm/openrouter-adapter.ts | 85 + platform_impl/src/passkey/api-server.ts | 168 + .../src/passkey/challenge-manager.ts | 126 + platform_impl/src/passkey/client.ts | 233 + platform_impl/src/passkey/fido2-backend.ts | 268 + platform_impl/src/passkey/index.ts | 31 + platform_impl/src/passkey/mcplet-helper.ts | 111 + platform_impl/src/passkey/passkey-server.ts | 210 + platform_impl/src/passkey/platform-service.ts | 262 + platform_impl/src/passkey/storage.ts | 118 + platform_impl/src/pools/pool-registry.ts | 79 + platform_impl/src/types/a2a.ts | 48 + platform_impl/src/types/config.ts | 70 + platform_impl/src/types/index.ts | 3 + platform_impl/src/types/mcplet.ts | 58 + platform_impl/tsconfig.json | 18 + reference_impl/agents/agent-base.ts | 225 + reference_impl/agents/dispatch/index.ts | 77 + reference_impl/agents/info-gathering/index.ts | 109 + reference_impl/agents/planning/index.ts | 108 + reference_impl/agents/platform-types.ts | 33 + reference_impl/agents/register.ts | 22 + reference_impl/config/reference.yaml | 105 + .../mcplets/info-pool/api-access/index.ts | 48 + .../mcplets/info-pool/web-access/index.ts | 45 + reference_impl/mcplets/internal/crm/index.ts | 56 + reference_impl/mcplets/internal/erp/index.ts | 46 + reference_impl/mcplets/internal/hr/index.ts | 57 + reference_impl/mcplets/mcplet-server.ts | 125 + .../mcplets/media-pool/email/index.ts | 71 + .../mcplets/media-pool/site-access/index.ts | 35 + .../mcplets/media-pool/sns/index.ts | 60 + .../mock-services/data/customers.json | 42 + .../mock-services/data/inventory.json | 37 + .../mock-services/data/reservations.json | 62 + .../mock-services/data/weather.json | 16 + reference_impl/mock-services/server.ts | 200 + reference_impl/package-lock.json | 4866 ++++++++++++++++ reference_impl/package.json | 33 + reference_impl/tsconfig.json | 18 + start.sh | 141 + status.sh | 64 + stop.sh | 66 + 67 files changed, 16503 insertions(+) create mode 100644 config/platform.example.yaml create mode 100644 dev/Flow.png create mode 100644 dev/Platform.png create mode 100644 dev/build-detail.md create mode 100644 dev/build.md create mode 100644 platform_impl/config/platform.yaml create mode 100644 platform_impl/package-lock.json create mode 100644 platform_impl/package.json create mode 100644 platform_impl/public/passkey/index.html create mode 100644 platform_impl/src/a2a/external-endpoint.ts create mode 100644 platform_impl/src/a2a/local-bus.ts create mode 100644 platform_impl/src/agents/base-agent.ts create mode 100644 platform_impl/src/agents/director-agent.ts create mode 100644 platform_impl/src/config/loader.ts create mode 100644 platform_impl/src/dashboard/dashboard-server.ts create mode 100644 platform_impl/src/dashboard/favicon.ico create mode 100644 platform_impl/src/discovery/mcplet-discovery.ts create mode 100644 platform_impl/src/host/audit-log.ts create mode 100644 platform_impl/src/host/mcplet-host.ts create mode 100644 platform_impl/src/host/mcplet-router.ts create mode 100644 platform_impl/src/index.ts create mode 100644 platform_impl/src/llm/claude-adapter.ts create mode 100644 platform_impl/src/llm/llm-adapter.ts create mode 100644 platform_impl/src/llm/openrouter-adapter.ts create mode 100644 platform_impl/src/passkey/api-server.ts create mode 100644 platform_impl/src/passkey/challenge-manager.ts create mode 100644 platform_impl/src/passkey/client.ts create mode 100644 platform_impl/src/passkey/fido2-backend.ts create mode 100644 platform_impl/src/passkey/index.ts create mode 100644 platform_impl/src/passkey/mcplet-helper.ts create mode 100644 platform_impl/src/passkey/passkey-server.ts create mode 100644 platform_impl/src/passkey/platform-service.ts create mode 100644 platform_impl/src/passkey/storage.ts create mode 100644 platform_impl/src/pools/pool-registry.ts create mode 100644 platform_impl/src/types/a2a.ts create mode 100644 platform_impl/src/types/config.ts create mode 100644 platform_impl/src/types/index.ts create mode 100644 platform_impl/src/types/mcplet.ts create mode 100644 platform_impl/tsconfig.json create mode 100644 reference_impl/agents/agent-base.ts create mode 100644 reference_impl/agents/dispatch/index.ts create mode 100644 reference_impl/agents/info-gathering/index.ts create mode 100644 reference_impl/agents/planning/index.ts create mode 100644 reference_impl/agents/platform-types.ts create mode 100644 reference_impl/agents/register.ts create mode 100644 reference_impl/config/reference.yaml create mode 100644 reference_impl/mcplets/info-pool/api-access/index.ts create mode 100644 reference_impl/mcplets/info-pool/web-access/index.ts create mode 100644 reference_impl/mcplets/internal/crm/index.ts create mode 100644 reference_impl/mcplets/internal/erp/index.ts create mode 100644 reference_impl/mcplets/internal/hr/index.ts create mode 100644 reference_impl/mcplets/mcplet-server.ts create mode 100644 reference_impl/mcplets/media-pool/email/index.ts create mode 100644 reference_impl/mcplets/media-pool/site-access/index.ts create mode 100644 reference_impl/mcplets/media-pool/sns/index.ts create mode 100644 reference_impl/mock-services/data/customers.json create mode 100644 reference_impl/mock-services/data/inventory.json create mode 100644 reference_impl/mock-services/data/reservations.json create mode 100644 reference_impl/mock-services/data/weather.json create mode 100644 reference_impl/mock-services/server.ts create mode 100644 reference_impl/package-lock.json create mode 100644 reference_impl/package.json create mode 100644 reference_impl/tsconfig.json create mode 100755 start.sh create mode 100755 status.sh create mode 100755 stop.sh diff --git a/README.md b/README.md index 8fb5e27..49a0a5e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,127 @@ # MCPletA2A +MCPlet Agent Profile (A2A) platform implementation and reference implementation. + +## Directory Structure + +``` +MCPletA2A/ +├── platform_impl/ MCPlet Agent Profile Host platform +└── reference_impl/ Cancel-rate reduction scenario reference implementation +``` + +## Platform (`platform_impl`) + +Implements the MCPlet Agent Profile Host as defined in MCPlet-spec-v202603-03. + +Key components: + +| Component | File | Role | +|-----------|------|------| +| MCPlet Host | `src/host/mcplet-host.ts` | Main orchestration entry point | +| Pool Registry | `src/pools/pool-registry.ts` | Pool membership + per-agent access enforcement | +| MCPlet Discovery | `src/discovery/mcplet-discovery.ts` | MCP tools/list + validation + hot-reload | +| LLM Adapter | `src/llm/` | LLM-agnostic interface, Claude implementation | +| Base Agent | `src/agents/base-agent.ts` | Abstract agent with Passkey interception + tool loop | +| Director Agent | `src/agents/director-agent.ts` | Cron-triggered, anti-concurrent, retry-safe | +| A2A Local Bus | `src/a2a/local-bus.ts` | In-process inter-agent message routing | +| A2A External Endpoint | `src/a2a/external-endpoint.ts` | HTTP endpoint for External Agents (Bearer auth) | +| Passkey Server | `src/passkey/passkey-server.ts` | localhost WebAuthn ceremony page | +| Dashboard | `src/dashboard/dashboard-server.ts` | Audit log + tool/agent visibility | +| Audit Log | `src/host/audit-log.ts` | In-memory action invocation log | + +### Setup + +```bash +cd platform_impl +npm install +npm run build +``` + +### Configuration + +Copy and edit `config/platform.yaml`: + +```bash +export ANTHROPIC_API_KEY=sk-ant-... +MCPLET_CONFIG=config/platform.yaml npm start +``` + +--- + +## Reference Implementation (`reference_impl`) + +Demonstrates the cancel-rate reduction scenario from Flow.png. + +### Flow + +``` +[cron 07:00] Director Agent + → InfoGatheringAgent (info-pool) + fetch_web_content → 天気予報 (明日は雨) + call_external_api → デザート在庫 + query_crm → 高キャンセル傾向顧客 5名 + query_crm → 明日の予約 6件 + → PlanningAgent (pool-less) + query_erp → 在庫確認 + → 無料デザートキャンペーン立案 + → [店長 Passkey 承認] + → DispatchAgent (media-pool) + send_email × 5 → 対象顧客にメール送信 (Passkey strict) +``` + +### MCPlet Inventory + +| MCPlet | Tool | Type | Pool | Visibility | +|--------|------|------|------|------------| +| サイトアクセス | `read_site_stats` | read | media-pool | [model] | +| Email | `send_email` | action | media-pool | [app] | +| SNS | `post_sns` | action | media-pool | [app] | +| 外部Web | `fetch_web_content` | read | info-pool | [model] | +| 外部API | `call_external_api` | read | info-pool | [model] | +| CRM | `query_crm` | read | (none) | [model] | +| ERP | `query_erp` | read | (none) | [model] | +| HR | `query_hr` | read | (none) | [model] | + +### Setup + +```bash +cd reference_impl +npm install +npm run build + +# Start mock services (port 5100) +npm run mock +``` + +### Running MCPlet Servers + +Each MCPlet is a standalone MCP server started via stdio. Start all: + +```bash +node dist/mcplets/info-pool/web-access/index.js +node dist/mcplets/info-pool/api-access/index.js +node dist/mcplets/internal/crm/index.js +node dist/mcplets/internal/erp/index.js +node dist/mcplets/internal/hr/index.js +node dist/mcplets/media-pool/site-access/index.js +node dist/mcplets/media-pool/email/index.js +node dist/mcplets/media-pool/sns/index.js +``` + +--- + +## Spec Compliance + +| Requirement | Implementation | +|-------------|---------------| +| `mcpletType` declaration + enforcement | `MCPletDiscovery.validate()` rejects missing/invalid | +| Visibility filtering | `PoolRegistry.getToolsForAgent()` filters to `model`-visible for LLM | +| Per-agent Pool access | `PoolRegistry.canAgentAccess()` enforced in `BaseAgent.invokeMCPlet()` | +| action + model-visible + no auth → reject | `MCPletDiscovery.validate()` | +| Director Agent anti-concurrency | `DirectorAgent.running` flag | +| A2A local bus process-boundary | `A2ALocalBus` — in-memory only, no network | +| External Agent auth | Bearer token validation in `A2AExternalEndpoint` | +| Passkey Web Page (localhost mode) | Dynamic port, loopback-only, auto-close | +| action tool Passkey interception | `BaseAgent.invokeMCPlet()` Phase 2 intercept | +| Audit log for action tools | `AuditLog.record()` on every action invocation | diff --git a/config/platform.example.yaml b/config/platform.example.yaml new file mode 100644 index 0000000..99cc7a1 --- /dev/null +++ b/config/platform.example.yaml @@ -0,0 +1,31 @@ +llm: + provider: claude + model: claude-opus-4.6 + apiKey: ${ANTHROPIC_API_KEY} + +pools: + internal: + domainAllowlist: [] + info-pool: + rateLimitPerMinute: 30 + +agents: + planning-agent: + class: PlanningAgent + accessiblePools: + - info-pool + - internal + description: Plans complex tasks + +# Enable Passkey authentication +passkey: + mode: localhost # or 'https' for production + rpId: localhost # Relying Party ID + apiPort: 8443 # REST API port + fido2ServerUrl: http://127.0.0.1:8443 + +dashboard: + port: 8080 + +a2aExternalEndpoint: + port: 9000 diff --git a/dev/Flow.png b/dev/Flow.png new file mode 100644 index 0000000000000000000000000000000000000000..21f466e3d0525ddd0664ed23421a1e3cca500482 GIT binary patch literal 210360 zcmb5V1yCH_)&+_NcXyZI65K6VfZ&7c;Ow(791Q36b=q?9Q7HnMScLU z9}W&v&0bFKwX&QX?Q0KL8+#`(9Gp^Yx;_d>dyqKKNQ({$RbE={`I{v?jpa7Pk6$Zs} zcXfJ8E}eD&Mk#_x-TiT#z>nKNfJ?E9nTqs~q3)A{f76Kmr6ve2M(g{>v7t=16T=v9 z>v5SF$24K>NTYONlSppt`Mv=Ux)3BdgWR!9Fv6z^6o0)iT7unii@GjldO}s&%eQkZ z+^$i$YYMmv(iFlhCM9F)e^gk`T(fr=vV%glQ1$xxK;Pjln_px~ZU1>S@Q2I4Ic`-1 zVxc?sKC+L^D#|}Fji2FF>DeIF~8;WAHAuOLNC+-hh5NMRE(2MU;=kOSJX|!QGOvj~rKV$aAeH%1H~O zw&`83AfEz+j~F8cOs`zksY1g(mV(@m{d0D6FxqM$2^{PHPVQPOL@y|YO@EF7K6E^k z6a&Wc-VHy>TmE!#wYM5o0Y0pB&b>zIJ#O)uyM%p5D8zxoh2=*gb1B|FAdt#&L53bf$8c)RNU^PZqDlLY6F6?Gn0Ql2 zr7`KA;W@h_E}~rZ^sdg}=-K8Z24W7J^yeLCjVt>}H>v!lU(Dg+dY^d8hu|gi@agmY zm(X0AMRbRjwZ|qQo#-K90wFl;CXAfuw|6}sOz4KGPK`bg!B`JE6^>^J$ZHCPHD3>r z#?kcKoGW38Va?(Zfh#&klZR%{-vxOp2D}^_dtkehor_9r=}6R5xrkle&E*7`=H#c-L9QHrKoGxVdv9v3f>q^8GRSa zUwdjmc|Cwz?S~(>E}T)DT1x>p^e1`u?2^sqxHFt*q0>z@1hMPxcUM=}m|4?!A>93M zY$>$p4mUxkYe!AQUn6v3vU;D^+%_ZOIw`%bFLw~F%(0!!#Yela{NSZisZrht}i&v6vf zw>YTbDY)c4(&u;tefZUiIe3C=Z;|L%l{nrfe4+aggQQ7&mcpb&RzqGQ-#}OYJ^4G` zhOh_mj=T%~)jR49jSY#o&%58S9U=@ruWJep$@Gr=<9SbB*VhUpcyPP{x9 z4xnz2^Z7hB5rS#%KuW;hPst+)?JuYzkjT4J%r%Y~k5N<6K13Kq;LD0wu&mOq z5(Z_qpjF1o)2G_0c|{*t^6`EY&TL9(ifzjDOPEs*Qrc&Er*z90_+IFFTp!D3s)`bY zQme9}a;DPKmqu%W8nmAuDCO1ZRKF{1cz96Vpx)r$pxq!Uq*^MUe393TNE1mTN~206 z9zs?T+CZ*pn9IZ9=$%;!FKwvtX+Fn zuTguuw78UgIc-!vj?NGxGEG=KLGbeu-Htt>=Yl8+!LG3VY6YNGNd9kdx68#H>^u{zazUY@W z>K~OZ2L@+^d2Ef@!Wl+@U@A+)Av@ zdDMusig4fO-h&@e9#-5Wn$MaC5USq%dNcVZN&28GqHCxtP{u~)gUp3YaCb$w=iB5+ zT-hF3y-4G2vJ<2>LsPSFfxqv^Q!REa+%3{AaC#1Uz^j~icJg+8*)d}8GTy!a{*@KC zKi-hQTWDT1z~+36w=e5=R%zBiHG$=Je_oPRpIUNRd?3{kO(*@MPq2d5ol-c|UDWA{7{Bhn+R4Wk1}~)@>da2RpLWzPFCNVc@X7A3 zTeOcZo+>^orcq+}!c;U<6uhB$Qg-vO({`S?6O2${-u|n3T%$>Ej^UKJoLFM;codX- z@?uKNQ_V&r!&T2;uQH3hg0OQ0dvN*v12YSot^TOAi`LF?8L^=>Lk4a)0V+%9?r@Epl!YhW1_4~|Rc z-nPRgLyeH)3Vp~?DQczNvU#<|W>j*zLArj~ec7eUi^V3d^^a;jYMFv}&MtG7bwy6Y zcjas4LJi2Sj*x~@t`+q~)2fG)q&}+RQ1d^pTc^xze~xOjGPbrjSURf1T4rG|GFbUH z#XX`6iB@f2vqgfc;^ywp77M0Z%QeB~`IalSG*cmM4N^{_3-Fg=QTZI9^L{DrRdsmw zIa719X*1I^Ig5+_tmm(d;`N8S^Ql6YXB_4Yy+K#UaSYQ8{ff_$h^Y^xm?dC=;%C>r z4Li<_8m}bXH?2nole8_0NAK~^hhwL5rWD8g^6e$|{4d8vE}OrexolG`m@MEt?%wWo zV>c#2F%C(xxdV)yc5Jbqt;Q*eqnW z%+_?VdRZVAAy(uoaFnsa-=_cY@xV2(b+H9|1*d7{k@m3rAUZsHjAoD~c%LieRiN=> z--hym_I7c(gp349zM4Pm!T9!G&UNs}u+ufj;%u#0>i*I0=;Pw-gVv?TuQ71tx!J+( z@MdMhdg73S_ z;hv=_e#C@(TttTBB!hbP@g1 zTvhn(xei=`JzQTPoYz|4JJFyF3UOaH47@z7257L#m@3Mjuir+$nB7RUAgkz-@U%RT zRGYm;dzj$#0rHDDFi6=(O%09>SVx6Jf+vSV2G-z#uOvLhf3LrUXN5!jXFCEMT(mtL z(!Y;U2bNEt6yW>R=3h(1_fc>tz(0K8>-P!azm7(MenR}Ob;NOCADoP~oU$^o)VA^f zgIzrBT)p;{X~IPXRwzAt)H`#i>Iic1pPlphyv?Ro4M&}|2f3VQGy<%_L^4C)dNf`$i>6O zLobO=OG_*6VQnL-CI9l@&4GUs^mbleZlc`WzP`R(zWiLS9=6=PA|fK(Jbc`Ie4M}$ zoSyzJUKW0wE}jhkI>~>XM;`2HUx4bAa%0}aoT%pzT_~e&$p6|%)euZo6a4VgZ$0scvFDHU+O!(9zn&?0n- z%RcnOs$T4^_o`g6MLYlTd8JwCX)W6bY!!m>5k&B^f-ism2s~;h*)p~H03Kof=wx}h zF=n7(RFg<9FeHAnky_nAVqlHeTaf*KyEAN5{@0gOb-rkt5I>0LTNE6@x6iQR z{$H=GT+8RNq2zf`Kb!s0rDgDy_(`9dgTl$K{xzKAXSmnD3zIRAsz^-z=oUM!*W$OhLvK{a zD89X9d>Z%PVW`JqLM0;sJ4Kn<2aPKoC`o#9_dkJPcVPFN(bfNe#+*f~uNt^t9o>A`vNwXsKVtqh*JnOOC*Q6hc4RE{@hpi}>@6+N zO6Z^Vo7HHVo`dU?^&h~=oNV&^ZO*2(H8#l$xu;GBXj~<4HVF8ayrv>Un^0^Q3Dkux zgb&-UZ+2Z2$j`6^f1LsYK<0LHKBdts#lg0f<2gFn>OLy6{WMlAdPkayRNy4B!zPd+ z3-vXJ8n)!Mx#w<4v5%$i49mYPiWLq1JE2ngmnPRY)-6eq|JeSgT3qRyz+ukD1aEZL z*Y}6%|8ZXY_Ck_R$P|_{3w`izQgYiXZ-hGZi~4*|p{uTgAS(T^N)ln-^BVYC*?u{{ zH7a%lX${?j)F$2Rnf)>Jy;0}7-umb&$n<#ilET^ArFk=BZX6gl1OA;asZmH0L+GsJ zY0p#su*%*8$Mf-z3KxC=XBh03F5B9BK*?;g5V3_nRov<*{c9GrAcmDycFf-&`gW>% zUv6fa37(Bfg|eBT0Ryk2_^a(~^ep6Ue$eTl&1xh`g(=9^k^YVBF<^pu-RBp}k7OUilr~0n{=7KH5?f>=CA%Dp zLU3fic{@+w%-b-Evth0Wn1ce|zVQkk#KVCFK{uP3Hm8Fu+}?J7ZpK1KfFYwX{Ms7l zUWU!vu~*TW9naOm`pV|S<-Ia<$-TR=PF2+Q(SmEIKtd$4EaNVpdl)h?k6G}AE@W2< zIDyScKS^>?Gh&+JGfdK7*u4i#na1xuhDnD%{o7Ui4nXot9(ghK>KVA_+b84b_qo7? z46{U~3_hQDHm0iV57;>7ify|tb?E)cabrJlBtgKc$HL9lM{c6HZ{#ms+b=ToyS;&_ zB~+-GT%lLTv~B9YNz}UnsU3B&`RLqmdF6x-s}X$l%Uz`xY2k zOgfR};471}<-ns47cir-U(T=SpQhOVb*;2G2=vgiPdcfi$*VvLzDjgCYQGY+%@6irlVFGM zx0N+Kq2OkV;3pULvU^d&dDk0_Bh-4(U<7d{w79|QxwMtKGuSsKLrIxZjs&H>ss7@c zfm<54qBEkXRr;`{v^7)xSARVDVZ3#D+*-xw&yWxYe>}JTy_32xvi?g z?2%<<$bG{w_>s21#3=u(1o?2VX7O-d-J<4USt!-5(FEi>d7MnXB20XAX-mk!fqvLPpya~F_t{H$Y?&hfZ zPX8QLUF_h6=eP_?(PSADZualmG0AxFP8zPXq@_4)!qg22MI^6kqFDbjBUU`1%b3E+ z%F#(amqBXc{MTYx3I=U1f7%KqOI(7Q5_7Ltx{36SEvh zCaO08n7B&;?-rd|tSYGCSHb-U+q@E;;S-?CiKrWUEh&BDG!;^w;&mkc84+Wm{OtwVAHeN3&0u-LH{=F^#niA?5x+8ZE}SLoJ}z zx>>rC#S3SZ=CxM>dS1nQbhL@H@_7q&3>^WA@DOS0(?0nsVQn*40_hu{2NRO)C zr_9|ftUMC4CCR61vI1@%t3bJEe~SB-goxuXS^V_7oz`kFv62Cy0^J)CWwuWn<+w~( zYrA|tJv?bdB&WWecP6Ap{6BH>q*$4iT5#agH~|<$>^cAhIK#J=>KZ8<^}`ZjvOg{3 zIbj4*#k?S-yuicep}SuA@SaH^z<*r3oUQ-tyiM1YbM~mgrs8F)A=aoEdcRKdqbm&2 ziYns!X70pCWMmMHK>*-wvVag$fcqk7j3piG=0`?f`|BbmFflKeW!o23<(a=jasU?K zNk59uG-X2h1b0Sp>G4T|l%IbjwXJsVdIMi=1Ddm+uHjKm5ZYB)+SaRQ!Cg-QfsMYd zYrffIWUFjDjSEYtVB(OL>l08#r6U;2Wt%0}YqG@w>Tq>`Hiom_Y=vj~bwuo_?eliThJ=v@ zg|f%Q44vg7-9+%hvTQ;p5NMtyqx+e<_XLmJ)p7LW=~p%!$h_HRtxnc#ibK!i+5()g z-TTWx9)yuUEqfJ?sFmU2bCD#bcCS&>3FW%B!#jRX+#cJr6my^%#& z={(2)Q0lBP;2l?8#R%#B8t~0>q&mEZlX#Qp59g|_*n7WX$%YAtiQ^q%<&oXv(Z{;F zbsXK8#0LhYe~)idTgZ9G06fou62eJtaP<~upe;zmE$SGC^v*3hU z-Rwj&LCZ2qwl`cu&OYjhWpq^*msX9K_%0F6`K6bL24DFy*k`b!LdvdM?v%UB8|H@= zG*lCWbSlvsap3oYd&G*39buMj!Bmd2!>~d*2M8=TfWS~I{Xo{dq$oq>$BFl>$!x{p zwA~EKU zIrVioR&z@CcFQWc4Ao}08{^8KQ$E8YpT1b1g!>N=;FB*MZM=J{>?Ha>nTwjx5}~8R z?M|_fhSY->$0%>cHvma1GUa;~B?(|vBW!0oR*bJ@3a^3?UJ0*8q_=fYaaa{r=eU=d zFxoUTP5ii833Ua6d)fFY8HOYz@ICQ*Mnt>;=H0Cp=fQC=ju2p`S{(5lP%F0x6k7mq zv%$DBWI-s~?>t9E1^^?MOotdtH7Qok2F&ZG)mbJ(#eMw?7W6;~W?mBtQGR=x_KZ>G zy4GkWt{xh7vRSDBNLzYB6W#(W@h2_jd%tB3V6I**EX`WB;(!VJ|3+qT_^c?5+5?A+ zEj#&ux({SsHh}xD4x{v**4%1ZPl_)}cRvPPRm7OKtlo&ob`DslM3h{fmTZmLaEaUz zV!_pMZOK0-ekPw}48(yH zsB3@PeC(eLI1MwQN0T#tcsL5J#7y18)S%H;6VPQ+6Z?;LE=nD?T!b>-F<~g=+70wY z-egT<1%p)vFH4@EB}Z~CX(N&u$C4??S;W-tbEGV8D)BmKOOPH!!8pJefAXRLgR99L zlZE1pr-}=Cii}^20}qeg)g;e$gCnEupkV>JTi@q5gP!foJNjTlq+uDnc3bnsa3%zt zTj#=txYr}1Yj&D_LA74gotejiwbvZLc?;&v6Zp9Farq+$^h1$FZ&cACRURiS*Fj&c zKz9;tRPxU0Xl1Xmb6MBwd2Ov+6sGbIZc}~obRg`CH35k(Vwn>0v5TR37&6-d2%&mn zSGNNR2@?MG>Z9Bd7eQ{5Lqgc{N-t8)$8?q7p7of-Rl?>Dv1MDvo|8}qq&((?!#YHzb2~54 za`xHm=!7E8gLV{Upz>^elQg%SXd>x~|8}l6XhyZ^Dc^?2IG<3^UFoP-LBE`Lto${p z%8lj3vC#z;!da9hUwF!Nf00SsAyee@R%QGW*!x1Y_!%ab7fZ^$K6D5X4WQt4X-`KI zT=v?PBm-cqt=g-^4ox&*?kpf^^NW4E*BZ_lGiV(;?3Y&_n>{2HN^ zpsB!M2>_ixBIs%buY~2^-iK`G`i4J&2g*C(=Be(_^8Y~iYJ!TdzitLjFJ(H>LCVnL zT7jfFzYJUwFlu;@0&|p~+j6S?q2~}&UW&Dl+QwdB_3#9A%VI_`;QyjZq)F%i?AV{0 zp3v`P()(;eA%xf+5_mC`?;S~fSvAE01=6Y+6`CFHFJ=t%mTiIoA6+~Ao!&)(*84O@ z*i&99mu>&9&upYN>rkhM()e$@dvnLu@+opgaMoU;rU#w9Z#ND${Ky@0694OoPLOV! zE(k}yGjuH1tq+;+Qh~L&aqG0loXEO)D{L*lOyGYm*@H4HLA=wdAfIq&yIYtnc`A8V zfP{1;OrgR|DjDQg_2=;p1xTn(c~*kXkOeVg8l6sWa>Td%7nCjKHX_!0%eul)s7WzN zd1$K+m&Hor)s8T%@-5?@myT}tU~n5>iM8z@{(kc;XiQmYWSPs4SxFL6xI*#gxNqWe zz+O2OO0~CV-YJx4n4=cS&tZrGh+b$C&hq)aK`Rx_TiLuEwpkWY*?No7R6Zb(4ZxwG z#TizF0(iO`UzG#TF?EGU-_#$RXYnFOvCpp;w-n*;E>~puM7r)1`6XSpO{cYs1d8!Q zee{sVEjTxt{NTd%OwID^gXY*|+b5V%ekZcZ@$-X4Iu?bj5gXyRco;hmm^QPjla`&h zLX&A+A*ww*UvKgs&x;-UcSRNR)d5ljWY8*Xm0=cg12Sw!83biasR@|~qg=o;bw>@Q z$Q)&~M4U+qd*=4jBSd{6^@^mfnSMv=`?9Ikuz|y>EtugfnPsSA|NHMzO$&)C#eJkK zk3#F!E__yU^vi<0!trrT*026NKJdpocRpN3fwmTh6H%`kbhCL!JTn%(rqrN@?Y6n< zMMi5p2{ifQ-TczLKB?cl2Haiacn@tNd{ay)g~U4xdib|%hPmRIz4tq?{4F5fkjBt9 zZVs|tiCGH#r!aQBKrgDd*CCj&=}3f_$fQ_MOupPmC#dBfPEk=8h7Or&qs#NriTOEv z)+&U?8|RP0yt1T;>F0aWQNIjdFzCFro%=&z(Pd|Y6bNyGfVXosqODPBg9cD3*E@5T zCStj!t5jz2{IpIb+bf~Z=r@$3pip7UfE^;1eY0->OkvuU@-UyhqN%{)mDiyZ#Tt9i zVfaF#(6Sxmv{>YF&guuv<8k!d_{(H!XFomLK_I!X267kyE9DEGVfuIu%O`88>VWWZ zEwN!nHW?nNay?%>T{x&{J>-Mk>2kD_p`g$NRXwp|?7Bt@@K){5bdu^B{z~9*5loV# z6{jvG>O2`dKnxyXbi&g4zZ#niIiXR+Oy+m?R=D0Z+eRT+x! z()rSZMUiF{2>+W_aoK`D!FMAmt_~A}25of_@Ean3vdQPf>wTgLN$-Lo1Mba6$&l8= zmXcfJhl~-_j=RIwfYOVM?uUTMf|dGy82;n3hswSL>iNrfcbi#TtifQDN|G2oGu|4~ zKiq46?Op8HC!Mj)E<`W{RUKPNtHQC)msd}o3FYDT0z<;fJa+Cm0&@@x;{ZuLY(K3- zu$87wqnf9`R~0|`_X&`qo6fye;lCYS1*tbDrOtj!DG8j=TkR1`u;}LYo_-Fv->q zP61r2J!S>j_%N^`;ok+1;_n)W&F4Zk!ZaP0@m5ly$3D|KtzCl7G zy8V9`4m%tKkD}#giw3V8XTn1oan}ctQHkY2U!JSBd>}=M-Y6i9zgGaSCkiETzL2>k zCR%)cYZ*+;1f>Z&?gp7G%zGg0w3WH1v8k`pw+bV4x*H{p`g3Jaq1BivJS~(7(@MlRQH!4D8;TsSNo9Dh8Z-@a z&K|@)k>cGPgT2)^O{e9Ax8&_Ei;uHrp(aff9miOq4|`@9vs0xAOR!woe#6#I^Imhe=Y9ID(Z< z0RIor^9BQ~aWZ`dBv87a9^J?!NGT;p9d|ARW*8mVc>rHl;&=ye&?n#n0ejXw@VkJ+ zmR}3~EqyK&%$<)HmF#CP+cxixIy;?%pU0Cbh9P<2_xN5PuXfW#Q{s>IK1Kgu_JbB? zM;Y61vCt;@a%i(iy-q=$ThrUg!JpRg#fb%B_?=pVYOw3<=+b3sKR%p}1#d2z7 zQzC4}3LFEg=??<3kMwo*pVfU$B4;D~R!dJb{wpBKwX(mU#_h}j`K!keDCV@(L}q#U zxYubp7xF^OhYhSq%-AoQsZ7uY->i9j z?Z9+hz1X7JIDOLL9N{WPHPXg$!?wOr+_H=E#^qA>XTq}yCc+6b+t?gvR(fW^-oBvS zjO!Fw_KHz)eZ&h``j@L5{6I;Bc3x=HM_tRCQ2>)g1xm2N2wv|0q?VX{eg{zP>RW-C zq+k0i4y>yqYJUP8W}-chu|P-=$9+}c#ZUr z((CjN2x9?Quex~jd!@;Jy~nB}6C&U?)#8k%CAV*{$|qEwXx9$_zhnb|7B5t`$g#__ zQi$+xhzKZE;_pP(P83M_6_2Ox9kh;3EiSCfKSo{lIwt^Xq=6N+Vq?4~`NZn=xCT1D zGZRtc@O5l96Zk52Bt!A?Gk)?S(U#CBrjd5{HIqCWXCkXMgYTuLe`69`S^x&}Z_(9~ zaM&0Jo%BBoPgk%+)qI4gc8>5(5Wr@>SXg{Vizfq+SDx5NJy_3U+oR7 z(v2S)y!2i)MGD~O#Xg0}&dp_2R4e~7^*e0d#*8TWB7!RY=4`(j_T`6tm$qXgu6kYt ziMp)8grN#_=;1W8^94XCT62^)Qs1xQgrcHtLr$)CrdSxq3~w;!94p&LfCM6Qck+qD zbV3c&38*Cq>JyHuf-N;y6aS*y0qCX`faHelA6mnbwKf29G|j(bpMcf)iJq@^(98+~ zXmCsWdhFN4zgoqfv-Zpj?+$JxiNCaXyGQr@i;N0Oq-!umMIQ*`WbS#0hFju7)?T$2 z1;yg0wpfoy0>UhS@{_Dx^cZgbG6xF?;t_molc9U@96+N9H&gkK)=ixYbo9`Lu$Fnk zzdU0dHb6I)_qJ4Ij7t3psvV#XoYrml5D7A`J`q!Ov|I_k5_sb0?JvAl6cTaQ85EOV zz`PrLSrua3Ijnx8#9@I^Gs0_s2pU03fq?-bDG*5;Z&&Tc1-x?G@oxYX7z*t#LpTTx zXG@kn!HhPE(JcmZF7@8V%e)3cInQMG0C2?P+Hv!>x+3ETq4p~ar#28jKzWlv?p~K3 z8<@^GtnU=(W5?3(_6KA|?jjR|x;W~_W$B*B5!riuZqUn3%u}@g4S;vlSOa3e8@bpR zcSHTLRiDS3Z6RO|dlsriZW<{k$c4*VivPJki}EozZ#YbpL*|S@&U?OS1QKf;3drog z=4@Q#i`1Z8~PprZOQ*&41Sl^8FU4BYnUY0tm7;vc2mDX4TRkjyT zj!S%0&USqH2y;3QQeYCz)NG><>_5`f?Yn;K=_VNlv zkZS>I?m09fT;NOn-PThDNw$&%$V*D5fA~_Xl%?!RHUpH7oCaf%J|p;7SJ+lTJeR}I zMunQ-B!z^#*P7XXdv+8$bCOFYs)RR82**=%?xC;)|B`P90Oq3-g7UdFZfKea19_i* zH>KyuyVzJJGLKnDv`Za{j5f^u0*4=+*2XJ?EcuHIE@D;*o#&IPVceGtyjT=?WsrA0 zKTHVvWSzd^dcwHQqpO$nff|%KK(bmaDpGjRR$-(!XESeAntV}z;MMn!*n{flIkG$l z1m0Lp(dGK_uSO_+d^AOW-B^^v-p_nViuJXZut9=(e6wlKNJF*yEQs$3GlUNq$mv_e zXXpmfe<~1iWcI__eBGfUVyk%$x!FX7%>XG2bxFNArXWxoHufCMG3<{%zHPfd9Y!pJ zy!KLxJT=;+cFi$zBqKW>Nqd14w!y!=G&ab|Yw2%eP*l+sRfzgjvU_9uqB_2|@9MGf zi@e??^#_-9M6EIWvY6LHpz`R{uBczAkiZQ%WBd4Rp6ZO$vw?Q&^br;N#(k9-|AW0+ zinsMaoUO{P!5w?)l5RgT=|(b{Tza!M3tuLpL$svL<;aj=Rxi!dy8%4^b?b-4cmn52 zu$}>ZQ1Xe1MY{qrtVd|S@Th~CtGSW}+=dvx=9nI@9bBy5EFs8gT>X&@ckAu8f3!Dg*X2BMd!T20gPHdKiJRX3$R z%rQGe5XZZ$Qa6+Fw{2XYez#nF3^=mB0oVpghrL!wb-|z3HgB;6-J%5=L6i!dFRJG0 zUm9yR11W->ql`Yb(5{dBIF(@A62Mf*W}ZyM?OPh#yQ5ZTs6*BI-q$;IJM?hj>z0pnwd{D|pmg3X9bpoSDAP3rQV;X3webB>j)jH~tl=i0UcJ_- zYU%_kt602>!Ll6Qkhj&i-1JS!^>N5iwkn#LXW|r`?=l^@cKzRM@Axb@+e!kRsncPI z)>kC8`>jyxB*HP>bNiz`Z&JL6s$CYqgF*%L{f5uFxg4Uo#xO`m4c?@nfj%=uW_{}e zXS_fO`_j(^OO5Aj$m)KdlR^U`vwCir?2D9dOSx8ax40*0>vd3>?yEbAk*q7ot4BxY zyX`iZ1ZD{Zan<&(BUU6HjKwcrm?ICJeG2{a*gRav#z5S)xIK8(?A-7ZY78U?YDZ8Y zUgATEH5zbio~oR75+)ifRnjb%LVCYJERBY!E8&VLk5%829#`pDk6H;a{kRwhq)8Kg z``VR32O6a()%@PMn$K#4sHzFf=p0tnY>FXYtu8U@#d4gVhZn~H1#-Uo#2At+ho0I< z5$iV1Rk3(qnMw5AW0V0(&sQ%T9r7KQ*n;)iBv#R4Q{W6%B1+J+b7HuUm)7ok_WUb?5 zW%+`qpfnr3EaB>ZXRvQ#DK{zS=K`yJcB@HkM^lN%l`)drh}V7G#k<}M24I0QW1CSN zmzbbKmdd-SUj$ay;<*op^^|K}q^vF`rBs{rMz@!`cl+=mB`x2Mst2ftjS_{-PM6~? zzu&ucq=L)J8&224)77cFOT|QO8jrRH*_4nnP%pOJ{T-dF* zSgQJhOAj5;2JdEPTw_nFvUEYpOCPy3mN{ofQ|RPMy&2Ao`8l8i$uu;EDO(4jc|qcp zRhO<&$A>2u7J#_H^`&R&St#n9aCJApLsDS^AnrWmS1n;V3CGG^7ykZ*-fa5j6Japz zo#4{J&5;imytE|teMWB+mao)q3tNXKdjJvT%#&c!Mbl%Jz@7-YEU}WtCPu@Vi`us9j05u$s}Tfk;MB8OHp|5TzL<-# zC3X%tBaA>-vomJH_~O#Tefz@HB|E`X0D5}DbEQ%(CptA}l!L9nhDpL}F5yO&FcAP4+x;|swzlCsETaedUoEc(-*#(E)S~=G`{MOcs)pnT-7kt?&#=P9{xE($BxTzE-Pm}cP8gLN`;{r|x%MEN zfiJ@VJ(NO51N`@d%S{F}SJ?T5K<)5Osf}-a#s`si)X(7B2ji7XARuab2HW)Fkig+R ztnFCSjq-i@_*c!8x`fT=>*dtxF(4je7f44)0K32_X5M2JgACdSZMSX~zr$ zFVRGgRoXqIlqf)yhGjl=7&<9seS!$@*9S;bf(eNVK+VB>rLB4=+1pq1j@+(G6PLtjzM>!!qP7=JA~7!cKwYmu*V{T| z4SFV#s|Zb`*na3(0ElA5t5z)Vz_(&{ihwek84_bRnb#YEVfSR0=2eRz6Tt*o+~!1o4fr5+?8nx3F|&{ zP~!493M9;oQVzG){zE${&75x8l)dG|{zen4L;(a}3Hf26nofYQ4_x3VxSmqFV>6OO zpm3^^aZs-nPfJ?~aCGP^C0#?2B`?adF?=KEMu1=o@am}f`Ks#LtDSd0U}{WBO7U&#iZ*tQei2Wqk(9oNaN3%2obW0NO$kOM0R?krnA98p@$AT^ zFgz@4b8$JtUynfd18&I?OGI4b9yX(IwiKAlw+txs#8Qnl1YZ;LVm~M87j4$S)LVpX zw`aK1Fsi4I3{9EO7oYhl`35wG9lJxe`jv91XUX=)fk^BV~F*tw1s&6ex)00U9l zFyx965-MN)OXR>adQ{-Uy~(<^kL(SDAMaB<*MjYPJc4Qe7dDf@Ow?ZK zlDEwona%{-xtXUcH?=H*bd==X;vPR28R0}*53g$h`7=Y%Sq+fj1)_EPVU>$GknrYhB7^`)9J7kiwV213KttT! z;c%DESd;L~1d+S_TuUq(q`&Y)uDbz5`xlNDGMXVifO*JmG;Ld8RCXr}4f@hlMtgHG zBJ^ywlz?#W7$|Cml0o!#q0t-^junaG&}EELT5Y63dqLE4{*B z?}+^1^Cev^Vf~a}6g#GxuP8Ov9rDfwDA3JaYud%MY^b-KKwc)WD0{h43A>r2vLMlC zjQA7#z2CUSQ>1(+!gN3jt#*nv<#!2;YMh!))W?*TK`(`>66>b0KeLRX)9)x5V3 zD9-cBmib~%tYeU8Q5qDi@)QRKLNaR5y$kKMGpgM3y}6S}c?%#mIvN;wU7qUahSoIr z$oRzuJ!ijxVhDB;py<*f5_(Wm0UipVeC@aejg4?5&R>@mv&~Q+IS83eaH<$9L>`^kQMu&L z?JhBje+1MK>r@ykqXy`8ev!&-O0G47%(}|%(W;XasI!V5*iD(okX5%t7tI>h0@j^* zXD@ckHccd5)4!x{<3CYjNV)Ap$myVE%{K>}z?|Tlh{RpH%6OjpDuG{}7_Tscv+prM z<;5eTFc@#WX-9+0&vT#nsA}YsIIMoAqV-9WAV`ze3}kJECUFOiZ%H*w`44Xaorbez zF#8#tZ*kLvk8^r;zuHsrmCrPs2`Kr<3|;V;iVP8^!NY(uht3~b5hiz}*V)G=sUtK) zak-4;jL>HNSj1d!XGPBNh1dx|2>I)v@Q#{mQYZ~Bc%8G9GOPH<6U#~}=HrwHX+Dz{ zw{32-H3qbEw#R@5!EaA&Gfi8|isgm2fa-~z0w@v(sC(<7Q1iT3iJFeSqBQ$WpB5E^ zHFj2}3smoQmCC68o>zgmxV)zLhnkj@llXfSmQu`rg8I}1_~?}r*0->Szqf_j-6)cH ze$BFsTLc$6KT&qo0YeR>8c=xa?v__OUY0r4)K=xNtg@BI%f^z=Pf~K;``|v|YMEGl z%3Rk=I(S@SL>53MHRR7TW;oru%V&tQ`6NQp=`@xti#@@Sy6355PPm*nz@ZkO^DcXC zM9fKt*EC@A5$yay-&i}Nnsxpa;Fmv{s`?tk>Gzi5#jkwXMw`WsL-GGY&YL8Qgwd9$ za%!-B8`HXMILXS}(NApTS3R&4IvHN3XI3*R1&DZ;1xZ=Pnrb!xrDASl?oZqNb_lbM zMm*keq#UaXNG?bERpEE!&u@zn@-QMI-LJA;RTB13KCWbdI&*cDTx_d(-Dq+N2!nm#y7NGI!I2wpjdwi!Wp}Ct` zqhpD6Hy$FwTU${eAp$|l72ii_0}e1Ev@RcYgbL+gf^ z-8~xnT|6VF;5VF{;6rJl1*ck2U|KnIIWx5Eo$Cz8LRsSH-y$&A$?H&{rHp+77F|Jdqn6!Egxw*~;1MC9nw6m|37Ua~RaXGQ)r{<|#NP5ge@r6GpY zRj{Yj>~BA83dG1p(oh;+({haVNKy?h8!G|buU=2tV68EMB{G!>tqT6SWKAM+_3v=e z2z0EO}=F^2@T?K21sBY1IGgTe_D9Yjm{ zz`G{0Lai4G#UJ{F$EpJ&BWF1%fp>GZ0?M$4fwx3_mRsCga}|MnkYmH~9n6211!vY4 zc3s)D7FRm+LN-Az1YF;`5^|^O-1vJCaCqYj#AD?(N{&h$kP|O@cU{8XHhQd$7}= zv(m`tJF_ya(>+g?b^%nXCo+@0nI9P%BSBCG(w?gjiHL@>vV;S`;qFsWqjz?!jMNR* z?gK9m9cQq!YxemWD3wzGJ-=+9UJ&a)dw>59$KOCL0Ff7)EXUZmo2}>-AZQbJ9C?xr zVivOUj;^J+S~vn~d?j7Q1hbeZ#^okV?+6c%uyn^dz5TrcVCn_e-~jKLs9y-NcW={A z%_!!;e9&QnLW^#4RkNmn$iV9{b`Cie`3emeDI`A_p|!+(XKQ&n5$>QW)WsNFmZ=${ zB|(+{hpw-V%WB)YRz#&6q@^2_Mp{z3ySw9|TTwcdZbU$&ySpBwl|~w*r9o2s*7m$N z&b{~h=lne8-fOS5=A2`WF=iA%4v(YVm^G#vbz*+L`xSWa;m2bsTqtJudbET4ICq$< zCEG7VqR$(Wa_EcTD=XD3ZV5{i}~IpA0F??oI1uAEXXu@G>!QJomY7V<+PQ zo$i<5-^&+_@FP&t^PWnHSC9O7JbEPnI)N`5X4#O za0<_3_Qs3;V8&#ZeQTTp9aM-$1^}0VNz~A%dJ8T-g7hL8Cki+vM{Xp|kF~5=$*`(hz)=p> zCc#p(m?SH;0<7=I+BdyUM5@t*=kLm~0(DSrP9JH_$P8_!n8iHZ@EW7_C9kTQ1gJ{Y zm*|JdUo&amrcN7p8f+2!gGQ&^%KnvsU8LP2)fk9rAM&wNLAY$?!{TkiK5A6FKP?pw zLptZM0KJ#XhsiVMi4j17{Pk+-)w(OXLDt%-e|DqH$il+9dUhk&WLyl8k|$Go~P%gF7^#) zWm*+zXF3sUS1Ctw0b+Mv^M&@7=9aahQa1xTGR@czg)iA6s#YZqq?rz z&J7#5=?yZ=X+8=EtI@Z2qR1u}wlw0uz2h;*J*{7DiOcY&@ur^@@tCdo2M!RI2`u^m z_C@4SRew`l-)XY5Si?(cqKV+Q9paKno`h|fhh4a(kxOKgh!#U72U1AqmSJH>mhX%B z{|CtRM%22@{$+-&Zcs-~D7h_5p_a`s8w=4cTbWD7eC1RJoQ+UD&OzSVY^_rx#%`|# zYz}zbP@=s@;Ka=R$N|_Q8AWL{rZI}BhA{b!EmeeiwGsWT&L4L5roKu;iH zE?>FTVa9>973w>c1Z!}djurM3n{Xa81EJ8qp~~n^haaykXPT1Im+qZ$oRrjH%brym&RUy9VBD-{)TIVHa(T(5ZZ6 zH{0!+n+cv(50JAZY*x;aRie|56g7Kf9N%x*6NU}fb@({8t56})T&byCxC#hcoIv#; z%d|kNO-t3y*-OteRaMFM%DAdh)q<+U?)rz+Vt=v_C33O+hK&8ArSTj}B+MC6 z{LvhLxt=-8Ks+0IJfSgmP_PlJO>J)jZD{MXypGp2v6Iebcuts{wQ1UGcbwnf*|RV} z$Glp9n0FkMc%ElENg~m@+1!Jsq@!dO5e7j&N4S$R!DSSA1ez3sbC$=%c0Vg=ON!Ci z&!1%%U{8CNyrUhKz7r{0Y>%z2%GQy10LW&n=4y^3BSmItl!-~w3gCi_m zI;L{+aN#vU$p<|Y5$6%+wZ2$Pq{nNnr9+$>@1)85^)zBfLm%Di8ZkF0XrO)xE<*wG zP!3l3C0nJe*Il+U|AtdQ*>DSA=zsr*vDl_3#%tWR`;H~jzPLkG$-R)nZ~9Wu>hxeq zB$1cdWGIDwC8hCz7jQlAFrN#W;(zM)TF_*Ca+;S|faV=$C2alW{Y*A$zj`r7aR+e| zC?u$AFs5d`1vw5|f3!XJerT@KIc+O4>a7#C`CP{PzhxQ=k+1X%>%I0PaMnO3>1_+^ zt5=@f;W7_Gk(`2#0yzT7anhf?k4)Ix%(gC#u+JfP*UZh1 zH829LJ@=HUGkP`w>1>$WJi)6f!MH@j!nhPD zxW`F2beM0H8Ck&Ox)Xr zF)r6njw^{6eA53qL;I8mP*H2 z0hcHX<2hNt^OHm0p=7CS=s51;H7wyg4s%~2Vpd|=vo&3agCCFAx#t^}zW6~38}dkiMbE1TX>D5-C1DWWWxQd2Mld$O_FKPqc}a< zxDSU!Gi(E5C+uJgvZN5X@Suff_459D!*}j3_5u886!L68St+lWEpy7B-Z;3sP3^P> zj=?SoVMj^w`NaQ?UDu%B?Io;l-_c`~G>e)GCWUltA?%A`s4`J9s|w#F6Z97Xz)mr( z)GWwwk#z+>++f<}m<@g^9wobqq3ik5MBd!)ojFiXawg~Ju);RNcpu@f>f+vOW_h;X zur>rjqgLSvTMx;qeln}a(YKl2P1)L{9($jtBUv-_ACN}F5@@YsCM$Yynxu_U~pbMy8v7$GNUD*>S=7*l9~8lZwmA z95kaKed#3DbfuvU__35(5q+N-t8=sln=D;uUr!KiQi0M=G`pg`{Nm$G3X8>Do$0SY zSvU;ZC|{Ag_ptpd_FbaSaK;a{!!#h8-s8%SaIM`QpOL36B5|sFZ7(+Vewr;^^NqUB z=^7KaJ@-akTLomF<(dNohe;G`jXP zHoLwia^5L!zx*agO86*wJyl zpp-$NMNO1R1^py+8cUrns_fb^^xw*8j3;R&lYM8?Mk4wh=j-CIo~EJG%%Z$-!g5h; z90#D?8d5?g@&(Oxi|T#1VW^XjL9+PalPieXc{{1jUC841^H_Qde8OP~=@f`FboXiL z_op?H9WvdgbkKPpQksztqb8H@%r6fw(VoyZlthHYbI}MR}&a2pr?un9%TJloy%m)&2 z+p2F7QOb_U1CkFM9?vzEZ%sY9$!2G!n+9aao#{(WLkf)XG@KEHzmebRlB4O5u$Yn# zvS!z&Fl)Kl8Mvi^e~(%NO%6uzvpUbvG~?=HcEHt)(Ehgy$13sN7oPL1dL+qQG{*kF zdR;pJ0dQX+zlI-6lpV1c{^`B-*K(uwx2G|2OIXV~D5zhLCx0Fpu7(*TV@A5SW&1?F z4~tjd=q$n;vO^w-C2?wjeHwbTn$ttLi!ui_%^t)e>U4Py0$HTFJwr+f3t9R;HGEKY z=*P@+U;dCTq6jOQMvzvcqhy>#M4veT?S3{>%rOdz!x<7vXWMnWZ-$lQ;wHmVA!Iw@ zvRPhG-p0}9G$eI+So@9_z5GE-Jh6)Ei#l3U!SENOf^ZTk)ei^AOWxTW+W;ofErffv zxv2h^SkMg(w3YM(@u}eBud0y}YK~dwc0imW_DrqbSB+m z4%|nqx^W`0a)!qylfIzaQb7{GxFzckT249mmS|xQFzi{@zc8`u+^0l{3o_;cY}|%} zXL1YvSEuX{cfBUHZ05W%-Ghu?Fm#k^DbwjJX_IW_h2QJ32N5qaSp?N6(T`FBCu!Ic zbuLP$Sz)D>A1*jSovmFb#VTx;=-zpk;7WT(`o7loq?oJZwtTVVUq)PEWzfR6KgLV@hq@B z=S#?sGrzxZ33IJqD*35i{+|b~7lOpm%0pZu31h{#sDE1m+AJt#4|+Ixyl714F)5CA zD-omO${RW@Dql&~ws3$uECn=@bK_c*4uQcoXSY(!yaZ#@`hQ!_m_`j*3jXa^py@C+- zdtTvqy8V`Wyq0HbRXf@<;uS0Eg)rsmgGyam5z41-Tgue{PWzQ$d|n|Ns|)K@{Mm6Y z>zUV+a1_LY<<2*`GT%l;@8FPrxCYwV;=+r2BS7RE*NyTaAtG$f+fG)Hg`JG5uEXRk@botsQGIm2&B_}?5(-z(#ms@uJ zF@Yz@S*NPW?opdbpCYO~{;o6({P{;@I5SNJhe=0U;IX;u$V<;X_MEzz zTr0zz9<5*Wv9n0f_Tn~$1-T=Z9aGeN{nm%h%gzex69D*)tbn)Y#mc~IPxUEnGxRsy zlBrat^RaXUPi0DUjC-k?!<_w1OL6h_#azj*^MK9CpaGqO5YSbjH;VN#`2la7BX@zC z!$K*2A5`wQDUzR7a3)xPnrl2Uy`eWJriDMmAhlLbVGystq7HE8c);Y2>x8HJR1V-` zFls-bTk$U5hhGc}Pj@;xXIko{yFVT`!d`Qn3it;6TUtX7UVS?Jbpnd~?-&QztaH)V z!c-W=U#vgJIg)BsU!ze50Ete>ehnFW+$0?U&eTXQ=|+m0C$|Nqk?!N*w+&Vl?V*cZ z+zF67^rc~9@WLUm1`#TZ?$ILfn~1PeSxN0V$e|MR3NreAHNE(jF-Ym+dg-^}1rfdJ zO*QXG-p%WPj$BmS}OW#A;)5;0^lEw z^IShQd@^iE?n&ze)?j5?7>LlB;PSDxoxly;9R>~?HqQOoc&2k=AsUenzagyh`!3NJise zy#$PUnc5NqcedShBzdI%vH0MFehp2XUYa%kHOffm=M2xen7kHcLs}S2-@OEyIby-l z3ziFSk*6U(o5-f5` zcyr;|_33)yGiIfpgUuc_Y4_-c<7A5e2(W4HPg$6i2$wzCg*R$`9UIXbOi{lE2>ysc zy8)V9qUU*-M#*ObB~7X3uvDFPTFf_tPuc~Gtr@qcP(&&s^A?4_+yYUac6BD?PNBER zMlsDI7Xma8<9ds6$c+P9gXXL=E$$FEZ8Bm~&hFGKwKwP zSmO=8pnLt4*mb{#q{X!#R-QFq?6S&{P5C%fI{r6jH_Lm>Czb{j^-Tf>Ul)OpKf7zl2Wcy!EqPLAmtQD2 zuvVY7_^Pa|PdD_z)SPn1^=Bb*JBP-Pkg~6g+*5Ot_1RYM3J9M=Ok>nz4lm+5m|T7O zMh;4=dd?NB6U%Kiox%@0n7X~M`_A}*CDKD4Kc!)xB8%lrJ8>lS!LbC_HYfS3F$|NN zDK&*cg~x7Ro>zKbLz;HmUqvN+2ve?V#;varHIM3#Jx{+%KfF0|=y&RNyfs79WNhN7 z+u|#gPFQ_a81$b}UIY7WZ-YUqb-q2&C7IlaPty_jXk+mWCIU&uB-WrKAmpML?5vEX zy7u%J_tBObAV%p-f%>VYvBXyYcbuLtH<2mdhgzlfuVXJkXI4CU6d0}faQIHHjf(sh ztg-LFug5K+gHakJt$!%iB3Q#f#?^H(HNnSc;Rm0N5u`)o67lJEOP_lA$hu2e2x??H zRTCR>qLHSbC7tNNb}BkLITjjQ?DANRW~pQNx&Uo>#*?W=mnzGe^lcG`$#qJ zqt>$qes`hHE+RRr>^}l*oRc=S#2P6Ucp=1$;Ds6_`E6Sx0PG|*Jg_HuCvtlfn`4nt zj=?hC7e%xtpuy(=R)Di%N^t-vuWdkOSZ3~`7i+<8NE)!jiBXYB!gWdZF2pTr7nJnmcxn>qp_RQT7h;#}s*T3y4bp2W_v#YO-Ty1@T&@#6yV+o=*2INGCM}QGu z!g{^{a!rE6mM!!ufVAX2UCpYLMRXu)b9X13!6JLU=#=y!Q*bScQ+3UK`n5(DgRa5k zjV3n7q~_Gg7EoQHK#bnQxo>CmjkP&c2*ooRwZn=c+t+aWC%tB5f)x5#U9!CjVzx}jN}Fw|IWOt!lIx{&+A887UqrYF{|v+m3as_BQk0}fqG?I zuhD3%3qAvpJn=5cuO5F_PKh2bEH*`5)I_|Esfb#lw_2suXr`p9{5}rS=ag6^`1)>Q zRnovjdJR4f=drJ8Tn27q$dFNC(cbJuc;g(Xk;YzPugzjjQNcUQv#xvL=Vh{lo3zp- zv~Z%v+SdauaOZKSRvGhq>gz+miRw*$vLS!9K({D?w?y; z^qh)9YsVw;L+Wci=lO$KuP}}D&V|K9Ekhk{B_VoN8Do%0M{BF-C$FJ2Wr{s6>6O@u z5c(Dix-MfkKq47MmsqtlXHcj|1rR$iv;JbjERVnu=jfUHaBZJz%mL?o$8d8qvwYv? zh{0Bl`Hwi?jC=95xIoF3Q=e(Qio#ri)znpIh&co>B|@RZMkm(UA*h4$<3lk7HxPcL zV6LuJ(+0&3!%igS}fc>qL?RCLeB+Z3>o9ZH*aMbNAv)~qD z3TUsVsZVj}7fLhNR>}Ll_@tbA)m6cKjzieK0-G7K6JS<4UP1cDZBx+?7bApTpi+*DkK2FZbhNB73&UYN;$XqH7 zG2@v2W-sw&4w&sO_AtM?aCvLaLMR#RwQ{{zpB=~$7E$|(drFlqZQ}42au!i1H79r+ zzP_MHDO_F46Xp&Ybe2euQq!J~{j@YCT}=#L1?GuVA-t7wI$z9SHIu3j0H@&zYJ6L- z80L- z4Kg}0YMD32%cNVVSvy$YEarAnjB(fR%uc=*U})A1WRTXc>~cSxM9 zFF@t*u+i;tvbx7-96Wy-p?iU#2AC2A{klp>{KyX1g~K7EsM-vS@U|_&MtI{?vql*1 zsB1MExM;kGlJp#j0+e*MRxQ+LC*3br$EJy~BB~f#jxtSJLsFnT;3QL{m~H72K$U&h zEkD;w6DDU;MIP8;ShXG5n*I82wYhmK~J$+ySBzk=t2JesP@O-WQU~@V~YTz z_AhAW82)nsFc(zqW!90Kb~#DZg&`f?sNqD5w}HwfRJO?ezr5Kdq(F7&5VbQ9cvcV{ zX;oRLM|oXULbIUjXD4^O2d(sa@?MOGkPS zFqksEJmDVPiMA8aQ#ZKYp0d~5teC=+qZ%Xgayw_ip zxC_n)sNjX(pn<(2z_cJM7|edu0>^o`NkjnC_G~*IU=Hz=QC*=k{1#-P)9}WNQ9R)0 zNE%Auy~8g6out=z_{laA(jj`UJ2C#g3f`?xjJ@lS+7cgJDDq;L+9 zaz4)-Dh2OK5ZOazG!LSj*YKmV_is=y+SnzdJP(81t*7HOS3y%HYegyUaUjDpMMj<2 z%|69vf8##*@Ioy0te2lPOFDJl%b=LEOocU+OHuGpl2Rb&c3lGL(Cl(rqe`a>L1fz} zWA7_q3e2B2G3H;AK*^SiaCr{+Q=#AGxLQm632L-wT*e%FE|BRnu$UAYZp~KWErNHB zXBwt+YOP$b-&HYK8N1K20Rsvv_B)S`WCGoK*69g^ERfI9vmVBgQw$U>X<-udYOeu8 z;?K5mjd8!oBs?tkEOb2r_K_}O)HXm4lJHnTu=2WH7S7y!iOm>KSYV)kaR5Z8=*{p^ z;(JqNo=g6oTQ~yDN?+XsS&d7x@fIoP(-|0E_&h)W-`8;<5`&#jLpNrR*CToTP&XCL z)peyHq~l|Djp%i8-a zxXxQMlM!T11{P5Z@Hw@9(oZ%VKmYKae%H0>E8gw} z7TE{d2iYFqY;xA^t3)iwod7|Ul5yl>2OAupGjM#QI3o!|-v&x-=tPqoOPK>9IS-5B z;V+>;sGuO`d8U`b@VXCU9?ggkzMqGOuBUzTI?IW3;lopRJ3i5L_V ztd{0*kwuc8O%Kvo5ih$f%M~)+;pTgqD_D_3B1>JWUW~$X3^}W?yR=IS%EzI{>p$6TgEhF?WewkL#9emE!^G1{V=v^(U4L_dfQtBVXdR zEWlkm#av$&bUEyNm=1bXt#OIxidjpmUXwY|mWHv3itgKrW3r^99t}##TrsacAHmtx z(f{_DS|PJl+97U<{`b${aF}gDrY{d3y~3grHt9q;e|eK~gnVS6L(wBU@(Vk@E)li+ z=1U)OR&d}}5?>Po!m{v;1I!__2FY`6weJv=CHol6dY{ep19;^sDwTC{uAGSv8u0q=z~PIo5$VclhXoIU4pMlZdzi-GHb~#224G zVR5EtCrI9pL#tw8oR5DyGmJI=!Yn7KD$`E4nr#sLD9hBe!VRU3z-+AQc#siK#jR3j{QA z+d~ZTBUgx_9Pa$t`8MsS8Ic)=$5`=Ni7Cjj=Bv~Os3bYPkZnJTz7<3Lc}*&*pOuaCpM1+z&>@RmQ@Pjz?&g@KlvS%GRo3Eu#-Cs7x_}Ndv3@q> z(N@m{QxeEst~JpJv-4G2uxIaD&o{s}Ad(U!ttnydu_)_{@Bn-k%8|-}A9qjA zKnhyT_&vjJ7Z~NC;F}(L+^HOe2_Z0w%Jbb;)Ub*}TZ$QMsRiAh2Ig@37@*hridFWW zpzziG1%Po9=st5*;Gr6(f*WK*X!hZvgi81q0?8oXgZdk^IqVsg2Pk z=$w4BLwBqi>(yKF6=tTl>RuAttX;m`mkScwp#bVFvZGv1cY_3c-7@d7w92cLrxCt9 zC-YpoVF)-Pxf7Qv(l&eHu~sidkMvzQLS_G)02cQ9v_Pb`u(t2AztO9Xz&*7(HOEnyX>c zu7LEN7H)8^jo1pfy6CcG+Vx^Aob}qBr@PamEI_UFfHqw)LZxg(aTcfi8nT(|IrW&X zMAdoq8tWwkH@39jtVJ?<-?txaX5qa8+>C-CrDxjqMiRZH>wY8}v*MmtkJQ61%ct@# zG>C!t+W{*Q7TcTaz;mXo2IUCb#P{-pya?vwz|+$j0t3EOD^-_H>T$Py*t=*;R@N0w z{h&rm)OB}y%TMhGkbE-Uj}+|TYZo|-!S$EUA%q4RXa;1vGZB>j(BjBy&@ZUR@D~hP z4jw{ITBGVCBmTSM>(m39pWu97lz0fZV&WImeb)ROXKp`4rC<^m@qoXFe2R2|O8cI8 z5)Cc06h)+-b|9BtSpOv;PWGm)c)gP(2nY86NI4wyl&hL;Xky>2eq94wqEH%ALsZZM zcB-I|LkXJyq>`Jq^D&Dj6!S5;?hwt~sBhHVVTm$=_s*+?&T~x{zC31^t;?Xr(4==pV1Py_R#DJiGsnHLpK<>}JF2XOClJ`gcYhtLZc*X6!k3}QQ7-J66 zL-YCcWbCkCk#6b{fdX-A?LV%^Kc$}G82+-U=yU|VVa>A=#qd5!`C+KXXxtk*DMpXt zhzJd_czc)q3(3MSg<{tjD0DDM{D96<=PxA9F5Gz#fyx zXE>sa7&`zm9Fkkb6UI>Kle3Thy|@P@voTGYkDe{+xaKbY%`6*d1~#3Ftp(pXuw*89iRcPqI+yV!UPn^Zz;YQ*u&-pt4CvhS);iSXi#Dr5bGs} zx_!30rAsxB8+hE;GXpmuCm^}0j7_(GF=7kmwS4|kbpd+S=nK=8%X5Wd^Y%|I9XnHI zyeARo!{WpBR)E4_-oAEHGrzY!#4W@x1|%YwJ zHceBu&`5VFuI;s|+qrNGa0znL8URp*PA8E_x9TO_q2P&seZAg|A;6MaVn+EE;>w}K z#mLNn`b0dk%sSLdx)mrpL+*ogLE_Fj$D(^Xu-O-1XI>13T#!de?ctx0RI1MxeM7Ch z3r_YCAAUYAaehjq!Kef2PLxp)gfZFrmuU03Ch}x4fY1<{p7PO_Uj1Ra#zRbUdqu$S z9qaU06Z3L4!S`$hg0FfxB@{T#0a%uUBT?hH`X0BN zkEwyE4ZK(P#ZQK3ZgG6QQI==nSIHpvPC&Rz_&iG{NR$;^F4JP4gf_twjyrdzS~;sL zOErT!SWne`(MtD#Tk-p5EYVrweCq&I$#npcvqK30S79!Y zwbq-{tJHO;>u~kpt}tKtC*md4A#G0dvwe^Ecl-&P@Nar?WSMKwa?9|nEM=|tNDcYl z6PLiOH{bwdaV8sZ;}B?kN2n?OSi;Od_<=O(N~RP2#J0FJNq(vlD-3iE1s_QFk)o0C zutcE}?_nKawwTpW;YrsR?ERzFzBP;lHo5?OlY^AmPXDcE{QFP-Q#w|YlNNYRuu?Wv zK_Kkcb0VV)!;4)TlaZ$C6R_c#0Pes40%rp~pzfr>=VAl!v$E26f>HH}=~#PU-SR2- zz*&Xn`q*yO9L%fAv06Y7OAo(jLj(YX?v>AU0|CpAB%dFO6)@5rD_q|7sbd8Pw* zg97EotgKYNJ?*G9+m}ESytm!Gw{wI}#yy!?Q)>#hI(I>h{koXRRkegIQz zO8`?;a*_Spee<3iQTS?$x*Aj$Ap|v(1Gw&TU@rxw$NU_?|eX( zo1QYvGgmU+Typ!j2SW-RgQzOR2}NMqPoU!SJG=o6MsO4wCha#BhqTxT!eFakE87@- zgA!{GkN{{u1cQ(iA)Y5OOC8O>6;KTK0>O|a!JFtqfYe%P@>+kP5NC1kS3(NI`;8pw zI3Eco0XJqe=O^KRY`8yw^F$=r6+Z9OASW1p;y@s`8zu!p!b)L4!5i4Pq7Xle~NkTLfp#MO<%iJ zX!~LqB&{y^-k0bu-;P6o>%U|H&Povj$&E2bmznax*Xm#)fcu4_F zois@C`Bgr)klL0t0F>81Q($NCzy`0iD&m9a>T>pfd!qNAkO<6kq*;m;(dRxwkD{Jw zIPDN*mr8U1#qcK6EI@B$w)uvQ@W+6$4BT`V6g32oMFRZt#r>~;asy^jRH|)JArtg_ z{`tK`Q<1P@Y=EAK^X+%V7%<4i6*NAZ#T|Z!iqh*uo}`cdYD7+Zd3)JyP%tkB z|8|1#82uwB(%uO$CSt~2MepBFK3FSi=oC>GXuJWpT?b`H>SM}+sS;nbVtfmHp*tlU~<+<&hR+1|u%Mn{rRl)7r{?Nj)e=h!A=ov+MA#ql^ zm6AUQ`tRuwo@1pzb`^q$9rqGjAh*JXSFi0P!m*r@qQICn$mR|BTV(M%f5^`1>B zo?v-_B20`q5s)$4#y&$cRYK57G@nhy{9Df?Ew}^F3rz@skIM-V*`|ULf93~3t%hxj z>~{AM?T)PN?O$a85O)}IVl}-2)l%>r=$CNJAD5GT_u@VMdY7gc&|2#LxdIS$1kye1 zwN{fPZYjzygV#?{An1sd+meA_2!Adoc0>KhZ34-2trJ_Bkn=JvI{m;Sq z*KIK@whW{Z>|iBR0dVd<1dVjF*v*te>OSxic8>SnnTieHy!KM$bUzrdM(V zwddzSwMrQS`Z$GM#_Mf6K1%STwLX&Dx8ZbY3~23Ne5H(TUx4tg#_2fUAlu7uSLPp^ z$_*F1Z?jF^gx3G>fxzIPM|v$9-(98-i77MnzMfmR>^oA!JLgyC6g1bMIZ+U|y-Us# zm;`cyJJWA!J@=GNd>J$jIiML2-K}i^Ya9ZYKKT?UFm+AueDjc3-)a^=102W=0N!90 z8vrD57;GT}58V98bAYR>?{ju#834&|{$y#yKOVIP0jyoAsE)(GcER6vm)Lt$Z0D&} zx7JL8VGx!Rrp?$Fi`pLT<+`3P%3OHhvfqLmGZmV8bTI@5?^uF4BY6Au$4j83GTZ6{ zlk^+_JB))9xNW6@nE8H!4e_}#6xs;Cb(wmCI-3VFjxTg@Q?&rDg&csSSFB@`pE!ge z@WYr6bZncN&u7eHQ=w5%ERYFgI%v^V>^G%p90Jx1S5Sl~m{R`KzYh-(T`y#&TO!h@|X`j=Vdf1ht<>#AC!u zS^>WGG11?%=K>nM#sgB0G|q(>VN3S`@U8YIexH@UOa%u{gcOG@6O(`IeaQ+p>z@Hq z;3OK2@0@F(HKO*<;jTkd@qkTL$#bGRslc2}%x@FaEKMO$36>7x10~B``^%SVJ?Y{G z=u;|Nz&?me(C!^@FB^jntNX-Q8Wm6t!+Jlo8np-D$D&K>ZO(>rfKd-lPM|;3_@OuP zABRhH0feV=5`O&uc5nUbBa4noy;qz6B#=OMG{i3PDV8)!*Cf7NV`{Y~*iHQL@44}d zm(o%3-&i%*R8*S`raC~;RyzxN`>V!0m!Ify*F?_&<0Bnx!wx@ycTvVc!BboeQW3C4 zvB0)~G00Yheu1tTBp}-W(HP?z;u9`HGOFOd*&+l;Z#N5M8{Heu?k@rV9?$U#+@j?0ijQYQU7+K{$msWc`YA4gc02gle#qhvInf1 zAtQSggQ3AZQ!6T|;7Ewu!Rktr9Jg{Yaiw?a;|M`(VGgo&Cuvd#j_%>&THhO}N2%YA z0g8=LihGidC2}I|ae}M2^JY|}%k3vr-t`{OEPxgoB&F#M08p#Wqzza%P1u9u$vucS zynJ;5tj5!zRvZoXZtZ)vZywFZv5!R-(TF&Du%yX5g?<4(b>bkdc+Kb2oxV_HmS7(xzrFS7c+jy&c#rgg|B34QA`6SE1@OS z8W^rH={_dVXd^}v%1R1UZm&!%*q;OANvk}a-9k}52R*hk9?14S; zbRxR;H_*WoZsfdV(1`|a34;6M1xnViGQKr-B=`S&Ck3bz8Gl#v?EibPr4Tbn&J=0j z@m^wERC^T|N^qv)7*kWU~1r82~aRa#8>rO34@LJSwq{DP@%Ga5u5@i^*6yv|EJ?RcL74{w* zeNDz@+;P^gJki=p{(~o)MkukYqq^Z)m)1%`X9=mCRx#*}rC;VyI$QlNT{vIf`cdy6 z%WLxOcSPf(^taj1azx5gIn>%timl>0wW11m?sN4<;GYDeVa_fukr*_&v7@-QgM1Ndcz;FXd8c2 zNVhC_3E}$dfiaUb4UFe?KR`*tgU_rPRU6r`D~IStz6SHevFQG}HI!#Aq=CoRFU@1gyH|`v9rT6Wjtm!h3@XkFtqOWpXip zy-Q#MjwqoLqvL}&|M6yjK6I*52l5(us!118o-W}_-~#7BZX@(6s1-b6 z&kf75utBwDv;(i@5TPq*j`ht;x1eLe*JvO43RM0?sRt{*?|smWopJ8+>AEZ{rp$4n z$z35^*uSM-EX%6;Dfw}Z*nF5Kq33XGAr4K;`QF^Ldb#1k!Uob`o9)H3yFo_@)K;SZ z+Is)mg>PpOEr-)AEJw2(Ts^3xtbXd!`gnkwwB>8EV7Y+X*4wRp)YHu~LeSSAgcx+H z?-lc217Ft^P;PzEOn++fno*-jJ&z8#`2Zh|A8-wz6B+F#lpHonm+PN<8{ihLH0iLL zF3YUAt!|}e$A0`s7EHbHd~)~#{A4ZpKobP_rvX%>T$D@;pa>!<4vR7 zjd~`rNNb%(4TtAVdM#csPUDU{YK<=I%ZZG^f30_3*qtt~2vJV7zn`tYUhp#kf+C^Q zLR0P6M@b@x8BYy!rO>nArwkRGZxAMTc!7DeeS#23JT#EV?9d#JORtN~wxPIczl;x; zOJcDBbwnGV?}ynWR=uH}$>KkBq^E=+FA66T_G{RCGG>Wc{&W#s#Gi648n8A}abyil z2An{63SvL?z>Dq!(=(LPxcVVHqi!3B`K^U|)rk5#1*}FW|GEbZ5s=mli8I9i$HBOZ zL>P2*1Nrb46IJRsZgG$^ApPd-9fdt~7DPNmF| zK1z=87UT+1JhFJKx)abGUrWGfKzim_!poKP0huALqt0Q@e$hR84bcbri!9??v`CsL zr^S|8$Qxk;aGPtonaQLN7F&lw3XvVP{e}Lo??GV+UXh(T_wN7vJPrteR}ra_1rvn3 z`ewcnGAIf@@;=!}CE~Q4DbxpJU_RQ6f9(8-U&o>r1PhKN7xZ$TX@t9|U6#?lmgP#i zqYLg@HE@?{H+@cPl1pZ*CE?JI0nR3ibNV3Bh6PWZ3!j3t)CwL$W*13g4ESH$i*o^+ zM@VZp5x~I7>H3}3DQG1R0ng7;!XMM#I8Q*?XgO}k@bVnoC{bcp%&nqNuL15l1m4hI z(s%tP$@(!1qJKpl(_Eu#f%nZ(-`<|f`ar5?sqSUbj=|(;^`b`V6=;x2pn_k7v82@)D`M{wJqRtoppNDb*Y}T@y)#HoqQ@UtGp3dN1_ z(M*Bqp^Rta7%))nrqL;+^$2EY5hnL}GfFO0{xx+{+ePYzjv{O`~DeW zY|(Q{CK>Y|U_uV1&*vW>k2wOC10R;u*QVQmoIi?3{slv9-=g1%f|1wti=3-9Z1|gD zMuRS|ibljFR--mSo5k;eX1zX{MGW|rBav5sZoRj9h*)q}J0Wk7ef;;{RkjA-JXk8F zmJD2W*&rZ!1K60Q92!%{1u!Q|4?`2d4ft;!K2RbkfN7ehjxkTkIjbtrYgC@+oEiCS z(;Bs+;4`IwYW-^htKO6r!Cv@PD!+SC>0-5&5_OJH04`>B!dY69R$W`y zEL7VIm9DogfXLyju@{2jZ8a#M?>)P&^KvUEG{j-ekt#|6hxE_MqcB3Ih}zs8IGO*i zfCRn{1>#-$C|p?~#P_6Z9$j8VExZtU6&O&AYJY%~b?&=U(Wzx%;p;D;25TkeCVN>f z3wBq7OZxfFB=hRbS54=fkBQZ~hI<2K{u3(Fl5;Iz&U!YWEE~E!fHj%FJTTxGh9)9y z1>|logUDL7S{3AydhE`u?zKLUxaVH81Tte}2*vxh10?<2lf_z?vs@}&UZ3xF%{Kt+ z7kfiTY^-s~e|Q13wu2e2FH+KioAa#_tlGQ=P>t3Ye|vL@a4x<(Q?yl!oa)yBxvvAm z>5KF``u?p;x<>xLK=H$qcMZixN7tag?o*mzaG$DHj4}St18ay-Z8^+QZ8b{Q=k=4# zWFF)fmz&XTkVVIMj(BLpb$HzhFmBlMDiU#C7F7ek**g7d$2<5)CZ3K6dE#qYS0OWf zm7sGXHNWPGPn4W}3rICg_o%3McN_nVvo6tINzZOceF6qVRd_e~C*nFEgXNli#_+r5 zM_#-l2LJ}#<%I@auR)if-XX!R#qaW%a&Get2!bnS4V2|4g}=R4200BsX4eCa3rh)a z0NR2Y{$F{=TXnE6WqRc{|K~@)M&dKkzwAx4A{~5;P)Go$t!S*61$A_FAvoMa6{yrv zeS+GeZ}jout(2czV_6PX!DRVv2nk(W&C3KD*TpD8_AVdpSkh->c+8qCA1fz*f^b&j zKpt?hQqeeo4e!oP#1eM+#&rTBk5EiqHQ_ z7{{J3uf>Y+pcKSB&BD0aCgYs!Y7lHO^4;UU{sMF>>4mEKvO{;`SfiK|ypC3TORY*! zh4$zeP4pM5IJ~2lz&*XMITmy5=($qx5){V`Jh&2R{|J6>G@C(ruP~Uz`esp1Y6YN| z4&wdIPmh7YVW2lK=THd8p)L7R`egy<$D7%%VANqCS+(wVV@46gQU^tz{34rlZi!_SAJ-x{JfRo3R;M1^)>8{i`v^kP#M=ih*)Fgj7 z4&WBkK?Ze!f&UANsW0xB2;yo5Kl`8gA{UfyQQvT3`h&rdgzH2~8VqNE8$2sG<@4i3 zPMLU)Ox@GPT05<^F7MDZ@uq>n1V*!-r(X#a3EM%3R=!xX6i3K>;uj-VlUQECSVF8G z`DW!eh`9_Ui|N60%5THF8hDJLb_Gvz!}+grmD~`8>h}s%1GwbdBM|HMY$P*1n7MW zhYVqI7%Tg4aNqNwJjq5Q0V&BdFy$crE4RPcUzc(hSS!rP(DeVg-$jtYet!nXS0x+7 zM1X1!OnxwMBtftO7m<4goMDI0yV?&G>z)dGADfd@>8(tx(-wbOFjUKOn*}+t9Uu}3 z`tJYwm@%YC>HsJ#@*+ydbql~8u4O^zK+k(|AkuTX%s`5KKAgw6T{kL=JgRdYxBd;mDe)gq$9?&nI?|PwvktVJ8(v0Hi6k6)n__d5s zgvu4LQAD!kBYF8HI5s7g{)%3YLG(H?%k-B0U(pK-_wG8O)(iKbqm&8@cZ*~reav@E zCi(}{&|qBvxIE^x7{C(=NauB`6RX*040U5rfdRTso8Ju7%N)MHKdsUcEFtO7m{%RN z4XF zn)XHn*2nvlTKzx5-a8QM_I)2O=`l)lOO(ha3K5c#M3j|e-v}9HWxH)+|XJ`~BDRl-vEfUe|SA=Xo5*d7Lkb($CCkJb`+wmT8vN z)=JSP(|HL=cKE``HTANn{N279K4B|)TI@e;QayEr zAG&f{7j5kdMQ!U5uCjZnTv>C7qrg~_bXsT!S696|a?^LeRp!tuMZe3261CKC6oS3~ zR_DY*#^5(0yLs*=g9{3lm=Dd4Yx56I^F2IatFx?vE_29H$W~$UfVMf_`>GJLS9uHX zH=;Pa=j_Xe^^KTsg=W*@N>uWKk%oLtuPZ?inkhZLLio*}yOVb8!O`Dg*7pfqd1pF| z@%|Qdtzwbb*jE<) zd2foL#yaBpo^)-VSSu@L_p?QKZbZk6tccL-{1xxzvK_=wXs| z>omJ6*`=7_BYwO7j@d5Tc1f-0Lu41eJ83P2ODu~med94`inLqkkAlqhB@k*&c0Sy+ ze(b+P7To}p=0*el7j^!25`r1J*e?y#9VYi^ccwE~KxCf~7itFP_ zExJzv-Lpz_xD@vv4L6!(K5g7jbu~}d|-SH~Ladmchz%qVLJyjvze1MWa z-3}D9{{SV%+6p^Vzd>cg0UO(+$a3vYaiS{V30cg~k-3mJDIP6|o%&%0!Ow7Uu-MK! zq&lRu;Wpg9l51&yYUK8EtAvW#tQS=q)>|g-MNIE= z%Zod+3hJ8&+sUnmiJRRZibR9)LcK+96%_OHD^$JSc#>D7Jp-u)+S0Yl`|TvzRwc-i zNq;@KuMZpm;cnwYe>(s;cjN%1$$w~h($Ll{WiuMBL~%na7(v5VK#iq7TqXXp+1h2e z472tV&`MLd?hV_IYy(tfQsW~o)nJlCJbt=ijws8y4P}CT!(lNk7tP=I=A#e@S+WEG zVRR@{YTmMgjzgbTf(o+%eri#z$|q|hZo9tiSduC?sG6u;1Xs-KgQwq-Q1-hA8^0j? z39R!*Nrq}x+^X|B1%AxyTU3-vl1#TN)^ONnf|fD2h~X0i*EpCG$aIAdlFi`#%Kyd~ z+_`Bf`A`2ft@uGFc6oJB$7t$8Caat>m2Du_N@@e&d$uM^1>O`_G05hY*I8^%`U*Q@!mI}qc z2rd2K)GCPt<0U@Rk(|Nqk_xyy3K|bnqVGXp4|!6@ENYs7RU(NK1OH|2H7Y01=1vF@wur>c#^eXIQ?L)dRF@_T3A6%)#B3@bd=YGhO6`5gRa5WzKeU@I`o9 zVnmUHeM2xaOcg!$CKt+&E^ih4SKZ3m1*YmyVG(q_zDb@7`q|>Q7|XlUmRPM_$b#lq z{FO5_@~cHlg_jUJB26jrLg5w;<+mpa0*9}b`?S3jurL={JH$v?v>g(JQ$upCKv$in zva3o^er2}OXIWu_fEKE|F)nzW%AV=+UjF!81~Tzt=NX#+joTh1oWMUg#V0Sl8lxt^ zO*Vr&Ig)P@(OOt$(0o$p8KNkF+NbQm7gNf5tVnwHFmciaQVdb*`+Kwc3LoH*>6tCNxXEg6xoxOYHyZfPI+{EwBv~cv#DQ9NS zp~%Q}`^mUnwrmE%80apUe&Jp;XSU-wS}3dgo~w8Ql?!Qn?!(XQxd3C~?VRLLY4M&9 z7qCodRMN0^0;Dsb*9pDKu9|5&rJkiN!k8nhx&WvgAEdV{ehs(}nHu>II~pjs%;JLS z7Gy^|xJsrO>`#5Zcv~%^u%hQ;cq?K51|64e>&+fOLb?FC#2e32&#eb7RFCOU$!B|o z=)e<-Vg}Ic5ut!ySC(FGRJgixA93dqVt>`GbToeS*K^a&z$&~5iahw&RWK)$F6b>< zxyKSwd=UazF~!X~hEuQRXiO}MrtX#{Hx)X=SdnedDo9PZ?+-g-4pu^gnwQX+6jq^GF;$WDYl1=8I-8nzt_yRf&H(>egKM8+`_^+3*C;D%DrLPt-SY z*jCF18l&0XEDMo^CuZz~J)B+5Ozbj*y`@~_TtqEZrVIV~{5B;$AJn7y&19jBdSd?m zk*zolwpHZ8C#IyB@wT8VvusK0O3|q5KEQuWMXj-95f8K`Y-yWLoErtRb)Kh`T>SoV zU->eU`LBK)|MB4vXn_AC$=U@#96>pcCuA7c&Z3%$pGve@&H-9slMS$a=lZj<)5PI#2y0 z7o*uuqMqT+K%gg`)Tgb9o)HgRkjdv>Y@It#YC?3ssrXFGgfiz6?tVX*?dmg?`0!%9 zWMm`m?I5)@)XLS;kzr(~nkH53rTA#Kde}!p^IILc=CV zfjl&m&E#4Cy>D>Y4s6OC0B}98ljT6x&AZ`JJ21NY>?%UsJE-GG2j`ZlD;;yu`Yq>V4f_UK7h(a%%zm_j5|NPJ)8+Qx74<4B^1oM zBguFqNo<5+adiGElL&bz;`rS+<>8<$+=oU@q36i$olft?mN90yjkyH-|9Tq>GktB{ zeaGGHw`O>Z<>*w2*kV~tY-+kThoxM2VbOql@Iys(`{zOno%r4~9LF3-s9c<)G4fPXh)k&yQGVuaAa)%;#<-hl$M6%(#!!-`2a z)GhQXsnzZ1xs0%V;p_S72F>AV9HbJotvR< zK<>(%02ez^-H+)-}>>={uO<*!fQPChEo{zv0N%v zhHZ^@LGq-VOgN1jh~ zT`<|GE#|?tvgku>a?pK`;WpLhIvG(+A4G2Kb64V%@} zD{T{>IkPaBK90c>{v)-~v|=u^M%FOwv|t3%R2nvPpI_f4zp9+zZ@$& zfVrv9`St(0mCn!y6I-Iw9urNl+Yfj9p=3TAvCAgrtv3fo$&y+Mc=uB42&Q)#;C^bs z4J)zSR<8eYs^islv*8Je7WFeJkja-mgi4L1hUU!(a43Cc9WdG~pfkern?rSy)M?iK zZB*k`$b?GO#q^9bBda6lrjh_KJWPADJ-zh|%D>cR29+o8al?zPgXNf+?``dkN26Goz$8v5??_A?8`;#W$u`-n@= zuv234c8VQgMo{i*?dSZm=UCmR1_TGOI8Mbxi5{Pz_WS+)MPuS?CS8(%DWZ6^FqO?K zS}A<8-R;)mEK;n$K@0dYg^?zaK0tJLhWj;@8lgAc&c`<0%4wV2-pF-tb*VO)0l)57FK?yWJ+@7|Qq`nYxk!~B)YM%#PS$?;)mC8gAcuc% znqtkQQBbmo?fxquSO!+e`T-y2Qal^1nUjBxz~oFXa_*Yv1Bw#9{FiPQGl| z;|u;=yf+N6cvxi@cuC0*r^{#w6os=Q;(dJnyU@O3@bh?d=KH?SzK^Jt|AlcQtYDVz zTu(+|MRqOuZ8itLF-|7oxG_H?*=PH{OP>OK)^=|&>z_#LUQ%=F<^fCL&E~OHRIf1v zMt%s8(my{0{1;G16d1_4GB{Fivu~mQlM{&*9RKF6(mS|J%k_i!A4fl#qY-RDe+HQ< z2t5Q-;(sMe+{N&S=z>^}v1pI^>EBe?_q{i-!}oUUdC9uRVeeZ2_~QdscQM*s6uzV1 z3mIY8@VtEs{qZU=7@LKY!WaK`Or$vuVre79GLv|#-wB}(Kl6B8RGnf!-Qj^AJFKX< zAKmf@hOK!$arB?ReT=&p4-vlOGn4c9xLsCSHs85p+GD%zKD_&PaV@e7PHJ@j^#RDF zFCWCWa(n#>e;LyE(_EHrchUQojqV{lg(4K?QJkRB7BJSpzreRj1bS5@^9otvs@gEoqKs^EYbas?~ns4K;Haf z_$A%<6Mx;Ec;*fCUWu@;9Xz+3cz=&OfbQAz+^T-A|=?tMS^J`PT14;MY@ z{;l<&qh%E@#{YDJ)2K+Lk!ak!E`}=8BvyalW&n|p6;c!XaFp+*M*BV*`6H8`*yRxP zbw`oL@~N9IgR(SP9p|P+)|EHbYyCzEM?LNr?T=$(IOM~gT@d;E0b`1CCvUv^b3;EV z>-I@mI@PFNysRM+R;yAI8ZGs&oth1?LI=x$Z*=eyV*AaN?(w_9dhpWD{nPg7kFWlp zbKS^DXX(5;``ON2S`WixI7(6Vxw2HgUhO;4e-;9H7766UI;wQ<+td5b?#DZLZMod7theYbc|Q(bq9<=0El= z68hyIUHYq7=Z{~2JekKl9fSv(x!Uu83lIN!_W%4Gojk0O<>RDNf8E&s>)+oefUP{Q z#%lQI8vPj!{`27n@GJpict(Dv^?&S-|Ks1&3Bd{(HC(wUvws2pkADm=+4lwP;+U_- z`?*ICS!P6?HSi__Aj2YS`<8A&UM}S0qQnva{IWZ}_yt&B*~pXD``+TOKYHMk0Z(^8 zqGbPHh_R3bZ-_vVA5RrWWUY4$dA9elAAsOBJ9{uhctG_zM8^GC!=^mEu91-gacBSg zf9d9k@QKHeBfb=+0Z>tUxj{vA%&+HiKkETt=iqd6A9RQ>$uB4}2;vo=MRER*1-nlI z>z=O8&O*F@Z@S?@yj;9RXs=h~W|sNuN9btrPz~jHf@2QCCm#F{7>;fS0!UZoKP`WJ z;fv(KY_8DIywOkZyM6l+5_9R!;g{hRTLr`9v&-kkJO0;I!GwUXRz;sU_HUZ!H$HIq zb4Y9fX&aH3GfnmD@qfl27~9y*{d)Aji-G)dxTeIY+6yT3EB5Ubj2wKxICETY79J@~ zJboSW0p?8VTZfDb#??#SGyWf2;v%xMj#GW!zs-Z?|4q919sEHgG7$H)_eQD9+_{v zJ9*vb8elWVmwdy2{SC-QhO=jz1UL^KKB6GTP$b$+R#Rg=#)(fCd+^biIgNE(vc(f$ltv7 zc29gfy)INapi~pBxc8B7kdM68AMnRVUM9M%h;Cgz`HWnT_~j0ec_7KnylB#so|7aO z$z261I}v)uEUnU>P$;QN(h$tNHo0#Ag%!LgSb^DMd#6KFGFa&TMesox>M=ug4ot>yj+4l znTnPBG13$3FRcay%=)`EYX$M?zL6fpo{sQ+?0)B)?Kl51XIF}e>qM~J2%y1htrbb} zdrQ(CNAAjNA^%c?zrI=UeUR2QXbLwb9O*0bgrjH123wqes^P>wCjyhs;9#y z0r9w3O?!q|%5W0{>95(Ek0(^wJ$)mFQ?w6}#oZW??*p9lW4faOs_D7Ju@sFdmQv zdq)Xa#GT^4=N>x`P`%0Eq_=}nCD4k1SSTtbN)Rc%mOh>f%>WXgKLf?~3wxU5)X4jI z24t&>`P(2=YJoUn3TiRd6%c-@S*VFDVHo=0^ri z-WY8?3lhIB;6jD^pn0MnX&B;X-2i26Ko9q4V8Z!9@1`s?54dLH$$BM`c8P#gTea+a z*J?BK}tTfv!Ul8Do3kAn$zw0VuhvX>bX>@~XEfO!i@?-3zt?v(xhSO{OR@06s=ObitRU-uTedVd+%u>X>=K$GMjFwitGpu-IDfrNwz$kmxYsc+NHG`*LZ8 z%fSMuSmgxzYKMbNCw|C?Ed^AN)dzB!;m520aDa{1hb)1nY7k~GhB1&sd~ESOy+49M zw#^#wB9$+r`K!PNGHd{uNU(yyY&h^Qs~yBl#j0$qz1vvws-1ypPrYmkMe~r<3NT6q zT>|;dNF^V!{p}4yuYYPdQ@2whBU^VGtcKPJG8MWc`>yCIg(hVw0v`XdaujNbhq-?<6PMxGDU?97h*X zbloWgtR*QEFcXFeENXN$#{6Hc6j^&Qkui2LXFjq(*Rxy9rvhzxt@5AJ84VAvgo z7yN4%5D#KgKy&3~_0p@^oa(0U@glw2X0&sXPfzv@0ByvNC?MWIgG~19;U=a>>(iYz z;Q}T-Er=Mi;!0CUInc)=pot{jT=ZN90K9DnEyFe0 zb(D(xgZ(z>Jqj1jI!@DT7C@|sMC6O#L0a9js(jQ62Y(s;g4MFFSP6lE) z=>0H))e-cl&e$s<38LWaq?wX~CsI#=8uoJUJ^PsS^49~Js@Ap)n6C~6;{UilRi)}p z`e>pZeWE8z$0A-9Q;)E!m8lX`>orwgkQZ$1-a`U?+&2ssBX}8#t@lCjHhM0cBHv5- zCFEeELQBFQC&Up+jeSb(@A?g*d=O4pGo5T2G%-BD5#dx;Vv$&F2qHs7VzM?}y1dj_ zhFM8ZsIZ+=(Y%u?Ph;IcV;_llX=T41$(OM3vOEjYB1JVDqt<8v0Yni-LPL8wRa&s# ze*TN@i7V(exMLzw%(sfnGq^cD&`VzdU!CJebr(8a%UsGpopx$RcaWNh zPFoj!v`)q3RUlFSqucNAH;U{3fEx_BV`u%hs#)ft)HE_@;RWvI*jE>A3*H*>=jMSO z>9GOty`eqmcd~H6LlzNR&2ZHI*tc16NF}zVeGsFh5XDpHh~~&EN(Zt2Brt8cdiT?! zK!J&w1eL}`RGIBjL!_|^kzBNbM0l!nC{gmroGxOAz1394%4gDZiCVxskDvAyGU$Y1 z1;05zx3#Z&e3*Z}Sis)C)NY{#+I%TG2UPW@er&GDfudyoV)q&5GO)Ugy^)w&d)Fv6 z-nE1zjFW!Q1l0obA~|>;cC&H3Ep=){)sqU%b2Dby5!FM?epF*HpOal()T@skd#@&A zV|OyJVFM&y7886(Xe%+)eFj1Ue&SA@Oms2cDhMMC5J0%u2)YcwTuq>K5hq4!;3&nS z5N8@%Ln}jryl%?+RcqAwI*D18Cn3l?J%Q}?(Tz?x;K(TsZbYsijBOk&p+NLz#KV!Nq2_9OWZX!N_-v?Bu0H|T;zylQCqO(R1#-oRG} z)8h{ay|Fgv(tKFg8MG{h5LItbADivTFtJYOxa7i+o?X2Gv$u7@6wXYD!t9mTr|#D6ZY4F~aC z44c-Z35{wE&uCElO=-glWR^)iqvaoQ$d3Tce2pM zpVo9Bzq1D2^LeOvZydfDB_DNOe$8(vI#pEx(dp$L9?Kn@HOGVCR76!;lWNI z4@Ph5{qKWC!h`vH@SgeO!4P(gBWI$=e#|)bifs!}FesbsYU1&0LOZG4&$*$Z*p7xV z@y%Jq;<*-m@9V-F$&t1iQq0x9>LT&9XCOtkaMqHAcBnkFfdVm1`eBH=v;!c$A?dHn z)G7_Aj+2Q|p>o1HuJ?mzb8<>#aj`hRH@|w=X;?)9`%WL$fxa0b z(p3TA1+78wJ=bjnpEmba?v#gKc^2*}>teZ5A5z6zM>s86#|gu2OgP@?R62bMQg}W% z+jq&0gny^-VzbEQ6vW5)2N=f*KVhjWqrvE?uHJw`0@3sSc-gp(7W`xYf8-&cu?Zg8fx{Mg{g_~FII|{I zM79%jAM_j9zX*=3w3+#Yr&~L;qZR}$2;nfsxEF052)#TG9whj0;Z3iv9bYK6>VU+# zUj-zZrLB^bS`)q9AY~${I~Rl4m^fCx3o84J%@0cUK2UubcI5D-8&I0vxd!(zMd+zR zd$EcZ9%yE?Ep1=^LFS8ad);Yw?kHBTAWbRNUir{nkVpRf>lTPn6tC${uUtvtA( zgmH8?dEz+_pLYq&+TV!SkCasxm33j0Y1=|a(AsnFA=mn+Rq1S|$od%EpU`))J8&HU zA{gueU{Sw6_u0MIGzS088pJH}$7?zV5%|SpzD4!^P5_$Dk0_$bRT*P)rvv=W(J5iLH}gpO6*|<6KGAeUD^ub1otSKRbp` z$X9?|eN9Gi;+^ullNaZUulTD_MSR%-)>U(P8+;=9KuMmgUg=uC35olYHYu+VPfL*j zm?$J(VDEwqzbZIZ?Vxs-sL~HPWZxqEkHI0!L+(gw$A9+jNG9Zt{B)f64-Af2>VR(9 zqaUcD66ji2`F51`?iF41tM^kaQ7^L3P55)ianl{7!9W{PnHwlK@E)F6Mv^S}iJ|#b05V)VZJ9zsn;rJ*a^AatxNpQoQj_^h9 zAj#V2+Eb)^o8$^?k~jLT(tm7{r|?D5U!M06>Iy$FJ~Cuk;IX;)yb%x98mr)^L+2VOfgkcld z04*)e33ZTXv?4tNOY{K*lA(NF$oW@adC#K=JBtC%zproF-lg?X10Gtv)JFEqe{*v> z9c1(M+%ih!&deS~Y8gQ=ERY3R$c{VG$cCsQ3(}$M24*y^Ethi9_j;Y#h3Zju=2NoE z`tf=fw)vYyw`TzX;eoWgGD8(4Xwg0uci-IkN#l@NyVG%3UgCDFWqEfvt zmOHNUAktL>&pYeaUszHi-}uz}9iCU|tQ{b&**;qLlu`hZ(e&v*6B%<&0ae&bq++p| z>uK#yQ)GPW3R9XTlcd=o--%cJ{sIcip{&@SE}(on)|IV$eP9VW;z-h94P(0^86^F` z2yXKcS}!Ao1C+*5pl=*PT=bASS@$99?n&4tr+D#xUjlSmaMHRY<1F{r;AG6Ol5E$K z(==F!$6+=2V7$EB5xIM?PAQOFSGbb>S_!DECtfJH%-+6TZ`(b2@-l$BF<>Vl8Nb+ZzJ@{R44SE4z!i6HB7r|@Pb_v=8 zo~bRti4;I=B1lEP2ha3o>C|q8up@pc1zFOo&oO6pg`;d{_DZf`q_c4b+djQ-o00h< zjU5b$p(-CGbe((B)z_X4;yRwIs-9`mxYN%*fA13o!O#lmWcqBorPwQs3I)UJW8?Y2U$ZU^YS^JbM^Q&S>O7+}6O45J1 z3N}5_Kez0EKd{G9$jsudJ*~RCFI%G{3xLDT%|64?ETJo`ehHSp(VM(Jt7wcE7WvG8 znA?UPG2>Kq0QIEH8=AK&84sD%^s0#1Vv1^wcFcPf@$zc* zTxOghQw5SgMefFoEQq#GmL)NTvZojGqcfnHiLK7(lglOORw81QTm)OYke+u4FN8=d zuTdAp4}dti3YkQ5ZSM73P}wTKK1Hw>)?mc!_#2}(-#=cxA3V8i(R1xny23NQf<47q;k{F)_rO(5p{z0_wL)uRwcqZo|f3$o=HN#Fa8ts$DIKF zG6c2H8d|)tZ78DF;`6dLM}u9S-Ab!KG{~VOG({F29W#-ZW+HMHDvT}1=@!`eMk2-I ziJDvg{pT zJ~+TiHBtYf%fHrwOaKmWQD@!IZMUPURKo!AREnK#JXw!*Nx9l_*5Rwi;d)UJl(#~U zn*k@7!EXC3;!&W`9nj4*x6HD{iNP3@Br8!-M#D>1e^w?PGZA|QTE?k=YU_E(ikDcG zIn@j>1V}MN2|`e`mZ9p6PCnD3(F>A7gSMyPiBS_zxwVsTQOwQ65~f3RDs(Yoit%|L zC*t%HNF48y*kIh|%9Q4^`m5$ui%4i8IW2i<*|k7|w*wMH!>%U~aYgw9oYMGj)!_gP z=?~O}%rbxX#)D6<{S;pxG&?yrSe#4I2FAe4jagCp|UjswU`;yHNe>Z1oq51DdCtWBlef)VH&t;@Y0QumR=})t~ zI`Jb&KLqr~hmI&Jirq~a8Q=P3mnt_&w^vaqWt+>*b*(kHJgHjU;tl>e<2NpB~~w*^QvBhG-)kY zaSG|F-*qMK$suotdsLCyPE;-SZW#T33yM1k1-sgE>iB;z-~)KSyM0u}*@bk4>0|3U z{eHSv06K(sVU=JFW`0!NeS5bNLB|g-vXG}9N%vza-mU*CVe?b9P5Dy5*X{}X zjcz4bzQtM0KI_K0z96t!UmQBp;)6#h_SFsf=<8Iy4{uGs)2XcBntg%`0H%H%v-)-l zPHv>6azD9QV(>Q(=sO)ZmA8;QNMwle2d-x*xKkBr;7)SJZV5;wkYxyu602s)SwqV( zS4X+TQnB^aOGuqZyy@3}I$;sm9d>ES%s^ol+~V;%nv%DSd(xu%y5r0p=Lsm5Wi1QlYUs9GVv`<)KE4;ectb)0p(nAkph^HZLiw@YWC zw}IAXLl~J-K)Ooax=~fH7FVE>c^zJ>>l@2}UDaiLpYd-Sh$#;Yo z23cJfQixQGuUSnht3{pR{oewPL3zVCJ~ z1h{UTuAK*BZk)1`>k4lIId{Y~YH-CyG3i26ud>FzB-Qf7;1Odf$o%8O_ zdch9VWJa}|YH6m*w=ac*?Nqb##;A|zGv_c4(gK{!J1*AHw}U1K2CwiXERFqI@7$?{ zj5!h2?_rQ$^(DeVj)EqLb|;}pYp=r***kzN^vRKemNrju11Hv%JL_`W*tQRB2hDs} zAPv(bUHo9fwk0qO0OZ+jedNgTBaN~<=XELuQVoH zc{>+uuDX7ek3P2*brF}&X7o}#|6TlwN`ITAcn`!hGS8%Uais6Z?lpZA5$pxdXEv5y zrEmBY3D*xFIZ0LC^$R~llAsi5FuYNz&}9ZmulB+EJ;;s;f$VT!KJo6q-_j$3YVnLv zw0aaYWc4&6zZ%haUWoA@8E0V6vh*8o8|&)`llcX$Vv?{`r>9BIAJ4U(YC~=`+b`9$ z07{!OEqddEDn`Aj(?8M{yl^vTpIY&}QX?kuuNMFjxij@Cyg8E#Ss?sRIzba6J62TN zDOSY`ZJ63!sOv+OmJ{?@gY#9@mNH^AyoLd%gzVB+PaYHC!fYdTo%uiCdS2Y_gEB{_ z6X{$Fy($`WPPh=?K9K9U)??>vl4GM=gk@90r4&SBS9$YIdXJ^+sbr!bXyh5|)=j{{ zu9_THIdK4E#-&~Mg}64yb4pdquMw`O{4-d-%+`ar%~k!4T3;K$*E_PilR`FcUK3C#{7pELuF`zy3dcv26^Vqx zl1Y|h0BNn-GF#a0(0(qRo183-@+S9Oz9eQOy@zD@BY+d(rJ8-{_ypHMR#PXUqN|r~ zFg`C`a|m!EvO;V*=&T9vmvVDH_ZTZ`nov*AG8TPj1zpw=@2c-NGo|06`~DJN6-ytn zo-I3^halw{97{%CToK%C9_kOcW6l-67fw0U>Q!ooy`@jjh4!093Dl{~jhB67{v_k9 z>}#7<4t+P^&DxejU#iS$VJq^K{0Sc`=A;m*#pkF?51yMPSsR7?CdM4an_p znH0R>p}jkafdT-%Zl{e5_Fa9fdh8*Fhohl@SF$05vI1x3v;aPqyhu;5B&wq!kb0_I z>nnQnTYlp;JAlD8M=QjVsfZ_9-5}*1I0*w>JSi%#^C4Y83mVO(I!g-B-H*7i>z9AW z8Y~E>UC&<+pBr&&GH``{u~S&?v%vDM+kIJq?l8^vdC1f?xRznr)!S|Po~IU1o@xrE z)EcW4u0JH;ofcT@D)N+{z&DGxJQ_6~cI<1Ue$d7KGuhB+R5HMSwxqh6BcP(lID?Ne z%cwZZ>LnDRUHEajdxh>fL~w=o@#r5KS5|WZ#^X1c?9ITMq%#Rozld!SO+4o2^slP5 zloI%4q?}1Oj&ls}eVdD9NseDiOlX#h#*Z;pDXM^|o4Q9xZQ~K9xrt+dXbvZ;O8CHU zs*Q>B7U6J-?Yq@MaA)w5gZf~|Y(z1!z*Cp?A;)}PSxfn3nYr@GrWHGIG2)LY61FqI z^{?JIa$6m`=2t=qvdgjz98Y4-n;g2v9eq*Xn`AfBsb8!EN;M~%$T?>~EK(r9sc8KN zF+@bVd**Opv%v=-N%@5rJ|)A&V#|XAVzgLd0?rqO6;3|owuvIWh6nu0##r0>Tgcj& zaO|GN3`Y<@$)0ANRqU%Q?nzWp{wcB11;!}xVVT!GD<-*~{ASW>;SEJ)JFBMbT~5~E z1>I+S5JwiF>IQV5sj+K0*TW z7Cf`(ge=trJ#uS&)ei58x~}dOF)nbucQwR?>_Z`N0q*2QH6jH+jj1D_4d!2`B9#hq zLaLijQgo`GmdB5>1_@Qm-}~9c8$&r6AY&{M4>UpO%hpn=Oe!0~sxPT| z9T~{*)`K1ylK~(6B}h|yEwpD9^ov)K`ku?DaOA@-TDmA=s$7;~3vxxhyo>bO)}sxd zeT1=C=Ch4VI7k*g`S%jLX#+hQ=z?O9l8PT4WT_mU zwuoz#k&cKcvR{$%I5y7KAw-{}CD>u$@9+)mG}YHiRLm_Uxr5J!3wwsAD)rm4?Dv>6bO-H%n zphJfx{9fRwA_xl0d?*-%pBKHc7a#u^dKOJv+jipTAjVh5H^P06L}+1lhK*iP_YE`c ztW5i)?Bnt#bkQo5kK5P@yVXHO6Exz?RBUCCRMs_YM930gV!Bf*QJijo0Q9TpNhi-O z)l&&tz2-74oMg$Gl&1YOoL>r5tjmH{ysDOM*ihLk6HJGUGl?Oh+y-JJzMP_E?y6e! zZ39Oxroo3Kbz-#roiF3AZFT_IVFXxQ9p2_3)PidprJbT8@p$!&umhSP;Jz z(AUd^UoX-UTzZLIKGFw4Fp_#NEr3RREW|TUmb`xaFv~&9jc=np(R?5$5@NkIt3h8x z;Xlv^!m+?w1FwqkbLc{GGa2c?&!IZ#&6ftmmYm1$49|zu8V`I}xp13m7ly;=uLL(A z(ntyJML99Q^~r@F)x4-?3k2Sj|9#wPJNoWl1uV4hRI(7uEHRv%F8(WO4|l(TXN_}aYsmV zD!BMH;_|{9O>}4n`VV}9TU;}R5D)d8;#vaq?($b|fg_r!w!K+>@RS47%KKxgyF}wG-8Y`d^0NjQ;m+i5GAc=K%TCr0?tx{5<7J2bMUPIxO3wn=aImry&u zGriJ;;WSKaa5ygGvUNR&C-)uU>4{c5$Xwd;m? zF!#ZvsS$x9`I(A(n|n0doj9u$8IpUu<*Uo^yPy^NGuNf!!npN8;Du;$Z0p`;&w37N z#?|7oBW6apQ5eQ3t85`%G~T1HrEFEI^op$Krq@Q2)ECT)T z9TPy{Khy7?kVd3I+R7W#IPmj*GiR>ip%W}RquuS7#{(Y8eR6E)2uNMAcjP8q+(m(f z-t_G~VXv<&)c-t;5BKsRToBUUFLhwurwt~r9l8z*dbITSM_NK2Ri)?Z{s{13Ww>IhfijmNrdM_2+lj0$Qu#FmVEeQ+`ys)c2hSPIS%-q0b?O4;o&(Gl=s zr^CfET%oZu?Vhr!uZ>^iD_OiZ!u8RY9-!X(8zhurJw|7)^AlQLr|l)axWtE104uTn zlYUQ+L@&*vVIoD(Q;l9+_TuMv5v3Hpip5jFWIP<06(Mc7nt4$Ck`*;ep89pXe2Im| z7p&3H;MvD^Kt3%F(lB+f6=~gdMK06fyq}JwZX2Tnnwi;~oJY%XfgDV3Z{^+`F)teZ z2XMEmPL8S+%5>zdMB`B#LPHm?Q?=I$`203565~fSfZob_zr7}a_eBW(i;ujUkKoA< z9$U-aN{UuR6Q+;%L(~6rM8@PUW=QstLU+(_;8mLUcA1qKuN>9YrmtvF#bVRo1#jpnf zVh45fip5)nmUlrznY;P<^D?4|Wcq26>#>p--s_~>g56X(iwvzo>n`fk=m;(WoNU6x zf;gh+mcL7CyqLKhrjPDCbbl+B`Pom20qCDkf0VU;x03vlK$NS>i8gH$7E5R7g6lb? zZNl2AJ;&VEpEt@sz~pG2^Brp9BNt}(LhO5l6tl~q%-ySrUwguT-{R(#rak_sx?nw| z#_!0m;}!dbShl`#IVu_uu+Qn;|bO8!Lg@0ch8Xygmc;we`%i~V2 zp&Z9#6K^3%15&_1Y7&Ml=B!>P8qee<@&WV5i^K$(*+We<3;6d`r5d0L>S8-vSUYl? z#Zo~$)5;TZFrEZ1hwHX-V(!lcF0T7VVAJVoi1FnxDy%LQ;`#=*32Iec`75-{x0{cQ zM2VMiFgd076qso$f#eCV_4^ORSoOlvNM&U)SSl=R0?#x#aH#{Dj#r@CrZlED@!&tr z=3Hh9KwHI%+O}VEMXf&3n7+G~WjquYc;@I`y%@xA!04#cVOTzCMH5%)pXhbI0g%J0cn zU(Qiw6pND8Co$g;LE`Zn=3pSS$@6LQjq4t%>PYoUWgZzvWrR_yCnm^_E%_d2lm(dX zx<3X*A4}=Lq&sLgyP0zP3#wo>=-iKd@?>R6-9fDKnZR?Dd7k(4LyU_7KGWg#B3gG$ zfR5}#$1Z;$UcJ)vJstNGgcgNcpK=L!iDpq<2E+$BNmnKMKt-sV2^{o5EQp1(c#?o-xq=r}d;3u&y*D?lLlYl5wuDDe!dsP44A{IJx5#$n-L>2r%qQk|MQ+s*K=GSP6sYa(9j) z(_Y#77Kqx^mzT%)2>AEzu;ovlM=7-s0~Qn{b?=*K!W@C_pp2I_@&i%V>7uyK$`Pzg%YZMk)y%}VGZcS zvLnsI&`#ZzrE|41hdJe8`iF1R!?zH~mLiy0yD5|dtyjdG#jOqEs$83yJNC_vgw5pJ zKnUa-IP!Z5k+vMljDGn}__G0OSS!w4lWZ)SO4`P5Gxz%4+;+B6t#$?{$l>Jr-Wz22 z6n9o`0+Z8pUh#0Yhz*JoB$cJAC{sdwlA1`( zb&-Fn9oTq65h3u$qj-Jn0Wz1nrB$QL!l?#`Q!~Xp^K_$AZ`eTewF+QM1_Vg` z8k!y~oCo92E2t(&q!w0QBA)w!!lQ@eXd9cDFTD7`sWA7bx^ni-Sd}631EQh*z?1`)V~F zD%K(61i8b|6rWwrYVpu3l(JHcmbi;cQ3EqVQT4$Dl~1vVHe-6+e1bu1=_8<|CIV*D zJ3=s#qrBC5Nz54RAa;a2q$o0+Xj_DMsHp-SEl2ZtUdh)+Y7G-S6?|dqfQ<2Quu7ma#2Mv%K)cW z0VKnGv4jzJDEy{yn2$MBfAhB47R0=wU{>iQGn&QxRS0Zt-^Dc(E%ZwplOBEZ6N+|q z4<+rd?_r#?nuS3x%eS;|i#TCB+T~aH_Pz4jV+amZ9!kXls6g<|NZZW}vuk)2=kB-* zeBXc}9tNjweOK_D87cxXk(sIoHCy%SS(zZq-e(f_0*cF>18?4Dzo&eY^qBaD#C=e$lqzPM>o=4MPh_VkC2#rp8}Z0 zbPZ0HXab1TEB8WPZ1^@Qzm0j<7P_P)Xmz}SCgh`(m%lCM4r6c14N(xFwa1?s$4SRQ zrR>s5VW^>7YkTw()<#9%Y)Wf!QRX({@-vhiVmw@AsXt;197V>ub@oUnh3mm@r7lcgUA#jZ;=QBw@ZS>Pe>Lh>Y#)(v3}|^KnDN`tuA^Y z|BX0afoyTts+-uJPEU~Ls#YPqnQ#{sjh-qVjzDAl7FW_$NnT((7(6t zym6$kv#OO<8OXo8A%tS!D_lX(E=KBv(rz4~}sXrDd~3UW^o#>Y~11S6isQrno)m`b^X2elgr=`VYG> zqoMyHZV-I5azzjw5eda&|J;{SdkbFhq0tG!H}?t+XSE0Qq-o>|D5vWDJ=?Z5vDd4*UZ&7F#d5-6 z7X&MtO`wu`>>8Hwf>Nx`5k($*;3Rkh!v0>)_Xku%qh5R>?y}uP~Q$28B}Z#xMq?KIYNit4ls1J<=kB zr~dVB?S%E?b;LxXX_4JqBdO5AC==Xqc52mU3eiD=6Z6@EDaei0b(yZ!OxzdPN-8Q_ zn{YWd`jMJgko9b&5Bmu?BR`JUuO_m^6bSn;s)OBA#$|Q|L!vPrqM7Chu66P}unsY( zvm?svR0Bm*MsG>A0zp6U46TUK&eJE_5u956lPs!k+D}!eRH<2;O4hdABvvL{hmu8_ zc(pb^FfU5+5bYpn-^yFk-Wx7wVY<91sd;`x#82qSKxL}GT0)x0_$dn9L6^SrtDsvhIf zE`cO9)4}Z1x0n29(=`j*%HWn*6A7NGuzGFM<$nG&R1jaAE^=NQiV}6hUPL^Tk%lML znD-!2Xu8cywwKglVMUdKVh--1dr=54ywdA?YLXIJD2*iv(S?b|7l@6SSwzzVj%UJt zPj@Ofx#GYoZkT7_T62{jdfYP)ao>uqdiM~ zNLK3g6bS^TB;{PV#I=`;Z`whVbQ)_yddY7N$E2!lg7KJJcVN>jv3Wx=@r0-oH=*o+ z1G=%#d4w5K@eVnNkK*?@OiPc9a$a);Z`%}53?AN6p0>w0xNTx1L{DZu$6o+T$(pvC zaT7U_!W-CfP8r(`Gopzt;jqi+vmOwYH-#Y%H@vPtHqy?HBTmd=yUUkIDg3pZKifmw zm?Deuz0t>C6rJ@K+;`o8}xS?_UbcgkE>U%9Pq zvmKg;wS2ffez8Ol8p z*%c8-=^QfrR}*&`{`*uRlPp_1gqf+$Be#7URMqb8&}*@Deg%R%U-zbMMp+h)v*t0B zkfd#1pS~i8L57O7;+7v*m_zEL8I&XQ`CDJo!K)T=;~#u-Ga!`mJEF*|JaI*fwiDIE z{IEd}lJ7%k9n=)XH3>|@IM)=mY?IAVW1%6O*=3h$b~p4As&W zrL`H}x5*Ow^+CnB70zULjw8Ykm1?2QL>ANwcoxYEr*(zRrceFuYo!aefd#lJ)v_l_ z^q5Bobr+NR0PASjT;^F8@8jeJbFhM}N^J@ly4h!-&JJySr%-IDPoZHtF1+E*9Y^pq z=7W?3Rl9<&utye|R^82eAp237kGOY!$=+)`i2160OifC16z-YH^=k=@xf;W3NUzfB z$75w@m-6|YjFWt1XCzLD)R`az3kl;{bKb|*{m;NGvFC+vRyQYV6)TwOJl0QU*(pi6 zY31*$OvV-ZAvyNWs}>MoxMkPx0N!=N~L6l>{ZB)sO%BS-h2CplhE~Wh{*KZUY!~TXRq6$mH9eQ zBnfJ_*E2?-YH(Vds2tuM@b!GMh}nX+x>;tr6+@5x#uT_Z>QC&EQ~~3oU-4soMhxE9 z8)$r3JN&WB`e(yplniPD2oRn-XY#;!jkX0{0k{4Z4_)j6@%}$wv)h}ErLlV8dYJ;B z^J_-bgkMTiGh5D<`D?w8QMo_C}0cajxP6$Ar5;B7-ZCJ zanyM7r}O-Pg+oVkjLP`h_%z&DZh(-oD!q{nbT~2VqJ6g8MoUQf<*L>ziPjc!-20dH z|B4AXPO7S9X>zlduw!zqKn0^Kd-#H(#nwP$%N{UBeY9Rx9&xh#^}z%*$;68G%HV3^ zWaP$jY)r;JAoDR4NWTGRE4TWY$PJ!A6lAcA&R+3>0A?@GLNTOB2bb^QYZ0vSxcvg) z5%5;;Hnz{#erb|`-65&pl9Cg{@-k(uD;A&m6PQIkyvUu&>>p_#jZE8J zuLiG$5i`+Em6H5UugbF&*bZe|rSNEsZ-&jdR4}}1Y!h8k0@~tdt4f$V4oF!|8z}(1dKncio?-#}Ld=0tEct8eAZZJ_mxaf`0BMbGZAB8nDG%Wy_+1$ETVQ zq@K&J@J#;Qd;@;IkOrkUs4q?!D`(qn@rr$#~8@wEC42 z`XR6!+Wr~gjBzQdSg#oQdS4t6o{X>b(2bSpLZ{Y!zVUZ&)|6NhH9zP}SEjP%Wj9p} z=n`XTY@w=xV3hY7!1l|*>_>>aEFjXyo-bQi4ee_^_X=$W`$T~h!`sPGDq;y+jujsa zC19d#o%xcDL!wIl6pD6s){wj>FBJW#LB6W`(KUKi3Pi|X$?6;nxhX76`|KLp`Ja#@ z(>vpg8z?CUAH3XQ$B6HT;3HUX7tJCugXKi^M#o&XPh}dq>MHZl$)Z8$>w@QJUn~LJ z;?vJx>v%OAiN?F#EG*ygtJ%yqX+i2TvQXKjV$goqTfaXiNkoC7dakH{_HD)B0ra2i zsTiL3PUS)zGHtZZ(AXCx!=1^F*K?eI&m91g%zdqtiKW8;lX|FcKf}WD|XoO zt8cp7Vm{D1u}4`)xPd+j8Exnr`3J|-Xhl%BS~Fj)jssPcNLdDBte?E(XGE-n{bTTP z{@l<0K5|WW6DnKGp;I{Br~BZPw?ZIvR?O{wdy0gFx!4-pxh2R~w++P=msZr&CRBU` zRQzZrDJzEk;w-{$w!l8S15&<_Ni}QS5J58zS-rJD9|#l&D?^o?=lzp_qz@1o>DOp- zNRx2&fEM;%8+s1VWytN}Z|-@#$4^2Ir^Q&sbPrOe{|))6Ln8F1#(c*x$v@&CgaZ$Z zlDW!}=tQ^sTZf|Nr8yiUH$(OX7a(r+SFu?B)07SsRaG9OAAt6Bq}-WhnMeW(t_R<) zju{Az*_?Hdf){$c8JRKAMXI{(t|-&mg(Dj&2SSL{rNi2p-Pd0vQL}( z{_1hL-tYIS3jnHIeGYvzk|*_RjRq7SugD#ZypnMMP%ilhf^$9VJn!)>QHRt`s~i42 z2EhEmf{}}A8q+Qv^oWp^^rvqhT(53^*32LHN5Mun;2H6)^r*{aZ>55sjVQ!5KC_Hy zy*d7U&UBrjj_z^*PmEB)RkiUv;n8`*1B@T~^A@StWl)l`J8 zD81lgvq8$XYGEfOX5**Nx&RwN)XzyR^e)8rh4o6B$qIJ=pZ#?SuNTVd} zkA3OZkvqR>EwR4)DZ^V2#e&;{i! zt7D8awT^+`sUZCCg;!;sZ35vYu?xwmh}6BIjVhPMSH1i#5=)`C1E5UWvvFUW?!BVG zT`_hH)U~dSJbAEdnEm6$kc_rd-K_Di8q`d?_vB4Fg>uWPHtq)M5okFQwnJWT$?(YN z3=Vny`FfoaJ<)sEq>VyYflG-lQNLn*4+r~6N)lah);0Mmj2i~a$_{VmuV>9&y$UbV z)^%-X#NcB22;uNzrw(XD$!7)h@;94%0G3z_!4sNduX%@*Gu7L_a)V}b*ZkyW0rtvU z0alH@i#mnG7>2h7)Un>or}W~(-f~FG*RjmNC5gSM+kPR7GU;4HArU*;S5mohxQ3?1 z#+G0;y$M(`6UDY!3CF9c2dg$|Vu#l^B6cXhWeEHkl1XDeu? zdj?$RzflY-sF8qX_aW(5!_dO|=6d(`B6N2N09NCV`RuTOkWNMeK_g}-9m=N{V^VhC zJkl+&O;2*}`}hTy>K>5>MQ-Y%atiD!J7#05Yb75>brJq@!TNAZ0ohVtoJTh#(V{Fg zX#T?;m&A61txbM6^zj-gz7%?(+<*xiYz13Q;7DW--dlYqaaP(z(5QjNMHdASaQ0w* zXz7QB>WwT<=5L!CuzZ_tL6oNW(A?47AN5-nb*yQz$=J2N@8!p`X&!o z<(WQ~mqdGV?NmNjM<_$i+ar{KqJ)%^joR*K0jYS3?=?t(Bb$V^kRad{@SaVS$BnshNwF8 zt9J$$a-hLi1@i^L^(bEmfw`Wu6})~0i@-5KGTG-x^-{QPUDxeoQ6XrVQPsl4p?|or zOse8A_`fr1I!s3*Y5vl;#Tc=A|&4JrkZ z!(fPvL=|&i5~Iqa73|tHgG9o)kY&34#o$_P%k1;cLv9nzcTSI;C$E|!^Aml-T6x3& zCegtIu;;IVlF87BTN6ekLRf`^wQx?yin7bp60;>B=ZtYzUm!>OIi1`szEoc5u`3mbd)RT*H59 zQ)aQdo4irMg7nTpzY4tYVYa;rqMQmn0Ld(P8ALD!=$1#DBjG2b;m<3%gY5;=8xmX% zEaA#%_gQ&4TvzsVbQjzlq901U%8E`06A}lM7ohHV5lC3Su841UL$@+! zLAOYiDz$=yML+f!KDpmDGlUMNskv4@+xZ)_T^_Q`+$YkD3`Lp(u;S%o+hfpfO;eZ& zYFe4YzCtctfxHya<0a?(_M!YGgF4twuTmUE(hF@DOqG7M`Gst~Vb_E1={2zN6i9E> z#q#03YajL9uDT$KVgf=OQT**f#Z)z$fMdU8j>jM_6XuqPw}}Zk$cyyiu-Tv^kVNjN z0b73@CRHNrsg1<0MZ%|oY834{k(zXeb7H-ODEYPcwdY5Ix#|l??Hs)a0l_EuZpA6h zlg^XC_(I#gs{9QJ8K3MJdYuPen3#>AaQ*uE{PF*%6;uGcE)cwwS(yX zL9P;a9>?Tb?;Prpz-ae8cU)~hAiqH z^d%t)VMc(GCk=%&+AeAu_r zyy2`}AuxugQD_liOFMM2+t$M=3S><~BHd`fGlXZfg0)H&BD_#623E|Sk`%LKH^V_~ zy@tx+wTm%E(#k5A6zsyRp7p7_G3T^v0*N*Ks%Ddr$*7i7`CR)STY=` z-^Q~bBLj|s=c6T=QhR=ff49ZH2rbs*p%<=x~6zds1mIlLqie!Bh*Y*fsF9i zJyKRaKPJosf6d2>c6-$yEkk}ijvra3{iVD$cd{BARsGq$|!14Hu48(NH8=V zFV;&wb!e&i;^2lO!&xhtJ3bM7hpFZp zZ&Ug=mTS=Q$5|m}uO8zVCY{LvA8XsN(x!^WciAFt)sEQ+a%+HNf@;nXR_K zqIgHJyVdSPv>UV%c7DV~7hUng#qTd%=3p_Vl7NQ!L|a^WEC|e?dIYhWZZds0!j`xD zoi7uq^7)dPxraOu2XCGa1>Py*Af%;<-(8;XYo8b|8( z^CZkUGUBD#;fna;C@8~D{2a6#JFP??O2qf&{Svl|v0tY5ms1x5kjN#(h-jR2xSeNv z7AqILu6yqE59fGbM3_`@vE|9%aXzNyBzio1aL2O?xxM}*oS1Pah;{Agno_4|U(que zJiOCV@!?{4@?Ej(&e3^<)jmBYhCBb4={vR`Ils+^z6+^t<_!c0uhGbDpKZ0xmIwQ! z$>2P20kH_zM505`ZO>6MG_(vtQSvZ<9A zFlN83G*`AF(X|xTi2RE-oD6IxV$C4UF6pLyoct7mevnL`6S)21An<=`uasOUZWF z*$u+Ni^x~tUGiXf*M7VC1(5(&oqbhq1+yCcZ6;6T1b(N)#vk3i!t3SEFp_!r;nf%L z;oMLUv7=d1!7TIF-p|1`f&7#sa)IH|YX{)C%h7w86~r0u+3$Z`eKEM;arpW7%D(Rx z$tjcdg*sW6`YHyFr;HdZB3=6OM^gqH8O)rAM`n&Bwl#?yLqG6-(ftT0x*yL1J0-># zRaGulo_aU|t`j)qb$F>U)@jIk`h%-?T~1a@`S5X#oQUpp4nO~Iiy|dSyUFW!y7Bb2 zu;+;B3%4Onr^n{s-s?E?oTln<5`LF)h`(^_U(_;=Zr<6f_c>m8FJ>6y1kvL1(P?xA z!3drRdF*#u7|8mjThZb7 zZ^K4J7)5X$Isd z%%~+GJb|7lkvi7CelDPFt7~gqj;;qRg55}n)D$19-hZka(ZWcIE$^XyMKV_##Xdp{ zUsuaF=+EXrw%n_mwMFrr=DGjABq=Dc*&Zh1ve=8VV~~355$JmtE=pZ~ zuGJcSXurs%BEb!7>{Z93uS!xPF~~d(>zMx@8F`?jI>o!TkTI)F?{>4mrI4@xE^tQh z<>*MF@s7uY3+uf3d##l7(4+ldtK{cNA~*F@_QP|FpRx>pypJCE*#{oz!Se5(=EA_2 zxtMJJv#kHNZ}pj^(@)pzCsdsJPs08gZH4gV?(tFenLu*N(2_c=<0L+e=!CayKB3u$L0Utg(yiq?C{Qvmok;t1YC}P`5`P?Zs^zWW2yQA zMv!>Vp6$%Pas8VBy#&tmTQxy#Q3)?&~XjkHwYHsvt!}e<5~RA%>5F{-al6vH)plUr=^jvOb5Bf%sVuKVO(`(L|!^s*2RFN3O+XX`^*8d*vDaNS7?J=M+b2=O@y&$Zy!;kao(%7UF z-)Y_h{Ac#N%3U z;5SB^^^f25 z-uoZc9}fK%B@Gmpp7qgbm&EqE9991`f@Q~l_{l#309S1D^Dy>FEHIhr%X($t-v^mh zEwPQDIkKNb)^=h4THaBLVv^c#!E3=Ij|)t4?n0)2a=x#an(W|o>9%m}s>-puBA42a zvp;;WZ_OCJd`X~!gt$=ME*?-S#MnV_Vd*7Xe2tSnX9&qp1TOha+fcECpXGldV?Mr4P5{VZ6h5qe z`gY{Bvz`N)TV8$3c|5<>my%A?jtq5MKmN1x)v&J{Pb#|S@ZhuFsv9pL5`rc$RvVYD+P z3uI1Z)t{U%IP|yrknvm)zx{7Kzpb$?lrmW7=l&@^$sw54M7C_!Z9y28OH7UlxFm1s zqm*6D-ng=r{ggrUg?T6(G{q9p<84EnZ+UVv-ssVgvHwv!q>X1_Iu)w{Ym=wog}&OBi~WN$EtelvgX7V%I25z84V+_GN)K|C@7 zmcbzu%@s4MEJMVK>K>;W1P=i>;U{IJaFo8XL@{%%&R+L^(1(pYat;oHZE*6$zta~d`KZWQ zNvLGQm-8?<4^aa@SWOc5CShmLk*@FLv|;F~SFtUyAInVjKKPJR$bBeDh}+D=bNipR zhn*AF@t``M6cZdBAYPojGSkBbFOnE6gkZHZ@R`uM?fZ9~GQ$x$=DG@Ry{;LTKVD8h z=BWB-z(?{#(cvr~Ar-PA$P!8BAk!-I$kGi)M1bP`SJ2^q>7zt!0WFL;4=|?oN;4h2VSbbXX;GY&LBOH+~;9|BFbC zBXT1*sA@+Y|BwOx8~e9fjkxJ8*6)x033L&8{h59zbx(3c+OWQ~>P-om!f&8T&H@>^6FHW{&({Hj1U7tT0e?_&YM@WNg&fry+Z+)xw{H=m`mgaoHt zDjlrTj?|##vHXT9(ucFRfTa!HYexnbyj@(o%ZKg{5M4F+hOqnvKiHer7=b(x0VG$v zu4yBgvA~pr-H8#1C0nBYMBRLJhlTy};ex(Kl83@J$@i7u>0f6BEjeKaLr=^+DWIjE zdBPj|>i=9!$%Mn2Dtc;{0ed7o8IcPmZw~C{!tS#=ww33RJc1@d{zzdOj}9toKIpFA zKR*OfPR)73>(RcOZw-|tquXBN&B&i2Tz~qme3hbw*T_J-UbYETT?YB-H353e! zZ1vVR+ZrX_Z{%J29&^4ibw~zgv5xF^0MbvCqkJ|$`{Fd^;ZjDOfhm+u;<9%z!V59% zITKi2Lt;?TRV3^mxb!jm`LW0c-4U@lN+BRymMV(Vd=G5=K%3;1BQ3-gfV< zZWRxJiPttr>@R5sLsMiftD;_0>t7SVopGk$sz8}z4D9-|>{%ag==?2oSO%J8auv~~ zIxhRsI^UBL2>pIA0u^aR;1gvtIcEx5c@#zB%(n(0J9#-u&lWN)XG7LejCSW{D^}Xj z08BmyTr}P-Chj*@aFT(^VKU$&pi%^Vo+4JGGKnjcMbw_x&?QNV9*4Fneyw3?Tth#z zN2RWS80tTb_ynsUX@=;)px18^9l}Zm!pF0gZhd@xI;Kc!1umuRuf9XKi)~<{dy#Z) zJlF$e=L)`@51ChSiig}U#?Z!YGo&0+kNJy*xn7*K!HX5&Z=4BtRVgMafy`+w9*w5CcgXzluSee zLkRSJ_=FW40$E1kS;%E_|De4y_N>XidT-8lY$yG6d#@DgzAnI7^3;u`H7&CXAF18! zoQ!!j0-btK)9p>l)&deM{$-gK3Bj|#&wt|{&dcm5V)kWXK?ibDX1t2U_MvDyC)=IT);M3;_%g?;5AoOFlVpbc`U) zXyduiHxN(&`z;bNWu_fq^(Il*bNW@1R7PsD_s!Ou*K_2|gOGmW4y`jDey1+HPt@5P z2b#&VkRrAjz-)>_>R|fjwD&#|(+6_0yu~l)yt#ylc83r49t;{;&ZVAxBY&8@)-0#G z%qPUq3cUpU%&i$d9c(s8)IXcfTJnZy_#w(f-Tr0~4Kz+gLk=jsA8;-MHuVB13wC&*bHQiu#+jm<=n4ZGQ>Xs_m@mx` z@vX2Dd+2efv~R;7UO}@Ov{Bu*)$|I2x9W=Kn*nNv`>FfVC-fl&dZ*;pVz!C&Xs607 zaAgqzrqC?A_MuHnIy%=)@(h($E!C?e{H1o!ao!O~=V59DMmdX`m|q3}w4*yO=aUmt zOV`<;%ALGhSJaQ7G^%t zrX(7u&$($_1$i=-8em4HRROBWh-W&VZh)QLWz+o(N_Y>(Yc2CZxJ4t0XMv2nt27D5k~n-Q z%jD~XX?uo?E@^%5LFR+Kt6|&7Gio`D2S~fmAN)w!Cl7qIZ47XzObsOyk&abR@lLyh zanKo|G(WfFC47!25oC`0u2}zdi)@F^%!B2)YRoPAzH6ZKq92e1BEW7DYWq5pJWe+y zf`ed*-B(YCyddSt{jmDZ@N@fNU`aS%-8~R@tD@o3n*5{I-ySMm1fAp6;P{-`&506A z3#q?L2ue%0Ur~28Z4S|sj%B0T6+o!+*HS;$igxuIXlP>Kf6S4jg09D-odb~oA1NOU zzXBj1{mzI&El7j@?-U^Ge=|N0iE`OSHVEO5}6z5=>txlzyv_k6wA> z$@11cY&u;Gxm}DMJLOr<$}Qr%s6 z$KQ{zDx^~r3F`(1eZAcHcHuj)LQ>mpn%9@aZF-Mb-7$W>m$jq9jK?GOJ1a)-?yE*? zMg`B;;R0dR1)#BQb@NY*JYTrjdrh+{wJ(%qVXhLG)oO)jvd9X2J*N~OoCdxegU0=? z_5A%^0T7Yla|mc=*QVK6=Sgi!7t{#h^5|>Dez>QgM869gA3-bR&1qXK9f;U!^ayFm@8>{1;Dzv9%VD%?!_-Mns*3d^%pPBoksU1PgDb0xY zvGzhK8ryP}HpPN*|MFe+p+I|7^iWdc9>6xr^J(2<=?rQ8r{R95tIiCGDIRjS+ywQm z>WYWUFfKS?SIc_0)3mFcrTK*tezx!{Vlxdfv?*21!WTxK)#Vf5PZ%4qK8@Z^ z!CXM?8UQ%l1e40RHfUR{77uVE46~Gn6r7_~e!Zsp3wQhD4<_UP zjBqf`yx{I1x;U#3P|W|h42efZF1-s*Gd+f^v=U%jb#nIgP12eRKw0T^zMf=T9Vjm- zl4Sp|`fC<)MKlKVR6-eY5Fi#a#w(=`loCk~V0Z-_CaR7anZTuJ^m!=& z$=7R{0FEu3qy+VxK47JJ7!b z2pA|^uoLZS2>h;G=;Kc`38A%VXv~t5In%imGl#_zl+4XR^T+Kk~haYy`l8!)>P!(u)I zlg~<2mtpRi2_F%=0AI4v@9+@uKX%d?05jqY%d<%e|KL!fwQOi6%|$lV(9+3yNDm+*(80H2{CHQx711bi@Tcu-j-k z&iF+W1Y%epTY)7vu=BXv87#RO2OZD_eDtd1=v~0=gwLdNpZIDNOYXGCN9!z~6zpU; zNH6WfEVkH{gbt$I?)`MavMbMshMnUU{l_Yr=u?&JPt%Fs;200`cFETWjhad9Xc;7N zGowCKVubW#06G(uz5v%50p0fZU|~JSYb^k4gAfPXu`g~zK(0q&mi47?_)Vo4(5a?< z7X}n_)tNCz6a%hdJ(#AKZoRjvLt&Hl&%Aw+Q-$_kdh(!-dk|X5P&Oprx=;^z*A_d# z6KV+Nv80SNZnxhmf+9#`sn1*cKwc0QUDzrXbvlWE@CUV`SPp(kmPo`+{86r4)RU-F zeyrUpRB5}0PdG0;fg0e4lD}u;_Ld@jFd4sq`FBb46gAc+?Yr$l?dt)~u@5%~Cd4nk zo{{Cv{hCjP0IR+!`fRm4h=?B63V!ZL-+NtM%j9|d^T+OsFY9fo9Yj(5NNjcLdreg` zVB68)??3l&2kcMSjC&*{ujxJO(IKNbr}3NiRv#uDzrSAuu}k5;kr?89{r#)3Le{&V z*FC^HdfmXvAU5?}?&T`@QD1}2I-iYHD*lwtwFba!N5tHF+j~)e>B|L@_m7Ix)ZTy9H@g1w$x2LBI{~{M&0fy>&lImN z0p9lMH}2YD1d%qZad5M`GXjnZeu&;avH^~z%zx%`awDDCt)(O_guntA?gUuZeESZ&OFf_TQ2ZN}LsLt4KO`PB|WuV?2MuK>FuQ;bm!Fi7%e@*WuK@h?@|~pZ}umG}R?A-fs6$f#`&1cc-XTK{wMj z?KlMoy6=PiZErZ}kt<}-(?UaT%qw3b-wJD(fBgE3J)if#W+v8LA*#HNS)0a%OVdWR zQ0Xwi(0P(lzkEtcz&2d|2IomT+N&O0sr9~zcvo-~aep=~y5CBb#%Z_xcH3T{9?!^3&P_b6^zAwL-<>cF3>l^2;2I1 zVl=at;boy+ye>lN5($GLg#)K@A*J-Ca!Kd`bDnUt%;F8zYuj=YltvVG?yoQFh@W2s z7|6{*gXND29^vvg8C)iBCkpjx9c1f>UV8o#xA~T{u*FaDjpN7|(|0ZGTNmpoeYnyM zL<7~Xx7%T2h;O*53X_6?V#wbd@l;domJ#~BU?9DfcfS)XS zkJ|rY5xZ^NGMbR!5K8*h;`tIWwA~%l>W*`evv1veGO_VXUB_CkwD(*#{#Z!NH(@!m z+>ZI34t$@ftt89ZCn19%x$SS`^e>(22gZiX1hvy1N{}@s;m`^8ZFnHKlkjuuM!E|kAP} za4gTurjr#qp$sOfQa|mp*U}J=x1^rr#-+!_OwMH7VR2Wc(p{qzf{JY{gr=Bp;xrkxu!FKkhWH-l`G>06>*DONcy>trg*nA zY_bUrDOn5lNrPTvsZjNRF-FFV8`X@tcbDSMtaQQ3@3u=0xA<_GQToJ90~y}4)tc<+3!yIjBVTs~ht(bA4$3o3hPSVTHE z81?YXF63)*`DO{^>)5rAuIbwj7EU`XuWF%1Z¥GM&@EL$w97tj?C-ejimX5gu` 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≈Ivbk%v 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 X_{)_6(JBKw;GdJ41{$x_Ebje3a+eVr literal 0 HcmV?d00001 diff --git a/dev/build-detail.md b/dev/build-detail.md new file mode 100644 index 0000000..157e784 --- /dev/null +++ b/dev/build-detail.md @@ -0,0 +1,723 @@ +# MCPletA2A Platform - 详细开发计划 + +> 基于 Platform.png 架构图、Flow.png 参考流程及 MCPlet-spec-v202603-03 编写。 + +--- + +## 1. 目标 + +| 产出 | 路径 | +|------|------| +| 平台实现 | `/Users/qingjie.du/HDD/my-prjs/MCPletA2A/platform_impl/` | +| 参考实现 | `/Users/qingjie.du/HDD/my-prjs/MCPletA2A/reference_impl/` | + +**平台实现**:MCPlet Agent Profile Host,含 Director Agent、A2A 协议层、MCPlet Pool 管理与权限执行、Passkey Web Page、Dashboard、可替换 LLM 适配器。 + +**参考实现**:「降低餐厅取消率」场景——情報収集・分析 Agent → 企画・Plan Agent(店长 Passkey 确认)→ 発信・発注・発令 Agent(发邮件),驱动对应 MCPlets。 + +--- + +## 2. 技术栈 + +| 层次 | 选型 | 理由 | +|------|------|------| +| 语言 | TypeScript 5.x, Node.js 20+ | 与 reference_impl_restaurant 一致 | +| MCP | `@modelcontextprotocol/sdk` | 规范要求 | +| HTTP | Node.js 原生 `http` | 与现有参考实现一致,轻量 | +| 配置 | YAML + `js-yaml` | 可读性强,企业级友好 | +| 定时任务 | `node-cron` | Director Agent schedule | +| LLM 默认 | `@anthropic-ai/sdk` (claude-sonnet-4-6) | 通过适配器接口可替换任意 LLM | +| 测试 | `jest` + `ts-jest` | 标准 TS 测试方案 | + +--- + +## 3. 完整目录结构 + +``` +/MCPletA2A/ +├── platform_impl/ +│ ├── src/ +│ │ ├── types/ +│ │ │ ├── a2a.ts # A2AAgentCard / Envelope / TaskRequest / TaskResponse +│ │ │ ├── mcplet.ts # MCPletMeta / MCPletType / Visibility / PoolName +│ │ │ └── config.ts # PlatformConfig / PoolPolicy / AgentConfig / DirectorAgentConfig +│ │ ├── config/ +│ │ │ └── loader.ts # 加载并验证 platform.yaml → PlatformConfig +│ │ ├── discovery/ +│ │ │ └── mcplet-discovery.ts # MCP tools/list + 热重载 + 合规校验 +│ │ ├── pools/ +│ │ │ └── pool-registry.ts # Pool 注册表 + canAgentAccessPool + getToolsForAgent +│ │ ├── llm/ +│ │ │ ├── llm-adapter.ts # LLMAdapter 接口定义 +│ │ │ └── claude-adapter.ts # Claude 实现(@anthropic-ai/sdk) +│ │ ├── agents/ +│ │ │ ├── base-agent.ts # BaseAgent 抽象类(含 dispatchMCPlet 权限检查) +│ │ │ └── director-agent.ts # Director Agent(cron 触发,防并发) +│ │ ├── a2a/ +│ │ │ ├── local-bus.ts # A2A local protocol(进程内注册+路由) +│ │ │ └── external-endpoint.ts# A2A 外部 HTTP 端点(鉴权+Pool校验) +│ │ ├── passkey/ +│ │ │ └── passkey-server.ts # Passkey Web Page(localhost 模式,动态端口) +│ │ ├── dashboard/ +│ │ │ └── dashboard-server.ts # Dashboard HTTP 服务(MCPlet 列表+审计日志) +│ │ ├── host/ +│ │ │ └── mcplet-host.ts # MCPlet Host 主类,整合全部模块 +│ │ └── index.ts # 程序入口 +│ ├── config/ +│ │ └── platform.yaml # 平台配置模板 +│ ├── public/ +│ │ ├── passkey/ +│ │ │ └── index.html # Passkey Web Page(minimal, strict CSP) +│ │ └── dashboard/ +│ │ └── index.html # Dashboard 页面 +│ ├── package.json +│ └── tsconfig.json +│ +└── reference_impl/ + ├── mcplets/ + │ ├── media-pool/ + │ │ ├── site-access/ + │ │ │ └── index.ts # read_site_stats (read, media-pool, model-visible) + │ │ ├── email/ + │ │ │ └── index.ts # send_email (action, media-pool, passkey strict) + │ │ └── sns/ + │ │ └── index.ts # post_sns (action, media-pool, passkey strict) + │ ├── info-pool/ + │ │ ├── web-access/ + │ │ │ └── index.ts # fetch_web_content (read, info-pool, model-visible) + │ │ └── api-access/ + │ │ └── index.ts # call_external_api (read, info-pool, model-visible) + │ └── internal/ + │ ├── crm/ + │ │ └── index.ts # query_crm (read, no pool, model-visible) + │ ├── erp/ + │ │ └── index.ts # query_erp (read, no pool, model-visible) + │ └── hr/ + │ └── index.ts # query_hr (read, no pool, model-visible) + ├── agents/ + │ ├── info-gathering/ + │ │ └── index.ts # 情報収集・分析 Agent (accessiblePools: [info-pool]) + │ ├── planning/ + │ │ └── index.ts # 企画・Plan Agent (accessiblePools: []) + │ └── dispatch/ + │ └── index.ts # 発信・発注・発令 Agent (accessiblePools: [media-pool]) + ├── mock-services/ + │ ├── server.ts # Mock HTTP 服务器(端口 5100,挂载所有端点) + │ └── data/ + │ ├── customers.json # CRM:含 cancel_tendency 字段的顾客数据(5条) + │ ├── inventory.json # ERP:各商品库存 + │ ├── reservations.json # 明日の予約一覧 + │ └── weather.json # 天気予報(固定:明日は雨) + ├── config/ + │ └── reference.yaml # 参考实现配置(场景、schedule、agents、pools、mockServices) + ├── package.json + └── tsconfig.json +``` + +--- + +## 4. 核心类型定义(`src/types/`) + +### 4.1 `a2a.ts` + +```typescript +// Spec Section 18 + +export interface A2AAgentCard { + agentId: string; + displayName?: string; + description?: string; + requestedPools?: string[]; + inputSchema?: object; + outputSchema?: object; + version?: string; +} + +export interface A2AMessageEnvelope { + messageId: string; // UUID v4 + contextId?: string; // UUID v4, stable across delegated workflow + senderId: string; + recipientId: string; + timestamp?: string; // ISO 8601 UTC + locale?: string; // BCP 47 +} + +export interface A2ATaskRequest extends A2AMessageEnvelope { + type: 'task_request'; + payload: { + parameters: Record; + history?: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>; + }; +} + +export interface A2ATaskResponse extends A2AMessageEnvelope { + type: 'task_response'; + replyToMessageId: string; + status: 'success' | 'error' | 'timeout' | 'cancelled' | 'partial'; + payload?: { + result?: unknown; + error?: { message: string; code?: string }; + }; +} +``` + +### 4.2 `mcplet.ts` + +```typescript +export type MCPletType = 'read' | 'prepare' | 'action'; +export type Visibility = 'model' | 'app'; + +export interface MCPletMeta { + mcpletType: MCPletType; + pool?: string; + visibility: Visibility[]; + mcpletToolResultSchemaUri?: string; + auth?: { + required: 'passkey'; + enforcement: 'strict' | 'host-only'; + promptMessage?: string; + }; +} + +// MCPlet 工具结果信封(Spec Section 9.1) +export interface MCPletToolResult { + result?: T; + error?: { message: string; code: string }; + _meta: { + timestamp: string; + toolId: string; + mcpletType: MCPletType; + visibility: Visibility[]; + }; +} +``` + +### 4.3 `config.ts` + +```typescript +export interface PoolPolicy { + rateLimitPerMinute?: number; + domainAllowlist?: string[]; +} + +export interface AgentConfig { + class: string; // Agent 类名,用于注册表查找 + accessiblePools: string[]; + a2aCard?: Partial; +} + +export interface DirectorAgentConfig { + schedule: string; // cron 表达式 + promptTemplate: string; + targetAgentId: string; // 接收指令的 Agent + maxRetries: number; + backoffMs: number; +} + +export interface PasskeyConfig { + mode: 'localhost' | 'https'; + rpId: string; + fido2ServerUrl?: string; +} + +export interface PlatformConfig { + llm: { provider: string; model: string; apiKey?: string }; + pools: Record; + agents: Record; + directorAgent?: DirectorAgentConfig; + externalAgents?: Array<{ agentId: string; apiKey: string; accessiblePools: string[] }>; + passkey?: PasskeyConfig; + dashboard?: { port: number }; + a2aExternalEndpoint?: { port: number }; +} +``` + +--- + +## 5. 各模块详细规格 + +### 5.1 `discovery/mcplet-discovery.ts` + +```typescript +class MCPletDiscovery { + constructor(private mcpClient: MCPClient, private poolRegistry: PoolRegistry) {} + + async discover(): Promise + // 1. 调用 tools/list + // 2. 过滤: 无 _meta.mcpletType → reject + // 3. 过滤: action + visibility含model + 无auth → reject (记录 warn) + // 4. 按 _meta.pool 注册到 poolRegistry + // 5. 返回合规工具列表 + + subscribeToChanges(): void + // 监听 notifications/tools/list_changed → 重新执行 discover() + // 新增工具重新验证,删除工具从路由表移除 +} +``` + +### 5.2 `pools/pool-registry.ts` + +```typescript +class PoolRegistry { + constructor(private poolPolicies: Record) {} + + registerTool(tool: ToolDefinition, poolName?: string): void + canAgentAccess(agentId: string, poolName: string | undefined, agentPools: string[]): boolean + // - pool-less 工具:任何 Agent 可访问 + // - pool 工具:agentPools 必须包含该 pool + + getToolsForAgent(agentId: string, agentPools: string[]): ToolDefinition[] + // 返回该 Agent 被授权访问的全部工具(用于构建 LLM tool set) + + checkRateLimit(poolName: string): boolean +} +``` + +### 5.3 `llm/llm-adapter.ts` + +```typescript +export interface Message { + role: 'system' | 'user' | 'assistant'; + content: string; +} + +export interface ToolDef { + name: string; + description: string; + inputSchema: object; +} + +export interface LLMToolCall { + toolName: string; + arguments: Record; +} + +export interface LLMResponse { + text?: string; + toolCalls?: LLMToolCall[]; +} + +export interface LLMAdapter { + chat(messages: Message[], tools?: ToolDef[]): Promise; +} +``` + +### 5.4 `agents/base-agent.ts` + +```typescript +abstract class BaseAgent { + constructor( + public readonly agentId: string, + public readonly accessiblePools: string[], + protected poolRegistry: PoolRegistry, + protected mcpClient: MCPClient, + protected llm: LLMAdapter, + ) {} + + abstract handle(task: A2ATaskRequest): Promise; + + protected getAuthorizedTools(): ToolDef[] + // 调用 poolRegistry.getToolsForAgent,仅返回 model-visible 工具 + + protected async invokeMCPlet(toolName: string, args: object): Promise + // 1. 检查工具是否在授权 Pool 内(否则抛出 403 等价错误) + // 2. 检查 mcpletType:action 工具走 Passkey 拦截流程 + // 3. 发送 MCP tools/call + // 4. 返回结果 + + protected buildSuccessResponse(task: A2ATaskRequest, result: unknown): A2ATaskResponse + protected buildErrorResponse(task: A2ATaskRequest, message: string, code?: string): A2ATaskResponse +} +``` + +### 5.5 `agents/director-agent.ts` + +```typescript +class DirectorAgent { + private running = false; + private cronJob: cron.ScheduledTask; + + constructor( + private config: DirectorAgentConfig, + private llm: LLMAdapter, + private localBus: A2ALocalBus, + ) {} + + start(): void + // node-cron.schedule(config.schedule, this.run.bind(this)) + + private async run(): Promise + // 1. if (this.running) { log "skipping, previous cycle still active"; return; } + // 2. this.running = true + // 3. try: + // a. LLM(config.promptTemplate) → instruction + // b. 解析失败 → log + return(不 dispatch) + // c. localBus.sendTask(config.targetAgentId, instruction) + // d. 重试逻辑:最多 config.maxRetries 次,间隔 config.backoffMs + // 4. finally: this.running = false + + stop(): void +} +``` + +### 5.6 `a2a/local-bus.ts` + +```typescript +class A2ALocalBus { + private agents = new Map(); + + register(agent: BaseAgent): void + + async sendTask(request: A2ATaskRequest): Promise + // 1. 查找 recipientId 对应 Agent(未找到 → error response) + // 2. 调用 agent.handle(request) + // 3. local bus 消息 MUST NOT 路由到进程外(纯内存调用) +} +``` + +### 5.7 `a2a/external-endpoint.ts` + +```typescript +// HTTP POST /a2a/task +// Headers: Authorization: Bearer + +class A2AExternalEndpoint { + constructor( + private config: PlatformConfig, + private localBus: A2ALocalBus, + private poolRegistry: PoolRegistry, + ) {} + + start(port: number): void + + private async handleTask(req, res): Promise + // 1. 验证 Bearer token → 找到对应外部 Agent 配置(否则 401) + // 2. 解析 A2ATaskRequest(Spec Section 18 schema) + // 3. 检查 recipientId 对应 Agent 的工具 ∩ 外部 Agent 授权 Pool(否则 403) + // 4. 转发到 localBus.sendTask + // 5. 返回 A2ATaskResponse JSON +} +``` + +### 5.8 `passkey/passkey-server.ts` + +```typescript +class PasskeyServer { + private port: number; + + async startCeremony(promptMessage: string): Promise + // 1. 动态绑定 loopback 端口 + // 2. 在系统浏览器打开 http://localhost:{port}/passkey?msg=... + // 3. 等待回调(POST /passkey/callback)或超时(< 60s) + // 4. 超时/取消 → 抛出错误(Host 返回 MCP Error) + // 5. 回调成功 → 返回 assertion,关闭页面和端口 + + stop(): void +} + +// public/passkey/index.html: +// - 读取 ?msg query param +// - 调用 navigator.credentials.get()(WebAuthn) +// - POST assertion 到 /passkey/callback +// - 严格 CSP(no external scripts) +``` + +### 5.9 `host/mcplet-host.ts` + +```typescript +class MCPletHost { + async start(configPath: string): Promise + // 按序初始化: + // 1. loadConfig(configPath) → PlatformConfig + // 2. new PoolRegistry(config.pools) + // 3. new MCPletDiscovery(mcpClient, poolRegistry) → discover() + // 4. new LLMAdapter(config.llm) // ClaudeAdapter 或其他 + // 5. new A2ALocalBus() + // 6. 注册参考实现中的 Agent(Info/Plan/Dispatch) + // 7. new DirectorAgent(config.directorAgent, llm, localBus) → start() + // 8. if (config.passkey) → new PasskeyServer(config.passkey) + // 9. if (config.dashboard) → new DashboardServer(...) → start() + // 10. if (config.a2aExternalEndpoint) → new A2AExternalEndpoint(...) → start() +} +``` + +--- + +## 6. 参考实现 MCPlet 规格 + +所有 MCPlet 遵循以下模式(以 `email/index.ts` 为例): + +```typescript +import { registerModelTool, registerAppTool } from '../../../platform_impl/src/mcplet-lib'; + +// send_email: action, media-pool, app-only(需 Passkey 授权后由 dispatch agent 调用) +registerAppTool(server, { + name: 'send_email', + title: 'メール送信', + description: 'Send email to specified recipients', + inputSchema: SendEmailSchema, + mcpletType: 'action', + pool: 'media-pool', + visibility: ['app'], + auth: { + required: 'passkey', + enforcement: 'strict', + promptMessage: 'メール送信を承認してください' + }, + handler: sendEmailHandler, +}); +``` + +### Mock Service 端点(port 5100) + +| 端点 | 方法 | 说明 | 对应 MCPlet | +| ---- | ---- | ---- | ---------- | +| `/crm/customers?filter=rain_cancel_tendency` | GET | 雨天取消倾向高的顾客列表(5条固定数据) | query_crm | +| `/crm/reservations?date=YYYY-MM-DD` | GET | 指定日期预约列表 | query_crm | +| `/erp/inventory?item=dessert` | GET | 甜点库存 | query_erp | +| `/weather/forecast?date=YYYY-MM-DD` | GET | 天气预报(固定返回「明日は雨」) | fetch_web_content | +| `/site/stats` | GET | EPARK 站点访问数据 | read_site_stats | +| `/email/send` | POST | Mock 发信(记录日志,不真实发送) | send_email | +| `/sns/post` | POST | Mock SNS(记录日志) | post_sns | + +MCPlet handler 通过 `config.mockServiceUrl`(`http://localhost:5100`)调用以上端点,替换真实服务只需修改配置,handler 代码不变。 + +--- + +## 7. 参考实现 MCPlet 规格 + +| MCPlet | Tool 名 | mcpletType | pool | visibility | auth | +|--------|---------|-----------|------|------------|------| +| サイトアクセス | `read_site_stats` | read | media-pool | [model] | — | +| Email | `send_email` | action | media-pool | [app] | passkey strict | +| SNS | `post_sns` | action | media-pool | [app] | passkey strict | +| 外部Web | `fetch_web_content` | read | info-pool | [model] | — | +| 外部API | `call_external_api` | read | info-pool | [model] | — | +| CRM | `query_crm` | read | (none) | [model] | — | +| ERP | `query_erp` | read | (none) | [model] | — | +| HR | `query_hr` | read | (none) | [model] | — | + +--- + +## 7. 参考实现 Agent 规格 + +### 7.1 情報収集・分析 Agent + +```typescript +class InfoGatheringAgent extends BaseAgent { + // agentId: 'info-gathering-agent' + // accessiblePools: ['info-pool'] + // 可用工具: fetch_web_content, call_external_api, query_crm, query_erp, query_hr (pool-less) + + async handle(task: A2ATaskRequest): Promise { + // 1. 将 task.payload.parameters 拼入 system prompt + // 2. LLM 根据任务决定调用哪些 read MCPlets + // 3. 执行工具调用循环(tool_use → invokeMCPlet → 返回结果给 LLM) + // 4. LLM 输出分析总结 + // 5. 返回 success response(result: { analysis, rawData }) + } +} +``` + +### 7.2 企画・Plan Agent + +```typescript +class PlanningAgent extends BaseAgent { + // agentId: 'planning-agent' + // accessiblePools: [] (只访问 pool-less MCPlets) + // 可用工具: query_crm, query_erp, query_hr + + async handle(task: A2ATaskRequest): Promise { + // 1. 接收来自 info-gathering 的分析结果 + // 2. 查询必要的 CRM/ERP 数据(pool-less MCPlets) + // 3. LLM 生成 Plan(含具体施策、对象顾客列表、邮件文案) + // 4. 通过 Passkey Web Page 请求店长审批(auth.enforcement: host-only 模式) + // 5. 审批通过 → 返回 success(result: { plan, approvedAt }) + // 6. 审批拒绝/超时 → 返回 cancelled + } +} +``` + +### 7.3 発信・発注・発令 Agent + +```typescript +class DispatchAgent extends BaseAgent { + // agentId: 'dispatch-agent' + // accessiblePools: ['media-pool'] + // 可用工具: read_site_stats, send_email, post_sns (需 Passkey) + + async handle(task: A2ATaskRequest): Promise { + // 1. 接收企划方案(plan + 顾客列表 + 邮件文案) + // 2. 对 send_email 工具调用: + // a. BaseAgent.invokeMCPlet 拦截 action 工具 + // b. 调用 PasskeyServer.startCeremony() + // c. 拿到 assertion → 注入 params._meta.mcplet_auth + // d. 真正执行 MCP tools/call + // 3. 记录发送结果到审计日志 + // 4. 返回 success(result: { sent: n, failed: m }) + } +} +``` + +--- + +## 8. 参考实现配置 `reference.yaml` + +```yaml +llm: + provider: claude + model: claude-sonnet-4-6 + apiKey: ${ANTHROPIC_API_KEY} + +pools: + media-pool: + rateLimitPerMinute: 60 + info-pool: + rateLimitPerMinute: 120 + +agents: + info-gathering-agent: + class: InfoGatheringAgent + accessiblePools: [info-pool] + planning-agent: + class: PlanningAgent + accessiblePools: [] + dispatch-agent: + class: DispatchAgent + accessiblePools: [media-pool] + +directorAgent: + schedule: "0 7 * * *" + targetAgentId: info-gathering-agent + promptTemplate: | + 今日の天気予報と在庫情報、キャンセル傾向の高い予約客情報を収集・分析し、 + キャンセル率を下げる施策を立案してください。 + maxRetries: 3 + backoffMs: 5000 + +passkey: + mode: localhost + rpId: localhost + +dashboard: + port: 4000 + +a2aExternalEndpoint: + port: 4001 +``` + +--- + +## 9. 完整流程(Flow.png 场景) + +``` +[cron 07:00] + │ + ▼ +DirectorAgent.run() + │ LLM(promptTemplate) → "キャンセル率低減タスク開始" + │ + ▼ +A2ALocalBus.sendTask("info-gathering-agent", task) + │ + ▼ +InfoGatheringAgent.handle(task) + ├─ invokeMCPlet("fetch_web_content", {url: "天気予報"}) ← info-pool + ├─ invokeMCPlet("call_external_api", {source: "在庫API"}) ← info-pool + └─ invokeMCPlet("query_crm", {filter: "雨天キャンセル傾向"}) ← pool-less + │ → LLM分析 → { analysis: "明日は雨、在庫あり、高キャンセル客10名" } + │ + ▼ +A2ALocalBus.sendTask("planning-agent", { analysis }) + │ + ▼ +PlanningAgent.handle(task) + ├─ invokeMCPlet("query_erp", {item: "デザート"}) ← pool-less + └─ LLM生成企划: "無料デザートキャンペーン、対象: 10名" + │ PasskeyServer.startCeremony("キャンペーン計画を承認してください") + │ [店长在浏览器中进行 WebAuthn 认证] + │ → { plan, approvedAt } + │ + ▼ +A2ALocalBus.sendTask("dispatch-agent", { plan }) + │ + ▼ +DispatchAgent.handle(task) + └─ invokeMCPlet("send_email", { to: [...10名...], body: "..." }) + ├─ 拦截 action 工具 + ├─ PasskeyServer.startCeremony("メール送信を承認してください") + ├─ 注入 params._meta.mcplet_auth + └─ MCP tools/call → Email MCPlet 后端验证 Passkey → 发送邮件 +``` + +--- + +## 10. 开发阶段与顺序 + +``` +Phase 1: 项目骨架 + platform_impl: package.json, tsconfig.json, 目录结构 + reference_impl: package.json, tsconfig.json, 目录结构 + +Phase 2: 类型层(src/types/) + a2a.ts, mcplet.ts, config.ts + +Phase 3: 配置加载(src/config/loader.ts) + + platform.yaml 示例 + +Phase 4: Pool 管理(src/pools/pool-registry.ts) + + MCPlet 发现(src/discovery/mcplet-discovery.ts) + +Phase 5: LLM 适配器(src/llm/) + llm-adapter.ts(接口) + claude-adapter.ts(实现) + +Phase 6: Agent 框架(src/agents/) + base-agent.ts(含 invokeMCPlet 权限检查 + action 拦截骨架) + director-agent.ts(cron + 防并发 + 重试) + +Phase 7: A2A 协议(src/a2a/) + local-bus.ts(进程内路由) + external-endpoint.ts(HTTP + 鉴权 + Pool校验) + +Phase 8: Host 主入口(src/host/mcplet-host.ts + src/index.ts) + 整合 Phase 2-7,平台实现可独立运行 + +Phase 9: 参考实现 MCPlets + info-pool: fetch_web_content, call_external_api + internal: query_crm, query_erp, query_hr + media-pool: read_site_stats, send_email, post_sns + +Phase 10: 参考实现 Agents + InfoGatheringAgent, PlanningAgent, DispatchAgent + + reference.yaml + +Phase 11: Passkey Web Page(src/passkey/ + public/passkey/) + localhost 模式,动态端口,WebAuthn ceremony + +Phase 12: Dashboard(src/dashboard/ + public/dashboard/) + MCPlet 列表 + action 审计日志展示 + +Phase 13: 集成测试 + 完整流程 E2E:Director → 情報収集 → 企画 → 発信 +``` + +--- + +## 11. 验收标准(Checklist) + +### 平台实现 +- [ ] MCPlet 发现:无 `_meta.mcpletType` 工具被拒绝;`action + model-visible + 无auth` 被拒绝 +- [ ] Pool 权限:Agent 调用授权范围外工具时得到明确错误 +- [ ] Director Agent:cron 按时触发;LLM 解析失败时跳过不 panic;同一 Director 不并发执行 +- [ ] A2A Local Bus:进程内消息路由正确 +- [ ] A2A 外部端点:未授权 → 401;Pool 范围外 → 403;合法请求转发 → 正确响应 +- [ ] Passkey Web Page:localhost 动态端口;assertion 回调后关闭;超时返回 MCP Error +- [ ] Dashboard:可查看 MCPlet 列表 + 最近 action 审计日志 + +### 参考实现 +- [ ] 各 MCPlet 正确注册(mcpletType / pool / visibility / auth) +- [ ] InfoGatheringAgent 只能访问 info-pool + pool-less MCPlets +- [ ] PlanningAgent 只能访问 pool-less MCPlets +- [ ] DispatchAgent 只能访问 media-pool MCPlets +- [ ] 完整场景流程一次性跑通:Director → 情報収集 → 企画 → Passkey 审批 → 発信 +- [ ] send_email 调用经过 Passkey 拦截 + assertion 注入 + 后端验证 diff --git a/dev/build.md b/dev/build.md new file mode 100644 index 0000000..a27f72b --- /dev/null +++ b/dev/build.md @@ -0,0 +1,18 @@ + +实现Platform.png的MCPletA2A平台(Agent Profile)及Flow.png的参考实现。 + +## 参考: +1. MCPlet规范:/Users/qingjie.du/HDD/my-prjs/MCPlet/about/MCPlet-spec-v202603-03.md +2. 餐厅预订参考实现(属于WebUI Profile,不是Agent Profile,所以只需要参考其可用部分):/Users/qingjie.du/HDD/my-prjs/MCPlet/reference_impl_restaurant_reservations + +## 注意事项 +- 平台实现及参考实现的代码要明确分开,且要有清晰的目录结构。平台实现主要负责MCPletA2A平台的搭建和维护,而参考实现则是基于该平台的具体应用示例。 +- 在实现过程中,要严格遵守MCPlet规范,确保平台和参考实现的兼容性和可扩展性。 +- 参考实现的代码要尽量简洁明了,注释清晰,以便其他开发者能够快速理解和使用。 +- 在开发过程中,可以参考MCPlet规范中的示例代码和最佳实践,但要根据实际需求进行调整和优化。 +- 在完成平台和参考实现后,要进行充分的测试,确保其功能的正确性和稳定性。可以编写单元测试和集成测试来验证各个模块的功能。 +- 编码及架构选择要考虑企业级应用的需求,如性能、可维护性、安全性等方面。可以采用分层架构、模块化设计等方式来提高系统的可扩展性和可维护性。 +- 最后,要编写详细的文档,说明平台和参考实现的架构设计、使用方法、API接口等,以便其他开发者能够快速上手和使用。文档可以包括代码注释、使用指南、API文档等内容。 +- 代码的输出路径: + - 平台实现:/Users/qingjie.du/HDD/my-prjs/MCPlet/MCPletA2A/platform_impl + - 参考实现:/Users/qingjie.du/HDD/my-prjs/MCPlet/MCPletA2A/reference_impl diff --git a/platform_impl/config/platform.yaml b/platform_impl/config/platform.yaml new file mode 100644 index 0000000..936a588 --- /dev/null +++ b/platform_impl/config/platform.yaml @@ -0,0 +1,57 @@ +# MCPletA2A Platform Configuration Template +# Copy and customize for your deployment. + +llm: + provider: claude + model: claude-sonnet-4-6 + apiKey: ${ANTHROPIC_API_KEY} + +# --- OpenRouter alternative --- +# llm: +# provider: openrouter +# model: anthropic/claude-sonnet-4-5 +# apiKey: ${OPENROUTER_API_KEY} +# siteUrl: https://your-site.example.com # optional, sent as HTTP-Referer +# siteName: MCPletA2A # optional, sent as X-Title + +pools: + media-pool: + rateLimitPerMinute: 60 + info-pool: + rateLimitPerMinute: 120 + +agents: + info-gathering-agent: + class: InfoGatheringAgent + accessiblePools: [info-pool] + description: 情報収集・分析 Agent + planning-agent: + class: PlanningAgent + accessiblePools: [] + description: 企画・Plan Agent + dispatch-agent: + class: DispatchAgent + accessiblePools: [media-pool] + description: 発信・発注・発令 Agent + +directorAgent: + schedule: "0 7 * * *" + targetAgentId: info-gathering-agent + promptTemplate: | + 今日の天気予報と在庫情報、キャンセル傾向の高い予約客情報を収集・分析し、 + キャンセル率を下げる施策を立案するためのデータを収集してください。 + 対象日付: {date} + maxRetries: 3 + backoffMs: 5000 + +externalAgents: [] + +passkey: + mode: localhost + rpId: localhost + +dashboard: + port: 4000 + +a2aExternalEndpoint: + port: 4001 diff --git a/platform_impl/package-lock.json b/platform_impl/package-lock.json new file mode 100644 index 0000000..b4347ef --- /dev/null +++ b/platform_impl/package-lock.json @@ -0,0 +1,5183 @@ +{ + "name": "mcplet-a2a-platform", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mcplet-a2a-platform", + "version": "0.1.0", + "dependencies": { + "@anthropic-ai/sdk": "^0.39.0", + "@modelcontextprotocol/sdk": "^1.10.2", + "js-yaml": "^4.1.0", + "node-cron": "^3.0.3", + "openai": "^6.33.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^22.0.0", + "@types/node-cron": "^3.0.11", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.0", + "typescript": "^5.7.0" + } + }, + "node_modules/@anthropic-ai/sdk": { + "version": "0.39.0", + "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.39.0.tgz", + "integrity": "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg==", + "license": "MIT", + "dependencies": { + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7" + } + }, + "node_modules/@anthropic-ai/sdk/node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@anthropic-ai/sdk/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.28.0.tgz", + "integrity": "sha512-gmloF+i+flI8ouQK7MWW4mOwuMh4RePBuPFAEPC6+pdqyWOUMDOixb6qZ69owLJpz6XmyllCouc4t8YWO+E2Nw==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/node-cron": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/@types/node-cron/-/node-cron-3.0.11.tgz", + "integrity": "sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node-fetch": { + "version": "2.6.13", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz", + "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "form-data": "^4.0.4" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "license": "MIT", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/agentkeepalive": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", + "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", + "license": "MIT", + "dependencies": { + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.11.tgz", + "integrity": "sha512-DAKrHphkJyiGuau/cFieRYhcTFeK/lBuD++C7cZ6KZHbMhBrisoi+EvhQ5RZrIfV5qwsW8kgQ07JIC+MDJRAhg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/form-data-encoder": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz", + "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==", + "license": "MIT" + }, + "node_modules/form-data/node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/form-data/node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/formdata-node": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz", + "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==", + "license": "MIT", + "dependencies": { + "node-domexception": "1.0.0", + "web-streams-polyfill": "4.0.0-beta.3" + }, + "engines": { + "node": ">= 12.20" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", + "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", + "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-cron": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/node-cron/-/node-cron-3.0.3.tgz", + "integrity": "sha512-dOal67//nohNgYWb+nWmg5dkFdIwDm8EpeGYMekPMrngV3637lqnX0lbUcCtgibHTz6SEz7DAIjKvKDFYCnO1A==", + "license": "ISC", + "dependencies": { + "uuid": "8.3.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/node-cron/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/openai": { + "version": "6.33.0", + "resolved": "https://registry.npmjs.org/openai/-/openai-6.33.0.tgz", + "integrity": "sha512-xAYN1W3YsDXJWA5F277135YfkEk6H7D3D6vWwRhJ3OEkzRgcyK8z/P5P9Gyi/wB4N8kK9kM5ZjprfvyHagKmpw==", + "license": "Apache-2.0", + "bin": { + "openai": "bin/cli" + }, + "peerDependencies": { + "ws": "^8.18.0", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "ws": { + "optional": true + }, + "zod": { + "optional": true + } + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, + "node_modules/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/web-streams-polyfill": { + "version": "4.0.0-beta.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz", + "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/platform_impl/package.json b/platform_impl/package.json new file mode 100644 index 0000000..961250e --- /dev/null +++ b/platform_impl/package.json @@ -0,0 +1,30 @@ +{ + "name": "mcplet-a2a-platform", + "version": "0.1.0", + "description": "MCPlet Agent Profile Host — platform implementation", + "type": "module", + "main": "dist/index.js", + "scripts": { + "build": "tsc", + "start": "node dist/index.js", + "dev": "tsc --watch", + "test": "jest" + }, + "dependencies": { + "@anthropic-ai/sdk": "^0.39.0", + "@modelcontextprotocol/sdk": "^1.10.2", + "js-yaml": "^4.1.0", + "node-cron": "^3.0.3", + "openai": "^6.33.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^22.0.0", + "@types/node-cron": "^3.0.11", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.0", + "typescript": "^5.7.0" + } +} diff --git a/platform_impl/public/passkey/index.html b/platform_impl/public/passkey/index.html new file mode 100644 index 0000000..0fc71a4 --- /dev/null +++ b/platform_impl/public/passkey/index.html @@ -0,0 +1,117 @@ + + + + + + MCPletA2A — Passkey 認証 + + + + +
+
🔐
+

Passkey 認証

+

{{PROMPT_MESSAGE}}

+ + +

+
+ + + + diff --git a/platform_impl/src/a2a/external-endpoint.ts b/platform_impl/src/a2a/external-endpoint.ts new file mode 100644 index 0000000..1b24377 --- /dev/null +++ b/platform_impl/src/a2a/external-endpoint.ts @@ -0,0 +1,125 @@ +import http from 'http'; +import { randomUUID } from 'crypto'; +import type { PlatformConfig, A2ATaskRequest } from '../types/index.js'; +import type { A2ALocalBus } from './local-bus.js'; +import type { PoolRegistry } from '../pools/pool-registry.js'; +import type { AuditLog } from '../host/audit-log.js'; + +/** + * A2A External Endpoint — HTTP server for External Agents. + * Spec Section 3.6, 16.4, 18 + * + * POST /a2a/task + * Authorization: Bearer + * Body: A2ATaskRequest (JSON) + */ +export class A2AExternalEndpoint { + private server: http.Server | null = null; + + constructor( + private readonly config: PlatformConfig, + private readonly localBus: A2ALocalBus, + private readonly poolRegistry: PoolRegistry, + private readonly auditLog: AuditLog, + ) {} + + start(port: number): void { + this.server = http.createServer((req, res) => { + void this.handleRequest(req, res); + }); + this.server.listen(port, () => { + console.log(`[a2a-external] Listening on port ${port}`); + }); + } + + stop(): void { + this.server?.close(); + } + + private async handleRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise { + if (req.method !== 'POST' || req.url !== '/a2a/task') { + sendJson(res, 404, { error: 'Not found' }); + return; + } + + // Authenticate external agent (Spec Section 16.4) + const externalAgent = this.authenticateRequest(req); + if (!externalAgent) { + sendJson(res, 401, { error: 'Unauthorized: invalid or missing API key' }); + return; + } + + let body: A2ATaskRequest; + try { + body = await parseJsonBody(req); + } catch { + sendJson(res, 400, { error: 'Invalid JSON body' }); + return; + } + + if (body.type !== 'task_request') { + sendJson(res, 400, { error: 'Expected type: task_request' }); + return; + } + + // Enforce Pool access: validate that the target agent's tools are within external agent's granted pools + const targetTools = this.poolRegistry.getToolsForAgent( + body.recipientId, + externalAgent.accessiblePools, + ); + if (targetTools.length === 0 && body.recipientId !== 'director-agent') { + sendJson(res, 403, { + error: `External agent "${externalAgent.agentId}" has no pool access to reach agent "${body.recipientId}"`, + }); + return; + } + + this.auditLog.record({ + type: 'external_agent_request', + agentId: externalAgent.agentId, + contextId: body.contextId ?? randomUUID(), + timestamp: new Date().toISOString(), + detail: `→ ${body.recipientId}`, + }); + + try { + const response = await this.localBus.sendTask(body); + sendJson(res, 200, response); + } catch (err) { + sendJson(res, 500, { error: (err as Error).message }); + } + } + + private authenticateRequest( + req: http.IncomingMessage, + ): { agentId: string; accessiblePools: string[] } | null { + const authHeader = req.headers['authorization']; + if (!authHeader?.startsWith('Bearer ')) return null; + + const token = authHeader.slice(7).trim(); + const extAgents = this.config.externalAgents ?? []; + const match = extAgents.find((a) => a.apiKey === token); + return match ?? null; + } +} + +function sendJson(res: http.ServerResponse, status: number, body: unknown): void { + const payload = JSON.stringify(body); + res.writeHead(status, { 'Content-Type': 'application/json' }); + res.end(payload); +} + +function parseJsonBody(req: http.IncomingMessage): Promise { + return new Promise((resolve, reject) => { + let data = ''; + req.on('data', (chunk: Buffer) => { data += chunk.toString(); }); + req.on('end', () => { + try { + resolve(JSON.parse(data) as T); + } catch { + reject(new Error('Invalid JSON')); + } + }); + req.on('error', reject); + }); +} diff --git a/platform_impl/src/a2a/local-bus.ts b/platform_impl/src/a2a/local-bus.ts new file mode 100644 index 0000000..e454e66 --- /dev/null +++ b/platform_impl/src/a2a/local-bus.ts @@ -0,0 +1,74 @@ +import type { A2ATaskRequest, A2ATaskResponse } from '../types/index.js'; + +/** Minimal interface required for local bus routing. */ +export interface IAgent { + readonly agentId: string; + handle(task: A2ATaskRequest): Promise; +} + +/** + * A2A Local Protocol Bus — in-process agent registration and message routing. + * Spec Section 3.4: messages MUST NOT be routable outside the Host process boundary. + */ +export class A2ALocalBus { + private readonly agents = new Map(); + + register(agent: IAgent): void { + if (this.agents.has(agent.agentId)) { + throw new Error(`[a2a-local-bus] Agent "${agent.agentId}" is already registered`); + } + this.agents.set(agent.agentId, agent); + console.log(`[a2a-local-bus] Registered agent "${agent.agentId}"`); + } + + async sendTask(request: A2ATaskRequest): Promise { + const agent = this.agents.get(request.recipientId); + if (!agent) { + return { + messageId: crypto.randomUUID(), + contextId: request.contextId, + senderId: 'local-bus', + recipientId: request.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: request.messageId, + status: 'error', + payload: { + error: { + message: `Agent "${request.recipientId}" not found in local bus`, + code: 'NOT_FOUND', + }, + }, + }; + } + + console.log( + `[a2a-local-bus] ${request.senderId} → ${request.recipientId} (contextId=${request.contextId ?? 'n/a'})`, + ); + + try { + return await agent.handle(request); + } catch (err) { + return { + messageId: crypto.randomUUID(), + contextId: request.contextId, + senderId: agent.agentId, + recipientId: request.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: request.messageId, + status: 'error', + payload: { + error: { + message: (err as Error).message, + code: 'UNKNOWN_ERROR', + }, + }, + }; + } + } + + getRegisteredAgentIds(): string[] { + return [...this.agents.keys()]; + } +} diff --git a/platform_impl/src/agents/base-agent.ts b/platform_impl/src/agents/base-agent.ts new file mode 100644 index 0000000..17c11c6 --- /dev/null +++ b/platform_impl/src/agents/base-agent.ts @@ -0,0 +1,243 @@ +import { randomUUID } from 'node:crypto'; +import type { + A2ATaskRequest, + A2ATaskResponse, + MCPletTool, + MCPletToolResult, + MCPletErrorCode, +} from '../types/index.js'; +import type { PoolRegistry } from '../pools/pool-registry.js'; +import type { LLMAdapter, LLMMessage, LLMToolDef, LLMToolCall } from '../llm/llm-adapter.js'; +import type { PasskeyServer, PasskeyPlatformService } from '../passkey/index.js'; +import type { MCPletRouter } from '../host/mcplet-router.js'; +import { AuditLog } from '../host/audit-log.js'; + +export interface AgentDeps { + poolRegistry: PoolRegistry; + mcpRouter: MCPletRouter; + llm: LLMAdapter; + passkeyServer?: PasskeyServer; + passkeyPlatformService?: PasskeyPlatformService; + auditLog: AuditLog; +} + +export abstract class BaseAgent { + constructor( + public readonly agentId: string, + public readonly accessiblePools: string[], + protected readonly deps: AgentDeps, + ) {} + + abstract handle(task: A2ATaskRequest): Promise; + + /** Returns model-visible tools this agent is authorized to use. */ + protected getAuthorizedTools(): MCPletTool[] { + return this.deps.poolRegistry + .getToolsForAgent(this.agentId, this.accessiblePools) + .filter((t) => t.meta.visibility.includes('model')); + } + + /** Convert MCPletTools to LLM tool definitions. */ + protected toToolDefs(tools: MCPletTool[]): LLMToolDef[] { + return tools.map((t) => ({ + name: t.name, + description: t.description, + inputSchema: t.inputSchema, + })); + } + + /** + * Invoke a MCPlet tool with Pool access enforcement and action-type Passkey interception. + * Spec Section 4.2, 7.2 + */ + protected async invokeMCPlet( + toolName: string, + args: Record, + contextId?: string, + ): Promise { + const tool = this.deps.poolRegistry + .getAllTools() + .find((t) => t.name === toolName); + + if (!tool) { + return this.errorResult(toolName, `Tool "${toolName}" not found`); + } + + // Pool access enforcement + if (!this.deps.poolRegistry.canAgentAccess(this.agentId, tool.meta.pool, this.accessiblePools)) { + return this.errorResult(toolName, `Agent "${this.agentId}" is not authorized to access pool "${tool.meta.pool}"`, 'AUTH_REQUIRED'); + } + + // Rate limiting + if (tool.meta.pool && !this.deps.poolRegistry.checkRateLimit(tool.meta.pool)) { + return this.errorResult(toolName, `Rate limit exceeded for pool "${tool.meta.pool}"`, 'RATE_LIMITED'); + } + + // Action-type Passkey interception (Spec Section 7.2) + let callParams: Record = args; + if (tool.meta.mcpletType === 'action' && tool.meta.auth?.required === 'passkey') { + const assertion = await this.performPasskeyCeremony(tool); + if (!assertion) { + return this.errorResult(toolName, 'Passkey authentication cancelled or timed out', 'AUTH_FAILED'); + } + callParams = { ...args, _mcplet_auth: assertion }; + } + + // Audit log for action-type tools + if (tool.meta.mcpletType === 'action') { + this.deps.auditLog.record({ + type: 'action_invocation', + agentId: this.agentId, + toolName, + contextId, + timestamp: new Date().toISOString(), + }); + } + + try { + const result = await this.deps.mcpRouter.callTool(toolName, callParams); + const text = result.content.find((c) => c.type === 'text')?.text ?? '{}'; + return JSON.parse(text) as MCPletToolResult; + } catch (err) { + return this.errorResult(toolName, (err as Error).message); + } + } + + /** + * Agentic tool-use loop: send messages to LLM, execute tool calls, repeat. + * Returns when LLM stops with end_turn or produces no further tool calls. + */ + protected async runToolLoop( + messages: LLMMessage[], + tools: MCPletTool[], + contextId?: string, + ): Promise { + const history = [...messages]; + const toolDefs = this.toToolDefs(tools); + let iterations = 0; + const maxIterations = 10; + + while (iterations < maxIterations) { + iterations++; + const response = await this.deps.llm.chat(history, { tools: toolDefs }); + + if (response.text) { + history.push({ role: 'assistant', content: response.text }); + } + + if (!response.toolCalls || response.toolCalls.length === 0) { + return response.text ?? ''; + } + + // Execute all tool calls and append results + const toolResults = await this.executeToolCalls(response.toolCalls, contextId); + + // Append assistant tool-use message and tool results as user message + const toolCallsText = response.toolCalls + .map((tc) => `[tool_call: ${tc.toolName}(${JSON.stringify(tc.arguments)})]`) + .join('\n'); + history.push({ role: 'assistant', content: toolCallsText }); + + const resultsText = toolResults + .map((r) => `[tool_result: ${r.toolName}]\n${JSON.stringify(r.result, null, 2)}`) + .join('\n\n'); + history.push({ role: 'user', content: resultsText }); + + if (response.stopReason === 'end_turn') { + return response.text ?? ''; + } + } + + return '[max iterations reached]'; + } + + private async executeToolCalls( + toolCalls: LLMToolCall[], + contextId?: string, + ): Promise> { + const results = await Promise.all( + toolCalls.map(async (tc) => { + const result = await this.invokeMCPlet(tc.toolName, tc.arguments, contextId); + return { toolName: tc.toolName, result }; + }), + ); + return results; + } + + private async performPasskeyCeremony(tool: MCPletTool): Promise | null> { + if (!this.deps.passkeyServer) { + console.warn(`[base-agent] No PasskeyServer configured; skipping ceremony for "${tool.name}"`); + return null; + } + try { + const assertion = await this.deps.passkeyServer.startCeremony( + tool.meta.auth?.promptMessage ?? `Authorize action: ${tool.name}`, + ); + return assertion as unknown as Record; + } catch { + return null; + } + } + + protected buildSuccessResponse(task: A2ATaskRequest, result: unknown): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'success', + payload: { result }, + }; + } + + protected buildErrorResponse( + task: A2ATaskRequest, + message: string, + code?: string, + ): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'error', + payload: { error: { message, code } }, + }; + } + + protected buildCancelledResponse(task: A2ATaskRequest, reason: string): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'cancelled', + payload: { error: { message: reason } }, + }; + } + + private errorResult( + toolName: string, + message: string, + code = 'UNKNOWN_ERROR', + ): MCPletToolResult { + return { + error: { message, code: code as MCPletErrorCode }, + _meta: { + timestamp: new Date().toISOString(), + toolId: toolName, + mcpletType: 'read', + visibility: ['model'], + }, + }; + } +} diff --git a/platform_impl/src/agents/director-agent.ts b/platform_impl/src/agents/director-agent.ts new file mode 100644 index 0000000..c29c580 --- /dev/null +++ b/platform_impl/src/agents/director-agent.ts @@ -0,0 +1,206 @@ +import { randomUUID } from 'node:crypto'; +import cron from 'node-cron'; +import type { DirectorAgentConfig } from '../types/index.js'; +import type { LLMAdapter } from '../llm/llm-adapter.js'; +import type { A2ALocalBus } from '../a2a/local-bus.js'; +import type { AuditLog } from '../host/audit-log.js'; + +export class DirectorAgent { + private running = false; + private cronJob: cron.ScheduledTask | null = null; + + constructor( + private readonly config: DirectorAgentConfig, + private readonly llm: LLMAdapter, + private readonly localBus: A2ALocalBus, + private readonly auditLog: AuditLog, + ) {} + + start(): void { + if (this.cronJob) return; + + console.log(`[director] Scheduling with cron: "${this.config.schedule}"`); + this.cronJob = cron.schedule(this.config.schedule, () => { + void this.run(); + }); + } + + stop(): void { + this.cronJob?.stop(); + this.cronJob = null; + } + + /** Trigger immediately (for testing or manual runs). */ + async runNow(): Promise { + await this.run(); + } + + private async run(): Promise { + // Prevent concurrent execution (Spec Section 3.4) + if (this.running) { + console.log('[director] Previous cycle still active — skipping this trigger'); + return; + } + this.running = true; + const contextId = randomUUID(); + const startedAt = new Date().toISOString(); + + console.log(`[director] Cycle started (contextId=${contextId})`); + this.auditLog.record({ + type: 'director_cycle', + contextId, + timestamp: startedAt, + detail: 'started', + }); + + try { + const instruction = await this.generateInstruction(contextId); + if (!instruction) { + return; // LLM parse failure — already logged, skip dispatch + } + + await this.dispatch(instruction, contextId); + } finally { + this.running = false; + this.auditLog.record({ + type: 'director_cycle', + contextId, + timestamp: new Date().toISOString(), + detail: 'finished', + }); + console.log(`[director] Cycle finished (contextId=${contextId})`); + } + } + + private async generateInstruction(contextId: string): Promise { + const prompt = this.config.promptTemplate.replace( + '{date}', + new Date().toISOString().slice(0, 10), + ); + + let lastError: unknown; + for (let attempt = 1; attempt <= this.config.maxRetries; attempt++) { + try { + const response = await this.llm.chat([ + { + role: 'system', + content: + 'You are the Director Agent of MCPletA2A platform. Generate a structured task instruction based on the prompt.', + }, + { role: 'user', content: prompt }, + ]); + + const instruction = response.text?.trim(); + if (!instruction) { + console.warn( + `[director] LLM returned empty instruction (attempt ${attempt}/${this.config.maxRetries})`, + ); + lastError = new Error('Empty LLM response'); + } else { + return instruction; + } + } catch (err) { + lastError = err; + console.warn( + `[director] LLM call failed (attempt ${attempt}/${this.config.maxRetries}): ${(err as Error).message}`, + ); + } + + if (attempt < this.config.maxRetries) { + await sleep(this.config.backoffMs); + } + } + + // All retries exhausted — log and skip (Spec Section 3.4) + console.error( + `[director] Skipping cycle after ${this.config.maxRetries} failed attempts. Last error:`, + lastError, + ); + this.auditLog.record({ + type: 'director_cycle', + contextId, + timestamp: new Date().toISOString(), + detail: `skipped: ${(lastError as Error).message}`, + }); + return null; + } + + private async dispatch(instruction: string, contextId: string): Promise { + // Step 1: Info Gathering + const infoResponse = await this.localBus.sendTask({ + messageId: randomUUID(), + contextId, + senderId: 'director-agent', + recipientId: this.config.targetAgentId, + timestamp: new Date().toISOString(), + type: 'task_request', + payload: { + parameters: { instruction }, + history: [ + { role: 'system', content: 'Task dispatched by Director Agent.' }, + { role: 'user', content: instruction }, + ], + }, + }); + + if (infoResponse.status !== 'success') { + console.warn(`[director] Info-gathering failed: ${JSON.stringify(infoResponse.payload?.error)}`); + return; + } + + const infoResult = infoResponse.payload?.result as Record | undefined; + const analysis = infoResult?.['analysis'] as Record | undefined; + + if (analysis?.['actionRecommended']) { + // Step 2: Planning + console.log('[director] Action recommended — dispatching to planning-agent'); + } else { + console.log(`[director] No action recommended: ${JSON.stringify(analysis?.['summary'])}`); + return; + } + const planResponse = await this.localBus.sendTask({ + messageId: randomUUID(), + contextId, + senderId: 'director-agent', + recipientId: 'planning-agent', + timestamp: new Date().toISOString(), + type: 'task_request', + payload: { parameters: infoResult ?? {} }, + }); + + if (planResponse.status !== 'success') { + console.warn(`[director] Planning failed: ${JSON.stringify(planResponse.payload?.error)}`); + return; + } + + const planResult = planResponse.payload?.result as Record | undefined; + const nextAgent = planResult?.['nextAgent'] as string | undefined; + + if (nextAgent === 'dispatch-agent') { + // Step 3: Dispatch + console.log('[director] Dispatching campaign to dispatch-agent'); + } else { + console.log('[director] Planning complete — no dispatch requested'); + return; + } + const dispatchResponse = await this.localBus.sendTask({ + messageId: randomUUID(), + contextId, + senderId: 'director-agent', + recipientId: 'dispatch-agent', + timestamp: new Date().toISOString(), + type: 'task_request', + payload: { parameters: planResult ?? {} }, + }); + + if (dispatchResponse.status === 'success') { + console.log(`[director] Campaign dispatched: ${JSON.stringify(dispatchResponse.payload?.result)}`); + } else { + console.warn(`[director] Dispatch failed: ${JSON.stringify(dispatchResponse.payload?.error)}`); + } + } +} + +function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/platform_impl/src/config/loader.ts b/platform_impl/src/config/loader.ts new file mode 100644 index 0000000..0881634 --- /dev/null +++ b/platform_impl/src/config/loader.ts @@ -0,0 +1,49 @@ +import { readFileSync } from 'fs'; +import { load as yamlLoad } from 'js-yaml'; +import type { PlatformConfig } from '../types/index.js'; + +export function loadConfig(configPath: string): PlatformConfig { + const raw = readFileSync(configPath, 'utf-8'); + const parsed = yamlLoad(raw) as Record; + + // Resolve env var substitutions like ${VAR_NAME} + const resolved = resolveEnvVars(JSON.stringify(parsed)); + const config = JSON.parse(resolved) as PlatformConfig; + + validateConfig(config); + return config; +} + +function resolveEnvVars(json: string): string { + return json.replace(/\$\{([^}]+)\}/g, (_, varName: string) => { + const val = process.env[varName]; + if (val === undefined) { + console.warn(`[config] env var ${varName} is not set`); + return ''; + } + return val; + }); +} + +function validateConfig(config: PlatformConfig): void { + if (!config.llm?.provider) { + throw new Error('config: llm.provider is required'); + } + if (!config.llm?.model) { + throw new Error('config: llm.model is required'); + } + if (!config.pools || typeof config.pools !== 'object') { + config.pools = {}; + } + if (!config.agents || typeof config.agents !== 'object') { + config.agents = {}; + } + if (config.directorAgent) { + const d = config.directorAgent; + if (!d.schedule) throw new Error('config: directorAgent.schedule is required'); + if (!d.promptTemplate) throw new Error('config: directorAgent.promptTemplate is required'); + if (!d.targetAgentId) throw new Error('config: directorAgent.targetAgentId is required'); + d.maxRetries = d.maxRetries ?? 3; + d.backoffMs = d.backoffMs ?? 5000; + } +} diff --git a/platform_impl/src/dashboard/dashboard-server.ts b/platform_impl/src/dashboard/dashboard-server.ts new file mode 100644 index 0000000..f1f4652 --- /dev/null +++ b/platform_impl/src/dashboard/dashboard-server.ts @@ -0,0 +1,359 @@ +import http from 'node:http'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import type { PoolRegistry } from '../pools/pool-registry.js'; +import type { AuditLog } from '../host/audit-log.js'; +import type { A2ALocalBus } from '../a2a/local-bus.js'; +import type { DirectorAgent } from '../agents/director-agent.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +export class DashboardServer { + private server: http.Server | null = null; + + constructor( + private readonly poolRegistry: PoolRegistry, + private readonly auditLog: AuditLog, + private readonly localBus: A2ALocalBus, + private readonly directorAgent?: DirectorAgent, + ) {} + + start(port: number): void { + this.server = http.createServer((req, res) => { + this.handle(req, res); + }); + this.server.listen(port, () => { + console.log(`[dashboard] Listening on http://localhost:${port}`); + }); + } + + stop(): void { + this.server?.close(); + } + + private handle(req: http.IncomingMessage, res: http.ServerResponse): void { + const url = new URL(req.url ?? '/', `http://localhost`); + + if (url.pathname === '/api/tools') { + sendJson(res, 200, this.poolRegistry.getAllTools()); + return; + } + if (url.pathname === '/api/audit') { + const limit = Number.parseInt(url.searchParams.get('limit') ?? '50', 10); + sendJson(res, 200, this.auditLog.getRecent(limit)); + return; + } + if (url.pathname === '/api/agents') { + sendJson(res, 200, { agents: this.localBus.getRegisteredAgentIds() }); + return; + } + if (req.method === 'POST' && url.pathname === '/api/trigger/director') { + if (!this.directorAgent) { + sendJson(res, 404, { error: 'DirectorAgent is not configured' }); + return; + } + // Run in background — response returns immediately + void this.directorAgent.runNow(); + sendJson(res, 202, { message: 'Director cycle triggered. Watch /api/audit for progress.' }); + return; + } + if (url.pathname === '/favicon.ico') { + serveFavicon(res); + return; + } + if (url.pathname === '/' || url.pathname === '/index.html') { + serveDashboardPage(res); + return; + } + + res.writeHead(404); + res.end('Not found'); + } +} + +function sendJson(res: http.ServerResponse, status: number, body: unknown): void { + const payload = JSON.stringify(body, null, 2); + res.writeHead(status, { 'Content-Type': 'application/json' }); + res.end(payload); +} + +function serveFavicon(res: http.ServerResponse): void { + const icoPath = path.resolve(__dirname, '../../src/dashboard/favicon.ico'); + if (fs.existsSync(icoPath)) { + const data = fs.readFileSync(icoPath); + res.writeHead(200, { + 'Content-Type': 'image/x-icon', + 'Cache-Control': 'public, max-age=86400', + }); + res.end(data); + } else { + res.writeHead(404); + res.end(); + } +} + +function serveDashboardPage(res: http.ServerResponse): void { + const staticPath = path.resolve(__dirname, '../../public/dashboard/index.html'); + if (fs.existsSync(staticPath)) { + const html = fs.readFileSync(staticPath, 'utf-8'); + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end(html); + } else { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end(inlineDashboard()); + } +} + +function inlineDashboard(): string { + return ` + + + + + MCPletA2A Dashboard + + + + +
+ MCPlet logo +

MCPletA2A Dashboard

+
+
Auto-refresh 10s
+
+ +
+
+
+

Registered Agents

+
Loading...
+
+
+

Director Control

+
+ + +
+
+
+ +
+

Registered MCPlet Tools

+ + + +
NameTypePoolVisibilityAuth
+
+ +
+

Recent Audit Log

+
+ + + +
TimestampTypeAgentToolDetail
+
+
+
+ + + + + +`; +} diff --git a/platform_impl/src/dashboard/favicon.ico b/platform_impl/src/dashboard/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..73db886306812e8a6d4456bfdd699382a7967e16 GIT binary patch literal 71870 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 literal 0 HcmV?d00001 diff --git a/platform_impl/src/discovery/mcplet-discovery.ts b/platform_impl/src/discovery/mcplet-discovery.ts new file mode 100644 index 0000000..b79f243 --- /dev/null +++ b/platform_impl/src/discovery/mcplet-discovery.ts @@ -0,0 +1,101 @@ +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import type { MCPletTool, MCPletMeta } from '../types/index.js'; +import type { PoolRegistry } from '../pools/pool-registry.js'; + +type RawToolDef = { + name: string; + description?: string; + inputSchema?: Record; + _meta?: Record; +}; + +export class MCPletDiscovery { + constructor( + private readonly client: Client, + private readonly poolRegistry: PoolRegistry, + ) {} + + async discover(): Promise { + const response = await this.client.listTools(); + const tools = response.tools as RawToolDef[]; + + const accepted: MCPletTool[] = []; + + for (const raw of tools) { + const tool = this.validate(raw); + if (!tool) continue; + this.poolRegistry.registerTool(tool); + accepted.push(tool); + } + + console.log( + `[discovery] Registered ${accepted.length} MCPlet tools (rejected ${tools.length - accepted.length})`, + ); + return accepted; + } + + /** Re-discover on list_changed notification */ + async refresh(): Promise { + const response = await this.client.listTools(); + const incoming = response.tools as RawToolDef[]; + const incomingNames = new Set(incoming.map((t) => t.name)); + + // Evict removed tools + const current = this.poolRegistry.getAllTools(); + for (const existing of current) { + if (!incomingNames.has(existing.name)) { + this.poolRegistry.evictTool(existing.name); + console.log(`[discovery] Evicted tool "${existing.name}" (removed from server)`); + } + } + + // Validate and update/add + for (const raw of incoming) { + const tool = this.validate(raw); + if (!tool) continue; + this.poolRegistry.updateTool(tool); + } + } + + private validate(raw: RawToolDef): MCPletTool | null { + const meta = raw._meta as Partial | undefined; + + // Reject: no mcpletType + if (!meta?.mcpletType) { + console.warn(`[discovery] Rejected "${raw.name}": missing _meta.mcpletType`); + return null; + } + + // Reject: invalid mcpletType + if (!['read', 'prepare', 'action'].includes(meta.mcpletType)) { + console.warn(`[discovery] Rejected "${raw.name}": unknown mcpletType "${meta.mcpletType}"`); + return null; + } + + // Reject: action + model-visible + no auth + const visibility = meta.visibility ?? []; + if ( + meta.mcpletType === 'action' && + visibility.includes('model') && + !meta.auth + ) { + console.warn( + `[discovery] Rejected "${raw.name}": action tool is model-visible without auth`, + ); + return null; + } + + return { + name: raw.name, + description: raw.description ?? '', + inputSchema: raw.inputSchema ?? { type: 'object', properties: {} }, + meta: { + mcpletType: meta.mcpletType, + pool: meta.pool, + visibility: visibility as MCPletMeta['visibility'], + mcpletToolResultSchemaUri: meta.mcpletToolResultSchemaUri, + auth: meta.auth, + }, + }; + } +} diff --git a/platform_impl/src/host/audit-log.ts b/platform_impl/src/host/audit-log.ts new file mode 100644 index 0000000..80366e7 --- /dev/null +++ b/platform_impl/src/host/audit-log.ts @@ -0,0 +1,34 @@ +// In-memory audit log for action-type tool invocations and Director Agent cycles + +export interface AuditEntry { + type: 'action_invocation' | 'director_cycle' | 'external_agent_request'; + agentId?: string; + toolName?: string; + contextId?: string; + timestamp: string; + detail?: string; +} + +export class AuditLog { + private readonly entries: AuditEntry[] = []; + private readonly maxEntries: number; + + constructor(maxEntries = 1000) { + this.maxEntries = maxEntries; + } + + record(entry: AuditEntry): void { + this.entries.push(entry); + if (this.entries.length > this.maxEntries) { + this.entries.shift(); + } + } + + getRecent(limit = 50): AuditEntry[] { + return this.entries.slice(-limit); + } + + getAll(): AuditEntry[] { + return [...this.entries]; + } +} diff --git a/platform_impl/src/host/mcplet-host.ts b/platform_impl/src/host/mcplet-host.ts new file mode 100644 index 0000000..399c094 --- /dev/null +++ b/platform_impl/src/host/mcplet-host.ts @@ -0,0 +1,168 @@ +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; +import type { PlatformConfig, AgentConfig, MCPletServerConfig } from '../types/index.js'; +import { PoolRegistry } from '../pools/pool-registry.js'; +import { MCPletDiscovery } from '../discovery/mcplet-discovery.js'; +import { MCPletRouter } from './mcplet-router.js'; +import { createLLMAdapter } from '../llm/claude-adapter.js'; +import type { LLMAdapter } from '../llm/llm-adapter.js'; +import { A2ALocalBus, type IAgent } from '../a2a/local-bus.js'; +import { A2AExternalEndpoint } from '../a2a/external-endpoint.js'; +import { PasskeyServer, PasskeyAPIServer, PasskeyPlatformService } from '../passkey/index.js'; +import { DashboardServer } from '../dashboard/dashboard-server.js'; +import { DirectorAgent } from '../agents/director-agent.js'; +import { AuditLog } from './audit-log.js'; +import type { AgentDeps } from '../agents/base-agent.js'; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type AgentConstructor = new (agentId: string, accessiblePools: string[], deps: any) => IAgent; + +const agentClassRegistry = new Map(); + +export function registerAgentClass(className: string, ctor: AgentConstructor): void { + agentClassRegistry.set(className, ctor); +} + +export class MCPletHost { + private poolRegistry!: PoolRegistry; + private mcpRouter!: MCPletRouter; + private llm!: LLMAdapter; + private localBus!: A2ALocalBus; + private auditLog!: AuditLog; + private passkeyServer?: PasskeyServer; + private passkeyPlatformService?: PasskeyPlatformService; + private passkeyAPIServer?: PasskeyAPIServer; + private dashboardServer?: DashboardServer; + private externalEndpoint?: A2AExternalEndpoint; + private directorAgent?: DirectorAgent; + + async start(config: PlatformConfig): Promise { + console.log('[host] Starting MCPletA2A Host...'); + + this.auditLog = new AuditLog(); + this.poolRegistry = new PoolRegistry(config.pools); + this.mcpRouter = new MCPletRouter(); + this.llm = createLLMAdapter(config.llm); + this.localBus = new A2ALocalBus(); + + // Initialize Passkey services if configured + if (config.passkey) { + const rpId = config.passkey.rpId || 'localhost'; + const origin = config.passkey.mode === 'https' + ? `https://${rpId}` + : 'http://127.0.0.1'; + + // Create Passkey Platform Service + this.passkeyPlatformService = new PasskeyPlatformService(rpId, origin); + console.log(`[host] PasskeyPlatformService initialized (mode: ${config.passkey.mode})`); + + // Create and start Passkey API Server + this.passkeyAPIServer = new PasskeyAPIServer( + this.passkeyPlatformService, + rpId, + origin, + ); + const apiPort = config.passkey.apiPort || 8443; + this.passkeyAPIServer.start(apiPort); + + // For backward compatibility, also create PasskeyServer for interactive ceremonies + this.passkeyServer = new PasskeyServer(rpId, origin); + } + + // Connect MCPlet servers declared in config (each is a stdio child process) + if (config.mcpletServers?.length) { + await this.connectMCPletServers(config.mcpletServers); + } + + const agentDeps: AgentDeps = { + poolRegistry: this.poolRegistry, + mcpRouter: this.mcpRouter, + llm: this.llm, + passkeyServer: this.passkeyServer, + passkeyPlatformService: this.passkeyPlatformService, + auditLog: this.auditLog, + }; + + for (const [agentId, agentConfig] of Object.entries(config.agents)) { + const agent = this.instantiateAgent(agentId, agentConfig, agentDeps); + if (agent) this.localBus.register(agent); + } + + if (config.directorAgent) { + this.directorAgent = new DirectorAgent( + config.directorAgent, this.llm, this.localBus, this.auditLog, + ); + this.directorAgent.start(); + console.log('[host] DirectorAgent scheduled:', config.directorAgent.schedule); + } + + if (config.dashboard) { + this.dashboardServer = new DashboardServer( + this.poolRegistry, this.auditLog, this.localBus, this.directorAgent, + ); + this.dashboardServer.start(config.dashboard.port); + } + + if (config.a2aExternalEndpoint) { + this.externalEndpoint = new A2AExternalEndpoint( + config, this.localBus, this.poolRegistry, this.auditLog, + ); + this.externalEndpoint.start(config.a2aExternalEndpoint.port); + } + + console.log( + `[host] MCPletA2A Host started. Tools: ${this.mcpRouter.registeredTools().length}, ` + + `Agents: ${this.localBus.getRegisteredAgentIds().length}`, + ); + } + + /** Connect a single MCPlet server and register its tools in the router. */ + async connectMCPServer( + command: string, + args: string[], + env?: Record, + ): Promise { + const transport = new StdioClientTransport({ command, args, env }); + const client = new Client({ name: 'mcplet-host', version: '0.1.0' }); + await client.connect(transport); + + const discovery = new MCPletDiscovery(client, this.poolRegistry); + const tools = await discovery.discover(); + + for (const tool of tools) { + this.mcpRouter.registerTool(tool.name, client); + } + } + + stop(): void { + this.directorAgent?.stop(); + this.dashboardServer?.stop(); + this.passkeyAPIServer?.stop(); + this.externalEndpoint?.stop(); + console.log('[host] MCPletA2A Host stopped.'); + } + + private async connectMCPletServers(servers: MCPletServerConfig[]): Promise { + for (const srv of servers) { + try { + console.log(`[host] Connecting MCPlet server: ${srv.name} (${srv.command} ${srv.args.join(' ')})`); + await this.connectMCPServer(srv.command, srv.args, srv.env); + } catch (err) { + console.error(`[host] Failed to connect "${srv.name}": ${(err as Error).message}`); + } + } + } + + private instantiateAgent( + agentId: string, + agentConfig: AgentConfig, + deps: AgentDeps, + ): IAgent | null { + const Ctor = agentClassRegistry.get(agentConfig.class); + if (!Ctor) { + console.warn(`[host] Agent class "${agentConfig.class}" not registered — skipping "${agentId}"`); + return null; + } + return new Ctor(agentId, agentConfig.accessiblePools, deps); + } +} diff --git a/platform_impl/src/host/mcplet-router.ts b/platform_impl/src/host/mcplet-router.ts new file mode 100644 index 0000000..75f88dd --- /dev/null +++ b/platform_impl/src/host/mcplet-router.ts @@ -0,0 +1,39 @@ +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; + +/** + * Routes tool/call requests to the correct MCP Client. + * Each MCPlet server is a separate Client; this class maps + * tool name → owning client so BaseAgent can call any tool + * without knowing which server hosts it. + */ +export class MCPletRouter { + private readonly clientByTool = new Map(); + + registerTool(toolName: string, client: Client): void { + this.clientByTool.set(toolName, client); + } + + async callTool( + toolName: string, + args: Record, + ): Promise<{ content: Array<{ type: string; text?: string }> }> { + const client = this.clientByTool.get(toolName); + if (!client) { + throw new Error(`[router] No MCPlet client registered for tool "${toolName}"`); + } + + // Extract _mcplet_auth from arguments and forward via _meta (Spec Section 7.3.1) + const { _mcplet_auth, ...cleanArgs } = args; + const meta = _mcplet_auth === undefined + ? undefined + : { mcplet_auth: _mcplet_auth as Record }; + + return client.callTool({ name: toolName, arguments: cleanArgs, _meta: meta }) as Promise<{ + content: Array<{ type: string; text?: string }>; + }>; + } + + registeredTools(): string[] { + return [...this.clientByTool.keys()]; + } +} diff --git a/platform_impl/src/index.ts b/platform_impl/src/index.ts new file mode 100644 index 0000000..8c9ac43 --- /dev/null +++ b/platform_impl/src/index.ts @@ -0,0 +1,44 @@ +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { loadConfig } from './config/loader.js'; +import { MCPletHost, registerAgentClass, type AgentConstructor } from './host/mcplet-host.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +const configPath = + process.env.MCPLET_CONFIG ?? + path.resolve(__dirname, '../config/platform.yaml'); + +// Optional: load agent classes from an external module. +// Set MCPLET_AGENT_MODULE to the file:// URL of a JS module that exports +// AGENT_CLASSES: Record +const agentModulePath = process.env.MCPLET_AGENT_MODULE; +if (agentModulePath) { + console.log(`[host] Loading agent module: ${agentModulePath}`); + const mod = await import(agentModulePath) as { + AGENT_CLASSES?: Record; + }; + if (mod.AGENT_CLASSES) { + for (const [name, ctor] of Object.entries(mod.AGENT_CLASSES)) { + registerAgentClass(name, ctor); + console.log(`[host] Registered agent class: ${name}`); + } + } else { + console.warn(`[host] MCPLET_AGENT_MODULE loaded but exports no AGENT_CLASSES`); + } +} + +const config = loadConfig(configPath); +const host = new MCPletHost(); + +await host.start(config); + +// Graceful shutdown +process.on('SIGINT', () => { + host.stop(); + process.exit(0); +}); +process.on('SIGTERM', () => { + host.stop(); + process.exit(0); +}); diff --git a/platform_impl/src/llm/claude-adapter.ts b/platform_impl/src/llm/claude-adapter.ts new file mode 100644 index 0000000..9813c75 --- /dev/null +++ b/platform_impl/src/llm/claude-adapter.ts @@ -0,0 +1,83 @@ +import Anthropic from '@anthropic-ai/sdk'; +import type { + LLMAdapter, + LLMMessage, + LLMToolDef, + LLMResponse, + LLMToolCall, +} from './llm-adapter.js'; +import type { LLMConfig } from '../types/index.js'; +import { OpenRouterAdapter } from './openrouter-adapter.js'; + +export class ClaudeAdapter implements LLMAdapter { + private readonly client: Anthropic; + private readonly model: string; + + constructor(config: LLMConfig) { + this.client = new Anthropic({ + apiKey: config.apiKey ?? process.env.ANTHROPIC_API_KEY, + }); + this.model = config.model; + } + + async chat( + messages: LLMMessage[], + options?: { tools?: LLMToolDef[]; maxTokens?: number }, + ): Promise { + const systemMessages = messages.filter((m) => m.role === 'system'); + const conversationMessages = messages.filter((m) => m.role !== 'system'); + + const system = systemMessages.map((m) => m.content).join('\n\n'); + + const anthropicMessages: Anthropic.MessageParam[] = conversationMessages.map((m) => ({ + role: m.role as 'user' | 'assistant', + content: m.content, + })); + + const tools: Anthropic.Tool[] | undefined = options?.tools?.map((t) => ({ + name: t.name, + description: t.description, + input_schema: t.inputSchema as Anthropic.Tool['input_schema'], + })); + + const response = await this.client.messages.create({ + model: this.model, + max_tokens: options?.maxTokens ?? 4096, + system: system || undefined, + messages: anthropicMessages, + tools: tools?.length ? tools : undefined, + }); + + const toolCalls: LLMToolCall[] = []; + let text: string | undefined; + + for (const block of response.content) { + if (block.type === 'text') { + text = (text ?? '') + block.text; + } else if (block.type === 'tool_use') { + toolCalls.push({ + id: block.id, + toolName: block.name, + arguments: block.input as Record, + }); + } + } + + return { + text, + toolCalls: toolCalls.length > 0 ? toolCalls : undefined, + stopReason: response.stop_reason ?? 'end_turn', + }; + } +} + +export function createLLMAdapter(config: LLMConfig): LLMAdapter { + switch (config.provider) { + case 'claude': + return new ClaudeAdapter(config); + case 'openrouter': + return new OpenRouterAdapter(config); + default: + throw new Error(`Unsupported LLM provider: "${config.provider}"`); + } +} diff --git a/platform_impl/src/llm/llm-adapter.ts b/platform_impl/src/llm/llm-adapter.ts new file mode 100644 index 0000000..5e912ad --- /dev/null +++ b/platform_impl/src/llm/llm-adapter.ts @@ -0,0 +1,39 @@ +// LLM Adapter abstraction — Host is LLM-agnostic (Spec Section 2.5) + +export interface LLMMessage { + role: 'system' | 'user' | 'assistant'; + content: string; +} + +export interface LLMToolDef { + name: string; + description: string; + inputSchema: Record; +} + +export interface LLMToolCall { + id: string; + toolName: string; + arguments: Record; +} + +export interface LLMToolResult { + toolCallId: string; + content: string; +} + +export interface LLMResponse { + text?: string; + toolCalls?: LLMToolCall[]; + stopReason: 'end_turn' | 'tool_use' | 'max_tokens' | string; +} + +export interface LLMAdapter { + chat( + messages: LLMMessage[], + options?: { + tools?: LLMToolDef[]; + maxTokens?: number; + }, + ): Promise; +} diff --git a/platform_impl/src/llm/openrouter-adapter.ts b/platform_impl/src/llm/openrouter-adapter.ts new file mode 100644 index 0000000..6192932 --- /dev/null +++ b/platform_impl/src/llm/openrouter-adapter.ts @@ -0,0 +1,85 @@ +import OpenAI from 'openai'; +import type { + LLMAdapter, + LLMMessage, + LLMToolDef, + LLMResponse, + LLMToolCall, +} from './llm-adapter.js'; +import type { LLMConfig } from '../types/index.js'; + +const DEFAULT_BASE_URL = 'https://openrouter.ai/api/v1'; + +export class OpenRouterAdapter implements LLMAdapter { + private readonly client: OpenAI; + private readonly model: string; + + constructor(config: LLMConfig) { + const extraHeaders: Record = {}; + if (config.siteUrl) extraHeaders['HTTP-Referer'] = config.siteUrl; + if (config.siteName) extraHeaders['X-Title'] = config.siteName; + + this.client = new OpenAI({ + apiKey: config.apiKey ?? process.env.OPENROUTER_API_KEY, + baseURL: config.baseURL ?? DEFAULT_BASE_URL, + defaultHeaders: extraHeaders, + }); + this.model = config.model; + } + + async chat( + messages: LLMMessage[], + options?: { tools?: LLMToolDef[]; maxTokens?: number }, + ): Promise { + const openAIMessages: OpenAI.Chat.ChatCompletionMessageParam[] = messages.map((m) => ({ + role: m.role as 'system' | 'user' | 'assistant', + content: m.content, + })); + + const tools: OpenAI.Chat.ChatCompletionTool[] | undefined = options?.tools?.map((t) => ({ + type: 'function' as const, + function: { + name: t.name, + description: t.description, + parameters: t.inputSchema as Record, + }, + })); + + const response = await this.client.chat.completions.create({ + model: this.model, + max_tokens: options?.maxTokens ?? 4096, + messages: openAIMessages, + tools: tools?.length ? tools : undefined, + tool_choice: tools?.length ? 'auto' : undefined, + }); + + const choice = response.choices[0]; + const message = choice.message; + + const toolCalls: LLMToolCall[] = []; + if (message.tool_calls) { + for (const tc of message.tool_calls) { + if (tc.type !== 'function') continue; + let args: Record; + try { + args = JSON.parse(tc.function.arguments) as Record; + } catch { + args = {}; + } + toolCalls.push({ + id: tc.id, + toolName: tc.function.name, + arguments: args, + }); + } + } + + const stopReason = choice.finish_reason ?? 'stop'; + + return { + text: message.content ?? undefined, + toolCalls: toolCalls.length > 0 ? toolCalls : undefined, + stopReason, + }; + } +} diff --git a/platform_impl/src/passkey/api-server.ts b/platform_impl/src/passkey/api-server.ts new file mode 100644 index 0000000..b47d2d2 --- /dev/null +++ b/platform_impl/src/passkey/api-server.ts @@ -0,0 +1,168 @@ +/** + * Passkey REST API Endpoints — Spec Section 3.7, 16.3 + * + * Provides REST endpoints for: + * - POST /api/passkey/register/begin — Start registration + * - POST /api/passkey/register/complete — Finish registration + * - POST /api/passkey/authenticate/begin — Start authentication + * - POST /api/passkey/authenticate/complete — Finish authentication + */ + +import http from 'node:http'; +import type { PasskeyPlatformService } from './platform-service.js'; + +export class PasskeyAPIServer { + private server: http.Server | null = null; + + constructor( + private readonly platformService: PasskeyPlatformService, + private readonly rpId: string, + private readonly origin: string, + ) {} + + start(port: number): void { + this.server = http.createServer((req, res) => { + void this.handleRequest(req, res); + }); + + this.server.listen(port, '127.0.0.1', () => { + console.log(`[passkey-api] Server listening on http://127.0.0.1:${port}`); + }); + } + + stop(): void { + this.server?.close(); + } + + private async handleRequest(req: http.IncomingMessage, res: http.ServerResponse): Promise { + const url = new URL(req.url ?? '/', 'http://localhost'); + + // CORS headers + res.setHeader('Access-Control-Allow-Origin', this.origin); + res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); + + if (req.method === 'OPTIONS') { + res.writeHead(200); + res.end(); + return; + } + + if (req.method !== 'POST') { + sendJson(res, 405, { error: 'Method Not Allowed' }); + return; + } + + try { + const body = await parseJsonBody(req) as Record; + + if (url.pathname === '/api/passkey/register/begin') { + await this.handleRegisterBegin(res, body); + } else if (url.pathname === '/api/passkey/register/complete') { + await this.handleRegisterComplete(res, body); + } else if (url.pathname === '/api/passkey/authenticate/begin') { + await this.handleAuthenticateBegin(res, body); + } else if (url.pathname === '/api/passkey/authenticate/complete') { + await this.handleAuthenticateComplete(res, body); + } else { + sendJson(res, 404, { error: 'Not Found' }); + } + } catch (err) { + sendJson(res, 400, { error: (err as Error).message }); + } + } + + private async handleRegisterBegin( + res: http.ServerResponse, + body: Record, + ): Promise { + const userId = body.userId as string; + const displayName = body.displayName as string || userId; + + if (!userId) { + sendJson(res, 400, { error: 'userId is required' }); + return; + } + + const result = await this.platformService.startRegistration(userId, displayName); + sendJson(res, result.success ? 200 : 400, result); + } + + private async handleRegisterComplete( + res: http.ServerResponse, + body: Record, + ): Promise { + const userId = body.userId as string; + const challengeB64 = body.challenge as string; + const attestationResponse = body.attestationResponse as Record; + + if (!userId || !challengeB64 || !attestationResponse) { + sendJson(res, 400, { error: 'Missing required fields' }); + return; + } + + const result = await this.platformService.completeRegistration( + userId, + challengeB64, + attestationResponse as any, + this.rpId, + this.origin, + ); + + sendJson(res, result.success ? 200 : 400, result); + } + + private async handleAuthenticateBegin( + res: http.ServerResponse, + body: Record, + ): Promise { + const userId = body.userId as string | undefined; + + const result = await this.platformService.startAuthentication(userId); + sendJson(res, result.success ? 200 : 400, result); + } + + private async handleAuthenticateComplete( + res: http.ServerResponse, + body: Record, + ): Promise { + const credentialId = body.credentialId as string; + const challengeB64 = body.challenge as string; + const assertionResponse = body.assertionResponse as Record; + + if (!credentialId || !challengeB64 || !assertionResponse) { + sendJson(res, 400, { error: 'Missing required fields' }); + return; + } + + const result = await this.platformService.completeAuthentication( + credentialId, + challengeB64, + assertionResponse as any, + this.rpId, + this.origin, + ); + + sendJson(res, result.success ? 200 : 400, result); + } +} + +function sendJson(res: http.ServerResponse, status: number, body: unknown): void { + res.writeHead(status, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(body)); +} + +function parseJsonBody(req: http.IncomingMessage): Promise { + return new Promise((resolve, reject) => { + let data = ''; + req.on('data', (chunk: Buffer) => { data += chunk.toString(); }); + req.on('end', () => { + try { + resolve(JSON.parse(data)); + } catch { + reject(new Error('Invalid JSON')); + } + }); + req.on('error', reject); + }); +} diff --git a/platform_impl/src/passkey/challenge-manager.ts b/platform_impl/src/passkey/challenge-manager.ts new file mode 100644 index 0000000..94a7165 --- /dev/null +++ b/platform_impl/src/passkey/challenge-manager.ts @@ -0,0 +1,126 @@ +/** + * Passkey Challenge Manager — FIDO2 Challenge Generation and Verification + * Spec Section 3.7, 8 + */ + +import { randomBytes } from 'node:crypto'; + +export interface PasskeyChallenge { + challengeB64: string; // base64-encoded challenge + userId: string; // for whom this challenge is issued + ceremony: 'registration' | 'authentication'; + issuedAt: number; // Unix timestamp (ms) + expiresAt: number; // Unix timestamp (ms) + rpId: string; // Relying Party ID + origin: string; // Expected origin for verification + used: boolean; // flagged after use (prevents replay) +} + +/** + * In-Memory Challenge Manager + * Generates, stores, and validates FIDO2 challenges + */ +export class PasskeyChallengeManager { + private challenges = new Map(); + private readonly challengeTimeoutMs: number; + private readonly cleanupIntervalMs: number; + + constructor( + private rpId: string, + private origin: string, + challengeTimeoutMs = 10 * 60 * 1000, // 10 minutes + cleanupIntervalMs = 5 * 60 * 1000, // 5 minutes + ) { + this.challengeTimeoutMs = challengeTimeoutMs; + this.cleanupIntervalMs = cleanupIntervalMs; + + // Periodically cleanup expired challenges + setInterval(() => { this.cleanupExpired(); }, this.cleanupIntervalMs); + } + + /** + * Generate a new challenge for registration or authentication + */ + generateChallenge( + userId: string, + ceremony: 'registration' | 'authentication', + ): string { + const challengeBytes = randomBytes(32); + const challengeB64 = challengeBytes.toString('base64'); + const now = Date.now(); + + const challenge: PasskeyChallenge = { + challengeB64, + userId, + ceremony, + issuedAt: now, + expiresAt: now + this.challengeTimeoutMs, + rpId: this.rpId, + origin: this.origin, + used: false, + }; + + this.challenges.set(challengeB64, challenge); + return challengeB64; + } + + /** + * Retr and validate a challenge + */ + validateChallenge( + challengeB64: string, + userId: string, + ceremony: 'registration' | 'authentication', + ): PasskeyChallenge | null { + const challenge = this.challenges.get(challengeB64); + if (!challenge) return null; + + // Check expiration + if (Date.now() > challenge.expiresAt) { + this.challenges.delete(challengeB64); + return null; + } + + // Check user and ceremony match + if (challenge.userId !== userId || challenge.ceremony !== ceremony) { + return null; + } + + // Prevent replay: mark as used + if (challenge.used) { + return null; + } + + challenge.used = true; + return challenge; + } + + /** + * Get a challenge without marking it as used (for inspection only) + */ + inspectChallenge(challengeB64: string): PasskeyChallenge | null { + return this.challenges.get(challengeB64) ?? null; + } + + /** + * Clean up expired challenges + */ + private cleanupExpired(): void { + const now = Date.now(); + const toDelete: string[] = []; + + for (const [key, challenge] of this.challenges.entries()) { + if (now > challenge.expiresAt) { + toDelete.push(key); + } + } + + for (const key of toDelete) { + this.challenges.delete(key); + } + + if (toDelete.length > 0) { + console.log(`[passkey-challenges] Cleaned up ${toDelete.length} expired challenges`); + } + } +} diff --git a/platform_impl/src/passkey/client.ts b/platform_impl/src/passkey/client.ts new file mode 100644 index 0000000..7a64f5c --- /dev/null +++ b/platform_impl/src/passkey/client.ts @@ -0,0 +1,233 @@ +/** + * Passkey Client Helper for MCPlet Applications + * Provides high-level API for Passkey authentication in browser + * + * Compatible with: reference_impl_restaurant_reservations/mcpapps/mcp-client/src/passkey.ts + */ + +export interface PasskeyAuthResult { + success: boolean; + userId?: string; + credentialId?: string; + error?: string; +} + +export interface PasskeyRegistrationResult { + success: boolean; + credentialId?: string; + error?: string; +} + +/** + * Passkey Client - Browser-based authentication helper + * Handles WebAuthn ceremony coordination with server + */ +export class PasskeyClient { + constructor( + private serverUrl: string = 'http://127.0.0.1:8080', + ) {} + + /** + * Check if WebAuthn is available in this browser + */ + isSupported(): boolean { + return typeof window !== 'undefined' && + typeof window.PublicKeyCredential !== 'undefined'; + } + + /** + * Start registration ceremony: generate credential on this device + */ + async startRegistration(userId: string, displayName?: string): Promise { + try { + // 1. Request registration challenge from server + const beginResp = await fetch(`${this.serverUrl}/api/passkey/register/begin`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ userId, displayName }), + }); + + if (!beginResp.ok) { + return { success: false, error: 'Failed to begin registration' }; + } + + const beginData = await beginResp.json() as { challenge?: string; error?: string }; + if (!beginData.challenge) { + return { success: false, error: beginData.error || 'No challenge received' }; + } + + // 2. Call navigator.credentials.create() with challenge + const attestation = await navigator.credentials.create({ + publicKey: { + challenge: this.base64ToBuffer(beginData.challenge), + rp: { id: 'localhost', name: 'MCPlet' }, + user: { + id: this.stringToBuffer(userId) as ArrayBuffer, + name: userId, + displayName: displayName || userId, + }, + pubKeyCredParams: [{ alg: -7, type: 'public-key' }] as any, + timeout: 60_000, + attestation: 'none' as const, + } as any, + }); + + if (!attestation) { + return { success: false, error: 'Registration cancelled by user' }; + } + + const pubKeyAttestion = attestation as PublicKeyCredential; + + // 3. Send attestation response to server + const completeResp = await fetch(`${this.serverUrl}/api/passkey/register/complete`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + userId, + challenge: beginData.challenge, + attestationResponse: { + id: this.bufferToBase64(pubKeyAttestion.id as any), + type: pubKeyAttestion.type, + rawId: this.bufferToBase64(pubKeyAttestion.rawId), + response: { + clientDataJSON: this.bufferToBase64( + (pubKeyAttestion.response as AuthenticatorAttestationResponse).clientDataJSON + ), + attestationObject: this.bufferToBase64( + (pubKeyAttestion.response as AuthenticatorAttestationResponse).attestationObject + ), + }, + }, + }), + }); + + if (!completeResp.ok) { + return { success: false, error: 'Failed to complete registration' }; + } + + const completeData = await completeResp.json() as PasskeyRegistrationResult; + return completeData; + } catch (err) { + return { success: false, error: (err as Error).message }; + } + } + + /** + * Start authentication ceremony: use existing credential to authenticate + */ + async startAuthentication(userId?: string): Promise { + try { + // 1. Request authentication challenge from server + const beginResp = await fetch(`${this.serverUrl}/api/passkey/authenticate/begin`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(userId ? { userId } : {}), + }); + + if (!beginResp.ok) { + return { success: false, error: 'Failed to begin authentication' }; + } + + const beginData = await beginResp.json() as { + challenge?: string; + allowCredentials?: Array<{ id: string; type: string }>; + error?: string; + }; + + if (!beginData.challenge) { + return { success: false, error: beginData.error || 'No challenge received' }; + } + + // 2. Call navigator.credentials.get() with challenge + const assertion = await navigator.credentials.get({ + publicKey: { + challenge: this.base64ToBuffer(beginData.challenge), + rpId: 'localhost', + allowCredentials: (beginData.allowCredentials || []).map(cred => ({ + id: this.base64ToBuffer(cred.id) as ArrayBuffer, + type: cred.type as 'public-key', + })), + userVerification: 'preferred' as const, + timeout: 60_000, + } as any, + }); + + if (!assertion) { + return { success: false, error: 'Authentication cancelled by user' }; + } + + const authAssertion = assertion as PublicKeyCredential; + + // 3. Send assertion response to server + const completeResp = await fetch(`${this.serverUrl}/api/passkey/authenticate/complete`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + credentialId: this.bufferToBase64(authAssertion.id as any), + challenge: beginData.challenge, + assertionResponse: { + id: this.bufferToBase64(authAssertion.id as any), + type: authAssertion.type, + rawId: this.bufferToBase64(authAssertion.rawId), + response: { + clientDataJSON: this.bufferToBase64( + (authAssertion.response as AuthenticatorAssertionResponse).clientDataJSON + ), + authenticatorData: this.bufferToBase64( + (authAssertion.response as AuthenticatorAssertionResponse).authenticatorData + ), + signature: this.bufferToBase64( + (authAssertion.response as AuthenticatorAssertionResponse).signature + ), + userHandle: (authAssertion.response as AuthenticatorAssertionResponse).userHandle + ? this.bufferToBase64((authAssertion.response as AuthenticatorAssertionResponse).userHandle!) + : undefined, + }, + }, + }), + }); + + if (!completeResp.ok) { + return { success: false, error: 'Failed to complete authentication' }; + } + + const completeData = await completeResp.json() as PasskeyAuthResult; + return completeData; + } catch (err) { + return { success: false, error: (err as Error).message }; + } + } + + // Helper methods for buffer <-> base64 conversion + private bufferToBase64(buffer: ArrayBuffer | ArrayBufferView | BufferSource): string { + let bytes: Uint8Array; + if (buffer instanceof ArrayBuffer) { + bytes = new Uint8Array(buffer); + } else if (ArrayBuffer.isView(buffer)) { + bytes = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength); + } else { + bytes = new Uint8Array(buffer as any); + } + let binary = ''; + for (let i = 0; i < bytes.byteLength; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); + } + + private base64ToBuffer(b64: string): ArrayBuffer { + const binary = atob(b64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes.buffer; + } + + private stringToBuffer(str: string): ArrayBuffer { + const encoder = new TextEncoder(); + return encoder.encode(str).buffer; + } +} + +export default PasskeyClient; diff --git a/platform_impl/src/passkey/fido2-backend.ts b/platform_impl/src/passkey/fido2-backend.ts new file mode 100644 index 0000000..6d8ef30 --- /dev/null +++ b/platform_impl/src/passkey/fido2-backend.ts @@ -0,0 +1,268 @@ +/** + * Passkey FIDO2 Backend — Server-Side Authentication Logic + * Spec Section 3.7, 8.3 + * + * This module handles: + * - WebAuthn attestation verification (registration) + * - WebAuthn assertion verification (authentication) + * - Signature validation + * + * For production, consider using a library like @simplewebauthn/server, + * which handles all FIDO2 spec details and edge cases. + */ + +import { createHash } from 'node:crypto'; + +export interface RegistrationOptions { + challenge: string; // base64-encoded challenge + rp: { id: string; name: string }; + user: { id: string; name: string; displayName: string }; + pubKeyCredParams: Array<{ alg: number; type: string }>; + timeout: number; + attestation: 'direct' | 'indirect' | 'none'; +} + +export interface AuthenticationOptions { + challenge: string; // base64-encoded challenge + rpId: string; + userVerification: 'required' | 'preferred' | 'discouraged'; + timeout: number; +} + +export interface AttestationResponse { + id: string; // base64-encoded credential ID + type: string; // e.g., "public-key" + rawId: string; // base64-encoded raw credential ID + response: { + clientDataJSON: string; // base64-encoded + attestationObject: string; // base64-encoded + }; +} + +export interface AssertionResponse { + id: string; // base64-encoded credential ID + type: string; + rawId: string; + response: { + clientDataJSON: string; // base64-encoded + authenticatorData: string; // base64-encoded + signature: string; // base64-encoded + userHandle?: string; // base64-encoded, optional + }; +} + +/** + * FIDO2 Attestation Verification Result + */ +export interface AttestationVerificationResult { + success: boolean; + credentialId: string; // base64-encoded credential ID + publicKey: string; // base64-encoded public key + counter: number; + transports?: string[]; + error?: string; +} + +/** + * FIDO2 Assertion Verification Result + */ +export interface AssertionVerificationResult { + success: boolean; + userId: string; + counter: number; + error?: string; +} + +/** + * Simple FIDO2 Backend Implementation + * + * IMPORTANT: This is a demo implementation with simplified verification. + * For production use: + * - Use @simplewebauthn/server library + * - Implement proper COSE key parsing + * - Handle all attestation formats + * - Implement proper EC2/RSA signature verification + */ +export class FIDO2Backend { + /** + * Verify WebAuthn attestation response (registration) + * Spec Section 8.3.1, 8.4 + */ + verifyAttestation( + attestationResponse: AttestationResponse, + expectedChallenge: string, + rpId: string, + origin: string, + ): AttestationVerificationResult { + try { + // 1. Parse and verify clientDataJSON + const clientDataJSON = JSON.parse( + Buffer.from(attestationResponse.response.clientDataJSON, 'base64').toString('utf-8') + ); + + if (clientDataJSON.type !== 'webauthn.create') { + return { success: false, credentialId: '', publicKey: '', counter: 0, error: 'Invalid clientData type' }; + } + + if (clientDataJSON.challenge !== expectedChallenge) { + return { success: false, credentialId: '', publicKey: '', counter: 0, error: 'Challenge mismatch' }; + } + + if (clientDataJSON.origin !== origin) { + return { success: false, credentialId: '', publicKey: '', counter: 0, error: 'Origin mismatch' }; + } + + // 2. Hash clientDataJSON + const clientDataHash = createHash('sha256') + .update(Buffer.from(attestationResponse.response.clientDataJSON, 'base64')) + .digest(); + + // 3. Parse attestationObject (simplified — assumes "none" attestation) + // In production: decode CBOR, verify attestation statement, extract authData + const attestationObject = Buffer.from( + attestationResponse.response.attestationObject, + 'base64' + ); + + // For demo: extract credential ID and public key from mock attestation + // In production: properly parse and verify CBOR attestationObject + const credentialId = attestationResponse.id; + const publicKey = this.extractPublicKeyFromAttestation(attestationObject); + + if (!publicKey) { + return { success: false, credentialId: '', publicKey: '', counter: 0, error: 'Could not extract public key' }; + } + + return { + success: true, + credentialId, + publicKey, + counter: 0, + transports: ['platform', 'usb'], + }; + } catch (err) { + return { + success: false, + credentialId: '', + publicKey: '', + counter: 0, + error: (err as Error).message, + }; + } + } + + /** + * Verify WebAuthn assertion response (authentication) + * Spec Section 8.3.2, 8.5 + */ + verifyAssertion( + assertionResponse: AssertionResponse, + expectedChallenge: string, + storedPublicKey: string, + storedCounter: number, + rpId: string, + origin: string, + ): AssertionVerificationResult { + try { + // 1. Parse and verify clientDataJSON + const clientDataJSON = JSON.parse( + Buffer.from(assertionResponse.response.clientDataJSON, 'base64').toString('utf-8') + ); + + if (clientDataJSON.type !== 'webauthn.get') { + return { success: false, userId: '', counter: 0, error: 'Invalid clientData type' }; + } + + if (clientDataJSON.challenge !== expectedChallenge) { + return { success: false, userId: '', counter: 0, error: 'Challenge mismatch' }; + } + + if (clientDataJSON.origin !== origin) { + return { success: false, userId: '', counter: 0, error: 'Origin mismatch' }; + } + + // 2. Hash clientDataJSON + const clientDataHash = createHash('sha256') + .update(Buffer.from(assertionResponse.response.clientDataJSON, 'base64')) + .digest(); + + // 3. Parse authenticatorData and extract counter + const authenticatorData = Buffer.from( + assertionResponse.response.authenticatorData, + 'base64' + ); + + // authenticatorData: [rpIdHash(32)] [flags(1)] [counter(4)] [optional credentialData] [optional extensions] + if (authenticatorData.length < 37) { + return { success: false, userId: '', counter: 0, error: 'Invalid authenticatorData' }; + } + + const counter = authenticatorData.readUInt32BE(33); + + // Check counter to detect cloned authenticators + if (counter <= storedCounter) { + return { success: false, userId: '', counter, error: 'Counter check failed — possible cloned authenticator' }; + } + + // 4. Verify signature + // signatureBase = clientDataHash + authenticatorData + const signatureBase = Buffer.concat([clientDataHash, authenticatorData]); + + // For demo: simplistic signature verification + // In production: proper COSE key parsing and verification (EC2, RSA, etc.) + const signature = Buffer.from(assertionResponse.response.signature, 'base64'); + const isValid = this.verifySignature(signatureBase, signature, storedPublicKey); + + if (!isValid) { + return { success: false, userId: '', counter, error: 'Signature verification failed' }; + } + + // Extract userHandle if present + let userId = ''; + if (assertionResponse.response.userHandle) { + userId = Buffer.from(assertionResponse.response.userHandle, 'base64').toString('utf-8'); + } + + return { + success: true, + userId, + counter, + }; + } catch (err) { + return { + success: false, + userId: '', + counter: 0, + error: (err as Error).message, + }; + } + } + + /** + * Extract public key from attestation object (simplified demo) + * In production: use CBOR parser, handle all formats, extract from authData + */ + private extractPublicKeyFromAttestation(attestationObject: Buffer): string | null { + // For demo: return a placeholder public key + // In production: properly decode CBOR, extract from attested credential data + try { + return attestationObject.toString('base64').substring(0, 100) || null; + } catch { + return null; + } + } + + /** + * Verify signature (simplified demo) + * In production: proper COSE key parsing and verification + */ + private verifySignature(signatureBase: Buffer, signature: Buffer, publicKeyB64: string): boolean { + try { + // For demo: always return true if signature is present + // In production: implement proper verification based on COSE key type + return signature.length > 0; + } catch { + return false; + } + } +} diff --git a/platform_impl/src/passkey/index.ts b/platform_impl/src/passkey/index.ts new file mode 100644 index 0000000..8034042 --- /dev/null +++ b/platform_impl/src/passkey/index.ts @@ -0,0 +1,31 @@ +/** + * Passkey Authentication Module — Public API + * Exports all passkey-related types and services + */ + +export type { PasskeyCredential, PasskeyUser, IPasskeyStorage } from './storage.js'; +export { InMemoryPasskeyStorage } from './storage.js'; + +export type { PasskeyChallenge } from './challenge-manager.js'; +export { PasskeyChallengeManager } from './challenge-manager.js'; + +export type { + RegistrationOptions, + AuthenticationOptions, + AttestationResponse, + AssertionResponse, + AttestationVerificationResult, + AssertionVerificationResult, +} from './fido2-backend.js'; +export { FIDO2Backend } from './fido2-backend.js'; + +export type { RegistrationResult, AuthenticationResult } from './platform-service.js'; +export { PasskeyPlatformService } from './platform-service.js'; + +export { PasskeyServer } from './passkey-server.js'; +export { PasskeyAPIServer } from './api-server.js'; +export type { PasskeyAuthResult, PasskeyRegistrationResult } from './client.js'; +export { PasskeyClient } from './client.js'; + +export type { MCPletPasskeyHelperConfig } from './mcplet-helper.js'; +export { MCPletPasskeyHelper } from './mcplet-helper.js'; diff --git a/platform_impl/src/passkey/mcplet-helper.ts b/platform_impl/src/passkey/mcplet-helper.ts new file mode 100644 index 0000000..b5881a9 --- /dev/null +++ b/platform_impl/src/passkey/mcplet-helper.ts @@ -0,0 +1,111 @@ +/** + * MCPlet Passkey Authentication Helper + * Simplified API for MCPlet tools requiring passkey authentication + * + * Usage in MCPlet tools: + * ``` + * import { MCPletPasskeyHelper } from '@platform/passkey/mcplet-helper.js'; + * + * const helper = new MCPletPasskeyHelper({ + * serverUrl: 'http://127.0.0.1:8443', + * toolName: 'sensitive-action' + * }); + * + * if (await helper.authenticate(userId)) { + * // Proceed with sensitive action + * } + * ``` + */ + +import { PasskeyClient } from './client.js'; + +export interface MCPletPasskeyHelperConfig { + serverUrl?: string; + toolName?: string; + actionDescription?: string; +} + +/** + * Helper for MCPlet tools to enforce passkey authentication + * Bridges between browser-side UI and server-side verification + */ +export class MCPletPasskeyHelper { + private client: PasskeyClient; + private config: MCPletPasskeyHelperConfig; + + constructor(config: MCPletPasskeyHelperConfig = {}) { + this.config = { + serverUrl: config.serverUrl || 'http://127.0.0.1:8443', + toolName: config.toolName || 'unnamed-tool', + actionDescription: config.actionDescription || 'perform this action', + ...config, + }; + + this.client = new PasskeyClient(this.config.serverUrl); + } + + /** + * Ensure user is authenticated with passkey before proceeding with sensitive action + * Flow: + * 1. Check if WebAuthn is available + * 2. Attempt authentication with existing passkey + * 3. If no passkey, offer to register one + * 4. Return true if authenticated, false otherwise + */ + async authenticate(userId?: string): Promise { + if (!this.client.isSupported()) { + console.warn('[MCPletPasskey] WebAuthn not supported in this browser'); + return false; + } + + // If userId provided, authenticate with that user's credential + if (userId) { + const result = await this.client.startAuthentication(userId); + if (result.success && result.userId) { + console.log(`[MCPletPasskey] User ${result.userId} authenticated with passkey`); + return true; + } + return false; + } + + // No userId: offer user to register or authenticate + // This is typically used in browser-based UI + console.log(`[MCPletPasskey] No userId provided for authentication`); + return false; + } + + /** + * Register a new passkey for the user + */ + async register(userId: string, displayName?: string): Promise { + if (!this.client.isSupported()) { + console.warn('[MCPletPasskey] WebAuthn not supported in this browser'); + return false; + } + + const result = await this.client.startRegistration(userId, displayName || userId); + if (result.success) { + console.log(`[MCPletPasskey] User ${userId} registered passkey`); + return true; + } + + console.warn(`[MCPletPasskey] Registration failed: ${result.error}`); + return false; + } + + /** + * Check if WebAuthn is available + */ + isAvailable(): boolean { + return this.client.isSupported(); + } + + /** + * Get configuration + */ + getConfig(): MCPletPasskeyHelperConfig { + return { ...this.config }; + } +} + +export default MCPletPasskeyHelper; diff --git a/platform_impl/src/passkey/passkey-server.ts b/platform_impl/src/passkey/passkey-server.ts new file mode 100644 index 0000000..c970385 --- /dev/null +++ b/platform_impl/src/passkey/passkey-server.ts @@ -0,0 +1,210 @@ +import http from 'node:http'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { exec } from 'node:child_process'; +import type { MCPletAuthPayload } from '../types/index.js'; +import { PasskeyPlatformService } from './platform-service.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +/** + * Passkey Server — Spec Section 3.7, 16.3 + * + * Provides two modes: + * 1. Interactive Ceremony Mode: Opens a browser page for WebAuthn user interaction + * - Binds exclusively to 127.0.0.1 + * - Port is dynamically allocated per ceremony + * - Server closes immediately after assertion delivery or timeout + * 2. REST API Mode: Provides HTTP endpoints for remote passkey operations + * + * Integrates with PasskeyPlatformService for FIDO2 backend operations. + */ +export class PasskeyServer { + private readonly timeoutMs: number; + private platformService: PasskeyPlatformService; + private apiServer: http.Server | null = null; + + constructor( + rpId: string = 'localhost', + origin: string = 'http://127.0.0.1', + timeoutMs = 55_000, + ) { + this.timeoutMs = timeoutMs; + this.platformService = new PasskeyPlatformService(rpId, origin); + } + + /** + * Opens the Passkey Web Page and waits for the WebAuthn assertion. + * Returns the assertion payload on success, throws on timeout or cancellation. + */ + async startCeremony(promptMessage: string): Promise { + return new Promise((resolve, reject) => { + let server: http.Server | null = null; + let timer: ReturnType | null = null; + + const cleanup = () => { + if (timer) clearTimeout(timer); + server?.close(); + }; + + server = http.createServer((req, res) => { + const url = new URL(req.url ?? '/', `http://localhost`); + + // Serve the Passkey Web Page + if (req.method === 'GET' && url.pathname === '/passkey') { + servePasskeyPage(res, promptMessage, url.searchParams.get('port') ?? ''); + return; + } + + // Receive assertion callback (POST /passkey/callback) + if (req.method === 'POST' && url.pathname === '/passkey/callback') { + let data = ''; + req.on('data', (chunk: Buffer) => { data += chunk.toString(); }); + req.on('end', () => { + try { + const assertion = JSON.parse(data) as MCPletAuthPayload; + res.writeHead(200, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify({ ok: true })); + cleanup(); + resolve(assertion); + } catch { + res.writeHead(400); + res.end(); + } + }); + return; + } + + // User cancelled + if (req.method === 'POST' && url.pathname === '/passkey/cancel') { + res.writeHead(200); + res.end(); + cleanup(); + reject(new Error('Passkey ceremony cancelled by user')); + return; + } + + res.writeHead(404); + res.end(); + }); + + // Bind to loopback with port 0 (OS assigns dynamic port) + server.listen(0, '127.0.0.1', () => { + const addr = server!.address(); + if (!addr || typeof addr === 'string') { + reject(new Error('Failed to bind Passkey server')); + return; + } + + const port = addr.port; + const pageUrl = `http://127.0.0.1:${port}/passkey?port=${port}`; + console.log(`[passkey] Opening ceremony page: ${pageUrl}`); + openBrowser(pageUrl); + }); + + // Timeout — close page and reject (Spec Section 3.7) + timer = setTimeout(() => { + cleanup(); + reject(new Error('Passkey ceremony timed out')); + }, this.timeoutMs); + }); + } +} + +function servePasskeyPage(res: http.ServerResponse, promptMessage: string, port: string): void { + // Try to serve static file first, fall back to inline + const staticPath = path.resolve(__dirname, '../../public/passkey/index.html'); + if (fs.existsSync(staticPath)) { + const html = fs.readFileSync(staticPath, 'utf-8') + .replace('{{PROMPT_MESSAGE}}', escapeHtml(promptMessage)) + .replace('{{PORT}}', port); + res.writeHead(200, { + 'Content-Type': 'text/html', + 'Content-Security-Policy': + "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'", + }); + res.end(html); + } else { + res.writeHead(200, { 'Content-Type': 'text/html' }); + res.end(inlinePasskeyPage(promptMessage, port)); + } +} + +function inlinePasskeyPage(promptMessage: string, port: string): string { + return ` + + + + 認証 + + + + +

${escapeHtml(promptMessage)}

+ + + + +`; +} + +function escapeHtml(str: string): string { + return str + .replaceAll('&', '&') + .replaceAll('<', '<') + .replaceAll('>', '>') + .replaceAll('"', '"'); +} + +function platformOpenCmd(url: string): string { + if (process.platform === 'darwin') return `open "${url}"`; + if (process.platform === 'win32') return `start "" "${url}"`; + return `xdg-open "${url}"`; +} + +function openBrowser(url: string): void { + import('node:child_process').then(({ exec }) => { + exec(platformOpenCmd(url), (err) => { + if (err) console.warn(`[passkey] Could not open browser: ${err.message}`); + }); + }).catch(() => { + console.warn('[passkey] child_process not available'); + }); +} diff --git a/platform_impl/src/passkey/platform-service.ts b/platform_impl/src/passkey/platform-service.ts new file mode 100644 index 0000000..32c06e6 --- /dev/null +++ b/platform_impl/src/passkey/platform-service.ts @@ -0,0 +1,262 @@ +/** + * Passkey Platform Service — Unified Passkey Management + * Consolidates storage, challenge management, and FIDO2 backend + * Spec Section 3.7, 7.3.1 + */ + +import type { PasskeyCredential } from './storage.js'; +import { InMemoryPasskeyStorage, type IPasskeyStorage } from './storage.js'; +import { PasskeyChallengeManager } from './challenge-manager.js'; +import { FIDO2Backend, type AttestationResponse, type AssertionResponse } from './fido2-backend.js'; + +export interface RegistrationResult { + success: boolean; + credentialId?: string; + userId?: string; + error?: string; +} + +export interface AuthenticationResult { + success: boolean; + userId?: string; + credentialId?: string; + error?: string; +} + +/** + * Passkey Platform Service + * High-level API for passkey registration and authentication + * Agnostic to transport layer (HTTP, WebSocket, etc.) + */ +export class PasskeyPlatformService { + private storage: IPasskeyStorage; + private challengeManager: PasskeyChallengeManager; + private fido2Backend: FIDO2Backend; + + constructor( + rpId: string, + origin: string, + storage?: IPasskeyStorage, + ) { + this.storage = storage ?? new InMemoryPasskeyStorage(); + this.challengeManager = new PasskeyChallengeManager(rpId, origin); + this.fido2Backend = new FIDO2Backend(); + } + + /** + * Start registration ceremony + * Returns challenge for the client to use in WebAuthn.create() + */ + async startRegistration(userId: string, displayName: string): Promise<{ + success: boolean; + challenge?: string; + userId?: string; + error?: string; + }> { + try { + // Create user if it doesn't exist + if (!(await this.storage.userExists(userId))) { + await this.storage.createUser(userId, displayName); + } + + // Generate challenge + const challenge = this.challengeManager.generateChallenge(userId, 'registration'); + + return { + success: true, + challenge, + userId, + }; + } catch (err) { + return { + success: false, + error: (err as Error).message, + }; + } + } + + /** + * Verify registration ceremony response + * Client sends attestation response after WebAuthn.create() + */ + async completeRegistration( + userId: string, + challengeB64: string, + attestationResponse: AttestationResponse, + rpId: string, + origin: string, + ): Promise { + try { + // Validate challenge + const challenge = this.challengeManager.validateChallenge(challengeB64, userId, 'registration'); + if (!challenge) { + return { success: false, error: 'Invalid or expired challenge' }; + } + + // Verify attestation + const attestResult = this.fido2Backend.verifyAttestation( + attestationResponse, + challengeB64, + rpId, + origin, + ); + + if (!attestResult.success) { + return { success: false, error: attestResult.error }; + } + + // Store credential + const credential: PasskeyCredential = { + id: attestResult.credentialId, + publicKey: attestResult.publicKey, + counter: attestResult.counter, + transports: attestResult.transports, + createdAt: new Date().toISOString(), + }; + + await this.storage.addCredential(userId, credential); + + return { + success: true, + credentialId: attestResult.credentialId, + userId, + }; + } catch (err) { + return { + success: false, + error: (err as Error).message, + }; + } + } + + /** + * Start authentication ceremony + * Returns challenge for the client to use in WebAuthn.get() + */ + async startAuthentication(userId?: string): Promise<{ + success: boolean; + challenge?: string; + allowCredentials?: Array<{ id: string; type: string }>; + error?: string; + }> { + try { + // If userId provided, generate user-specific challenge; + // otherwise, generate challenge for resident key + const ceremonyUserId = userId || 'any-user'; + + const challenge = this.challengeManager.generateChallenge(ceremonyUserId, 'authentication'); + + const allowCredentials = userId + ? (await this.storage.getCredentialsByUserId(userId)) + .map(cred => ({ id: cred.id, type: 'public-key' })) + : []; + + return { + success: true, + challenge, + allowCredentials, + }; + } catch (err) { + return { + success: false, + error: (err as Error).message, + }; + } + } + + /** + * Verify authentication ceremony response + * Client sends assertion response after WebAuthn.get() + */ + async completeAuthentication( + credentialId: string, + challengeB64: string, + assertionResponse: AssertionResponse, + rpId: string, + origin: string, + ): Promise { + try { + // Find credential and associated user + const credential = await this.storage.getCredential(credentialId); + if (!credential) { + return { success: false, error: 'Credential not found' }; + } + + // Determine user ID (credential is unique, so only one user can own it) + let userId = ''; + const allUsers = await this.storage.getUser(assertionResponse.response.userHandle || ''); + if (!allUsers) { + // Try to find user by credential + for (const [uid] of Object.entries({})) { + const creds = await this.storage.getCredentialsByUserId(uid); + if (creds.some(c => c.id === credentialId)) { + userId = uid; + break; + } + } + } else { + userId = allUsers.userId; + } + + if (!userId) { + return { success: false, error: 'Could not determine user for credential' }; + } + + // Validate challenge (note: we need to validate against the correct ceremony userId) + const challenge = this.challengeManager.validateChallenge(challengeB64, userId, 'authentication'); + if (!challenge) { + return { success: false, error: 'Invalid or expired challenge' }; + } + + // Verify assertion + const assertResult = this.fido2Backend.verifyAssertion( + assertionResponse, + challengeB64, + credential.publicKey, + credential.counter, + rpId, + origin, + ); + + if (!assertResult.success) { + return { success: false, error: assertResult.error }; + } + + // Update credential counter + await this.storage.updateCredentialCounter(credentialId, assertResult.counter); + + return { + success: true, + userId, + credentialId, + }; + } catch (err) { + return { + success: false, + error: (err as Error).message, + }; + } + } + + /** + * Get user's credentials (for management UI) + */ + async getUserCredentials(userId: string): Promise { + return this.storage.getCredentialsByUserId(userId); + } + + /** + * Delete a credential + */ + async deleteCredential(userId: string, credentialId: string): Promise<{ + success: boolean; + error?: string; + }> { + try { + await this.storage.deleteCredential(userId, credentialId); + return { success: true }; + } catch (err) { + return { success: false, error: (err as Error).message }; + } + } +} diff --git a/platform_impl/src/passkey/storage.ts b/platform_impl/src/passkey/storage.ts new file mode 100644 index 0000000..c75b7da --- /dev/null +++ b/platform_impl/src/passkey/storage.ts @@ -0,0 +1,118 @@ +/** + * Passkey Storage Interface and In-Memory Implementation + * Spec Section 3.7, 7.3.1 + */ + +export interface PasskeyCredential { + id: string; // base64-encoded credential ID + publicKey: string; // base64-encoded public key + counter: number; // signature counter (prevents cloned authenticators) + transports?: string[]; // e.g., ["platform", "usb"] + createdAt: string; // ISO 8601 timestamp + lastUsed?: string; // ISO 8601 timestamp +} + +export interface PasskeyUser { + userId: string; + displayName: string; + credentials: PasskeyCredential[]; + createdAt: string; // ISO 8601 timestamp +} + +export interface IPasskeyStorage { + // User operations + getUser(userId: string): Promise; + createUser(userId: string, displayName: string): Promise; + userExists(userId: string): Promise; + + // Credential operations + addCredential(userId: string, credential: PasskeyCredential): Promise; + getCredential(credentialId: string): Promise; + getCredentialsByUserId(userId: string): Promise; + updateCredentialCounter(credentialId: string, counter: number): Promise; + deleteCredential(userId: string, credentialId: string): Promise; +} + +/** + * In-Memory Passkey Storage Implementation + * Suitable for demo/localhost mode. For production, implement persistent storage + * (e.g., MongoDB, PostgreSQL, etc.) + */ +export class InMemoryPasskeyStorage implements IPasskeyStorage { + private users = new Map(); + + async getUser(userId: string): Promise { + return this.users.get(userId) ?? null; + } + + async createUser(userId: string, displayName: string): Promise { + if (this.users.has(userId)) { + throw new Error(`User ${userId} already exists`); + } + + const user: PasskeyUser = { + userId, + displayName, + credentials: [], + createdAt: new Date().toISOString(), + }; + + this.users.set(userId, user); + return user; + } + + async userExists(userId: string): Promise { + return this.users.has(userId); + } + + async addCredential(userId: string, credential: PasskeyCredential): Promise { + const user = this.users.get(userId); + if (!user) { + throw new Error(`User ${userId} not found`); + } + + // Check for duplicate credential ID + if (user.credentials.some(c => c.id === credential.id)) { + throw new Error(`Credential already exists for user ${userId}`); + } + + user.credentials.push(credential); + } + + async getCredential(credentialId: string): Promise { + for (const user of this.users.values()) { + const cred = user.credentials.find(c => c.id === credentialId); + if (cred) return cred; + } + return null; + } + + async getCredentialsByUserId(userId: string): Promise { + const user = this.users.get(userId); + return user?.credentials ?? []; + } + + async updateCredentialCounter(credentialId: string, counter: number): Promise { + for (const user of this.users.values()) { + const cred = user.credentials.find(c => c.id === credentialId); + if (cred) { + cred.counter = counter; + cred.lastUsed = new Date().toISOString(); + return; + } + } + throw new Error(`Credential ${credentialId} not found`); + } + + async deleteCredential(userId: string, credentialId: string): Promise { + const user = this.users.get(userId); + if (!user) { + throw new Error(`User ${userId} not found`); + } + + const idx = user.credentials.findIndex(c => c.id === credentialId); + if (idx >= 0) { + user.credentials.splice(idx, 1); + } + } +} diff --git a/platform_impl/src/pools/pool-registry.ts b/platform_impl/src/pools/pool-registry.ts new file mode 100644 index 0000000..b8beba0 --- /dev/null +++ b/platform_impl/src/pools/pool-registry.ts @@ -0,0 +1,79 @@ +import type { PoolPolicy, MCPletTool } from '../types/index.js'; + +interface RateLimitBucket { + count: number; + resetAt: number; +} + +export class PoolRegistry { + private tools: MCPletTool[] = []; + private buckets = new Map(); + + constructor(private readonly policies: Record) { + // Warn about any unknown pools at startup is deferred to registerTool + } + + registerTool(tool: MCPletTool): void { + const pool = tool.meta.pool; + if (pool && !(pool in this.policies)) { + console.warn( + `[pool-registry] Tool "${tool.name}" declares pool "${pool}" which is not in platform config — treating as pool-less`, + ); + // Treat as pool-less per spec: host MAY reject or treat as pool-less + const adjusted: MCPletTool = { + ...tool, + meta: { ...tool.meta, pool: undefined }, + }; + this.tools.push(adjusted); + return; + } + this.tools.push(tool); + } + + evictTool(toolName: string): void { + this.tools = this.tools.filter((t) => t.name !== toolName); + } + + updateTool(tool: MCPletTool): void { + this.evictTool(tool.name); + this.registerTool(tool); + } + + /** Returns tools the given agent is authorized to invoke. */ + getToolsForAgent(agentId: string, agentPools: string[]): MCPletTool[] { + return this.tools.filter((tool) => this.canAgentAccess(agentId, tool.meta.pool, agentPools)); + } + + /** Whether an agent can access a tool belonging to a given pool (or no pool). */ + canAgentAccess(agentId: string, toolPool: string | undefined, agentPools: string[]): boolean { + if (!toolPool) { + // Pool-less: accessible to any agent + return true; + } + return agentPools.includes(toolPool); + } + + /** Check and update rate limit for a pool. Returns false if limit exceeded. */ + checkRateLimit(poolName: string): boolean { + const policy = this.policies[poolName]; + if (!policy?.rateLimitPerMinute) return true; + + const now = Date.now(); + let bucket = this.buckets.get(poolName); + + if (!bucket || now >= bucket.resetAt) { + bucket = { count: 0, resetAt: now + 60_000 }; + this.buckets.set(poolName, bucket); + } + + if (bucket.count >= policy.rateLimitPerMinute) { + return false; + } + bucket.count++; + return true; + } + + getAllTools(): MCPletTool[] { + return [...this.tools]; + } +} diff --git a/platform_impl/src/types/a2a.ts b/platform_impl/src/types/a2a.ts new file mode 100644 index 0000000..664a3d7 --- /dev/null +++ b/platform_impl/src/types/a2a.ts @@ -0,0 +1,48 @@ +// A2A Protocol types — Spec Section 18 + +export interface A2AAgentCard { + agentId: string; + displayName?: string; + description?: string; + requestedPools?: string[]; + inputSchema?: Record; + outputSchema?: Record; + version?: string; +} + +export interface A2AMessageEnvelope { + messageId: string; // UUID v4 + contextId?: string; // UUID v4, stable across delegated workflow + senderId: string; + recipientId: string; + timestamp?: string; // ISO 8601 UTC + locale?: string; // BCP 47 +} + +export interface A2ATaskRequest extends A2AMessageEnvelope { + type: 'task_request'; + payload: { + parameters: Record; + history?: Array<{ + role: 'system' | 'user' | 'assistant'; + content: string; + }>; + }; +} + +export type A2ATaskStatus = + | 'success' + | 'error' + | 'timeout' + | 'cancelled' + | 'partial'; + +export interface A2ATaskResponse extends A2AMessageEnvelope { + type: 'task_response'; + replyToMessageId: string; + status: A2ATaskStatus; + payload?: { + result?: unknown; + error?: { message: string; code?: string }; + }; +} diff --git a/platform_impl/src/types/config.ts b/platform_impl/src/types/config.ts new file mode 100644 index 0000000..31b06ef --- /dev/null +++ b/platform_impl/src/types/config.ts @@ -0,0 +1,70 @@ +// Platform configuration types + +export interface PoolPolicy { + rateLimitPerMinute?: number; + domainAllowlist?: string[]; +} + +export interface AgentConfig { + class: string; + accessiblePools: string[]; + description?: string; +} + +export interface DirectorAgentConfig { + schedule: string; // cron expression + promptTemplate: string; + targetAgentId: string; // recipient agent for the generated instruction + maxRetries: number; + backoffMs: number; +} + +export interface ExternalAgentConfig { + agentId: string; + apiKey: string; + accessiblePools: string[]; +} + +export interface LLMConfig { + provider: string; // e.g. "claude" | "openrouter" + model: string; + apiKey?: string; + // OpenRouter-specific (ignored for other providers) + baseURL?: string; // defaults to https://openrouter.ai/api/v1 + siteUrl?: string; // sent as HTTP-Referer header + siteName?: string; // sent as X-Title header +} + +export interface PasskeyConfig { + mode: 'localhost' | 'https'; + rpId: string; + fido2ServerUrl?: string; + apiPort?: number; // Port for REST API (default: 8443) +} + +export interface DashboardConfig { + port: number; +} + +export interface A2AExternalEndpointConfig { + port: number; +} + +export interface MCPletServerConfig { + name: string; + command: string; // e.g. "node" + args: string[]; // e.g. ["/abs/path/to/dist/mcplets/crm/index.js"] + env?: Record; +} + +export interface PlatformConfig { + llm: LLMConfig; + pools: Record; + agents: Record; + mcpletServers?: MCPletServerConfig[]; + directorAgent?: DirectorAgentConfig; + externalAgents?: ExternalAgentConfig[]; + passkey?: PasskeyConfig; + dashboard?: DashboardConfig; + a2aExternalEndpoint?: A2AExternalEndpointConfig; +} diff --git a/platform_impl/src/types/index.ts b/platform_impl/src/types/index.ts new file mode 100644 index 0000000..f821abe --- /dev/null +++ b/platform_impl/src/types/index.ts @@ -0,0 +1,3 @@ +export * from './a2a.js'; +export * from './mcplet.js'; +export * from './config.js'; diff --git a/platform_impl/src/types/mcplet.ts b/platform_impl/src/types/mcplet.ts new file mode 100644 index 0000000..5722d39 --- /dev/null +++ b/platform_impl/src/types/mcplet.ts @@ -0,0 +1,58 @@ +// MCPlet metadata types — Spec Section 4, 6 + +export type MCPletType = 'read' | 'prepare' | 'action'; +export type Visibility = 'model' | 'app'; + +export interface MCPletAuth { + required: 'passkey'; + enforcement: 'strict' | 'workflow' | 'host-only'; + promptMessage?: string; +} + +export interface MCPletMeta { + mcpletType: MCPletType; + pool?: string; + visibility: Visibility[]; + mcpletToolResultSchemaUri?: string; + auth?: MCPletAuth; +} + +// Registered tool with resolved MCPlet metadata +export interface MCPletTool { + name: string; + description: string; + inputSchema: Record; + meta: MCPletMeta; +} + +// Tool result envelope — Spec Section 9.1 +export interface MCPletToolResult { + result?: T; + error?: { message: string; code: MCPletErrorCode }; + _meta: { + timestamp: string; + toolId: string; + mcpletType: MCPletType; + visibility: Visibility[]; + }; +} + +export type MCPletErrorCode = + | 'AUTH_REQUIRED' + | 'AUTH_FAILED' + | 'VALIDATION_ERROR' + | 'NOT_FOUND' + | 'RATE_LIMITED' + | 'SERVICE_UNAVAILABLE' + | 'UNKNOWN_ERROR' + | `X_${string}`; + +// WebAuthn assertion injected by Host into params._meta (Spec Section 7.3.1) +export interface MCPletAuthPayload { + type: 'passkey_assertion'; + challenge: string; + clientDataJSON: string; + authenticatorData: string; + signature: string; + userHandle?: string; +} diff --git a/platform_impl/tsconfig.json b/platform_impl/tsconfig.json new file mode 100644 index 0000000..2c632d7 --- /dev/null +++ b/platform_impl/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "dist", + "rootDir": "src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/reference_impl/agents/agent-base.ts b/reference_impl/agents/agent-base.ts new file mode 100644 index 0000000..970d035 --- /dev/null +++ b/reference_impl/agents/agent-base.ts @@ -0,0 +1,225 @@ +/** + * Lightweight AgentBase for reference implementation. + * + * When instantiated by the platform Host, deps (AgentDeps from platform_impl) + * is passed as the third constructor argument. AgentBase wires callTool to go + * through the platform's MCPlet router with pool-access, rate-limit, and + * Passkey enforcement — without importing platform types directly. + * + * In standalone/test mode, call bindCallTool() to inject a mock implementation. + */ +import { randomUUID } from 'node:crypto'; +import type { A2ATaskRequest, A2ATaskResponse } from './platform-types.js'; + +// Structural shape of the platform deps we need (duck typing, no import required) +interface PlatformDeps { + mcpRouter?: { + callTool?: ( + toolName: string, + args: Record, + ) => Promise<{ content: Array<{ type: string; text?: string }> }>; + }; + poolRegistry?: { + getAllTools?: () => Array<{ + name: string; + meta: { + pool?: string; + mcpletType: string; + auth?: { required?: string; enforcement?: string; promptMessage?: string }; + }; + }>; + canAgentAccess?: (agentId: string, pool: string | undefined, pools: string[]) => boolean; + checkRateLimit?: (pool: string) => boolean; + }; + auditLog?: { + record?: (entry: Record) => void; + }; + passkeyServer?: { + startCeremony?: (message: string) => Promise; + }; +} + +export abstract class AgentBase { + abstract readonly agentId: string; + abstract readonly accessiblePools: string[]; + + abstract handle(task: A2ATaskRequest): Promise; + + protected callTool: ( + toolName: string, + args: Record, + ) => Promise; + + /** Set by subclasses (or AgentBase.handle wrapper) before calling tools in a task. */ + protected _currentContextId: string | undefined = undefined; + + /** Per-contextId assertion cache for 'workflow' enforcement tools. */ + protected readonly _assertionCache = new Map(); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + constructor(_agentId?: string, _accessiblePools?: string[], deps?: any) { + if (deps) { + this.callTool = buildPlatformCallTool(this as unknown as AgentBase & { agentId: string; accessiblePools: string[] }, deps as PlatformDeps); + } else { + this.callTool = async (toolName) => { + throw new Error( + `[agent-base] callTool("${toolName}") called without a bound implementation. ` + + 'Inject via bindCallTool() or use the platform Host.', + ); + }; + } + } + + /** Bind a tool caller (used in standalone/test mode). */ + bindCallTool(fn: (toolName: string, args: Record) => Promise): void { + this.callTool = fn; + } + + protected success(task: A2ATaskRequest, result: unknown): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'success', + payload: { result }, + }; + } + + protected error(task: A2ATaskRequest, message: string, code?: string): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'error', + payload: { error: { message, code } }, + }; + } + + protected cancelled(task: A2ATaskRequest, reason: string): A2ATaskResponse { + return { + messageId: randomUUID(), + contextId: task.contextId, + senderId: this.agentId, + recipientId: task.senderId, + timestamp: new Date().toISOString(), + type: 'task_response', + replyToMessageId: task.messageId, + status: 'cancelled', + payload: { error: { message: reason } }, + }; + } +} + +/** + * Build a callTool function that goes through the platform's MCPlet router + * with pool-access, rate-limit, and Passkey enforcement. + */ +function buildPlatformCallTool( + agent: AgentBase & { agentId: string; accessiblePools: string[] }, + deps: PlatformDeps, +): (toolName: string, args: Record) => Promise { + // Access protected cache fields via a typed cast (same class file, safe). + const agentCache = agent as unknown as { + _currentContextId: string | undefined; + _assertionCache: Map; + }; + + return async (toolName: string, args: Record) => { + const tools = deps.poolRegistry?.getAllTools?.() ?? []; + const tool = tools.find((t) => t.name === toolName); + + // Pool access check + if (tool?.meta.pool) { + const canAccess = + deps.poolRegistry?.canAgentAccess?.(agent.agentId, tool.meta.pool, agent.accessiblePools) ?? true; + if (!canAccess) { + throw new Error(`[${agent.agentId}] Pool access denied for tool "${toolName}" (pool: ${tool.meta.pool})`); + } + } + + // Rate limit check + if (tool?.meta.pool) { + const allowed = deps.poolRegistry?.checkRateLimit?.(tool.meta.pool) ?? true; + if (!allowed) { + throw new Error(`[${agent.agentId}] Rate limit exceeded for pool "${tool.meta.pool}"`); + } + } + + // Passkey interception for action tools + let callArgs = args; + if (tool?.meta.mcpletType === 'action' && tool.meta.auth?.required === 'passkey') { + const enforcement = tool.meta.auth.enforcement ?? 'strict'; + + let assertion: unknown; + if (enforcement === 'workflow') { + // Cache key: contextId (scopes assertion to one Director cycle) + const contextId = agentCache._currentContextId ?? 'default'; + if (agentCache._assertionCache.has(contextId)) { + assertion = agentCache._assertionCache.get(contextId); + console.log(`[${agent.agentId}] Reusing cached Passkey assertion for contextId="${contextId}" (tool: ${toolName})`); + } else { + assertion = await deps.passkeyServer?.startCeremony?.( + tool.meta.auth.promptMessage ?? `Authorize workflow actions for this task`, + ); + if (!assertion) { + throw new Error(`[${agent.agentId}] Passkey authentication cancelled for "${toolName}"`); + } + agentCache._assertionCache.set(contextId, assertion); + console.log(`[${agent.agentId}] Passkey assertion cached for contextId="${contextId}"`); + } + } else { + // 'strict': new ceremony per invocation + assertion = await deps.passkeyServer?.startCeremony?.( + tool.meta.auth.promptMessage ?? `Authorize action: ${toolName}`, + ); + if (!assertion) { + throw new Error(`[${agent.agentId}] Passkey authentication cancelled for "${toolName}"`); + } + } + + callArgs = { ...args, _mcplet_auth: assertion }; + } + + // Audit log for action tools + if (tool?.meta.mcpletType === 'action') { + deps.auditLog?.record?.({ + type: 'action_invocation', + agentId: agent.agentId, + toolName, + timestamp: new Date().toISOString(), + }); + } + + if (!deps.mcpRouter?.callTool) { + throw new Error(`[${agent.agentId}] mcpRouter not available for tool "${toolName}"`); + } + + const result = await deps.mcpRouter.callTool(toolName, callArgs); + const text = result.content.find((c) => c.type === 'text')?.text ?? '{}'; + + let parsed: unknown; + try { + parsed = JSON.parse(text); + } catch { + return text; + } + + // MCPlet server wraps results in { result, _meta } envelope — unwrap it. + const envelope = parsed as { result?: unknown; error?: { message: string; code: string } }; + if (envelope && typeof envelope === 'object' && 'error' in envelope && envelope.error) { + throw new Error(`Tool "${toolName}" returned error: ${envelope.error.message} (${envelope.error.code})`); + } + if (envelope && typeof envelope === 'object' && 'result' in envelope) { + return envelope.result; + } + return parsed; + }; +} diff --git a/reference_impl/agents/dispatch/index.ts b/reference_impl/agents/dispatch/index.ts new file mode 100644 index 0000000..afbc89c --- /dev/null +++ b/reference_impl/agents/dispatch/index.ts @@ -0,0 +1,77 @@ +/** + * 発信・発注・発令 Agent + * + * accessiblePools: [media-pool] + * 利用可能ツール: read_site_stats (media-pool, read), + * send_email (media-pool, action, passkey-workflow), + * post_sns (media-pool, action, passkey-workflow) + * + * タスク: 企画・Plan Agent が作成した施策を実行する。 + * send_email は action ツール (enforcement: workflow)。 + * 最初の send_email 呼び出し時に一度だけ Passkey 認証を行い、 + * 同じ contextId 内の後続呼び出しはキャッシュされた assertion を再利用する。 + */ +import type { A2ATaskRequest, A2ATaskResponse } from '../platform-types.js'; +import { AgentBase } from '../agent-base.js'; + +interface Plan { + title: string; + targetDate: string; + campaign: { dessertItem: string }; + targetCustomers: Array<{ customerId: string; name: string }>; + emailTemplate: string; +} + +export class DispatchAgent extends AgentBase { + readonly agentId = 'dispatch-agent'; + readonly accessiblePools = ['media-pool']; + + async handle(task: A2ATaskRequest): Promise { + const { plan } = task.payload.parameters as { plan?: Plan }; + + if (!plan) { + return this.error(task, 'No plan provided in task parameters'); + } + + // Set contextId so buildPlatformCallTool can scope the workflow assertion cache + this._currentContextId = task.contextId; + + const results: Array<{ customerId: string; name: string; status: string; error?: string }> = []; + + for (const customer of plan.targetCustomers) { + try { + // send_email enforcement: 'workflow'. First call in this contextId triggers + // one Passkey ceremony; subsequent calls reuse the cached assertion. + await this.callTool('send_email', { + to: `${customer.customerId}@example.com`, + subject: `【特別ご招待】明日のご来店に無料${plan.campaign.dessertItem}をプレゼント`, + body: plan.emailTemplate, + customerId: customer.customerId, + }); + + results.push({ customerId: customer.customerId, name: customer.name, status: 'sent' }); + console.log(`[dispatch] Email sent to ${customer.name} (${customer.customerId})`); + } catch (err) { + results.push({ + customerId: customer.customerId, + name: customer.name, + status: 'failed', + error: (err as Error).message, + }); + console.error(`[dispatch] Failed to send to ${customer.name}: ${(err as Error).message}`); + } + } + + const sent = results.filter((r) => r.status === 'sent').length; + const failed = results.filter((r) => r.status === 'failed').length; + + console.log(`[dispatch] Campaign dispatch complete: ${sent} sent, ${failed} failed`); + + return this.success(task, { + campaign: plan.title, + targetDate: plan.targetDate, + dispatch: { sent, failed, total: plan.targetCustomers.length }, + results, + }); + } +} diff --git a/reference_impl/agents/info-gathering/index.ts b/reference_impl/agents/info-gathering/index.ts new file mode 100644 index 0000000..219dc85 --- /dev/null +++ b/reference_impl/agents/info-gathering/index.ts @@ -0,0 +1,109 @@ +/** + * 情報収集・分析 Agent + * + * accessiblePools: [info-pool] + * 利用可能ツール: fetch_web_content (info-pool), call_external_api (info-pool), + * query_crm (pool-less), query_erp (pool-less), query_hr (pool-less) + * + * タスク: 天気予報・在庫・顧客キャンセル傾向を収集し、分析サマリを返す + */ +import type { A2ATaskRequest, A2ATaskResponse } from '../platform-types.js'; +import { AgentBase } from '../agent-base.js'; + +export class InfoGatheringAgent extends AgentBase { + readonly agentId = 'info-gathering-agent'; + readonly accessiblePools = ['info-pool']; + + async handle(task: A2ATaskRequest): Promise { + const instruction = (task.payload.parameters['instruction'] as string | undefined) ?? ''; + const targetDate = new Date().toISOString().slice(0, 10); + + try { + // 1. Collect weather forecast + const weather = await this.callTool('fetch_web_content', { + source: 'weather_forecast', + date: targetDate, + }); + + // 2. Collect dessert inventory via external API + const inventory = await this.callTool('call_external_api', { + api: 'inventory', + params: { item: 'dessert' }, + }); + + // 3. Query CRM for high-cancellation-tendency customers + const customers = await this.callTool('query_crm', { + entity: 'customers', + filter: 'rain_cancel_tendency', + }); + + // 4. Query reservations for tomorrow + const reservations = await this.callTool('query_crm', { + entity: 'reservations', + filter: `date=${targetDate}`, + }); + + // 5. Synthesize analysis + const analysis = this.synthesize({ weather, inventory, customers, reservations, targetDate, instruction }); + + console.log(`[info-gathering] Analysis complete: ${analysis.summary}`); + + return this.success(task, { + analysis, + rawData: { weather, inventory, customers, reservations }, + }); + } catch (err) { + return this.error(task, (err as Error).message); + } + } + + private synthesize(data: { + weather: unknown; + inventory: unknown; + customers: unknown; + reservations: unknown; + targetDate: string; + instruction: string; + }): Record { + const wx = data.weather as { forecasts?: Array<{ condition?: string; summary?: string; precipitationProbability?: number }> }; + const forecast = wx?.forecasts?.[0]; + const isRainy = forecast?.condition === 'rainy'; + const precipProb = forecast?.precipitationProbability ?? 0; + + const inv = data.inventory as { items?: Array<{ name?: string; stock?: number; category?: string }> }; + const desserts = (inv?.items ?? []).filter((i) => i.category === 'dessert'); + const hasDessertStock = desserts.some((d) => (d.stock ?? 0) > 0); + + const cust = data.customers as { customers?: Array; total?: number }; + const highCancelCount = cust?.total ?? (cust?.customers?.length ?? 0); + + const res = data.reservations as { reservations?: Array; total?: number }; + const reservationCount = res?.total ?? (res?.reservations?.length ?? 0); + + const actionRecommended = isRainy && hasDessertStock && highCancelCount > 0; + + return { + targetDate: data.targetDate, + weather: { + condition: forecast?.condition ?? 'unknown', + isRainy, + precipitationProbability: precipProb, + summary: forecast?.summary ?? '', + }, + inventory: { + hasDessertStock, + dessertsAvailable: desserts.map((d) => ({ name: d.name, stock: d.stock })), + }, + customers: { + highCancelTendencyCount: highCancelCount, + }, + reservations: { + tomorrowCount: reservationCount, + }, + actionRecommended, + summary: actionRecommended + ? `明日は雨予報(${precipProb}%)で、デザート在庫あり、高キャンセル傾向顧客${highCancelCount}名・予約${reservationCount}件あり。無料デザートキャンペーンを推奨。` + : `現時点でキャンペーン実施条件が揃っていません。`, + }; + } +} diff --git a/reference_impl/agents/planning/index.ts b/reference_impl/agents/planning/index.ts new file mode 100644 index 0000000..72d602f --- /dev/null +++ b/reference_impl/agents/planning/index.ts @@ -0,0 +1,108 @@ +/** + * 企画・Plan Agent + * + * accessiblePools: [] (pool-less のみ) + * 利用可能ツール: query_crm, query_erp, query_hr (全て pool-less) + * + * タスク: 情報収集結果を受け取り、具体的な施策を立案する。 + * Passkey (host-only) で店長に承認を求める。 + */ +import type { A2ATaskRequest, A2ATaskResponse } from '../platform-types.js'; +import { AgentBase } from '../agent-base.js'; + +interface AnalysisResult { + targetDate: string; + weather: { isRainy: boolean; precipitationProbability: number; summary: string }; + inventory: { hasDessertStock: boolean; dessertsAvailable: Array<{ name: string; stock: number }> }; + customers: { highCancelTendencyCount: number }; + reservations: { tomorrowCount: number }; + actionRecommended: boolean; + summary: string; +} + +export class PlanningAgent extends AgentBase { + readonly agentId = 'planning-agent'; + readonly accessiblePools: string[] = []; + + async handle(task: A2ATaskRequest): Promise { + const { analysis, rawData } = task.payload.parameters as { + analysis?: AnalysisResult; + rawData?: unknown; + }; + + if (!analysis) { + return this.error(task, 'No analysis data provided in task parameters'); + } + + if (!analysis.actionRecommended) { + return this.cancelled(task, `施策実施条件未達: ${analysis.summary}`); + } + + try { + // 1. Get today's reservations from CRM for targeting + const reservationData = await this.callTool('query_crm', { + entity: 'reservations', + filter: `date=${analysis.targetDate}`, + }) as { reservations?: Array<{ customerName: string; customerId: string }> }; + + // 2. Get dessert inventory details from ERP + const inventoryData = await this.callTool('query_erp', { + entity: 'inventory', + item: 'dessert', + }) as { items?: Array<{ name: string; stock: number; costPerUnit: number }> }; + + // 3. Build the plan + const desserts = (inventoryData?.items ?? []).filter((i) => (i.stock ?? 0) > 0); + const targetDessert = desserts[0]; + const targetCustomers = (reservationData?.reservations ?? []).slice(0, analysis.customers.highCancelTendencyCount); + + const plan = { + title: '無料デザートキャンペーン', + targetDate: analysis.targetDate, + rationale: analysis.summary, + campaign: { + dessertItem: targetDessert?.name ?? 'デザート', + freeItemPerCustomer: 1, + totalCost: (targetDessert?.costPerUnit ?? 0) * targetCustomers.length, + }, + targetCustomers: targetCustomers.map((c) => ({ + customerId: c.customerId, + name: c.customerName, + })), + emailTemplate: buildEmailTemplate(analysis.targetDate, targetDessert?.name ?? 'デザート'), + createdAt: new Date().toISOString(), + status: 'pending_approval', + }; + + console.log( + `[planning] Plan created: ${plan.title} for ${targetCustomers.length} customers`, + ); + + // 4. Approval is handled by the Host (Passkey ceremony triggered by DispatchAgent) + // PlanningAgent returns the plan with status: pending_approval. + // The orchestration layer (Director → Dispatch) is responsible for auth flow. + return this.success(task, { + plan, + rawData, + nextAgent: 'dispatch-agent', + }); + } catch (err) { + return this.error(task, (err as Error).message); + } + } +} + +function buildEmailTemplate(date: string, dessertName: string): string { + return `件名: 【特別ご招待】明日のご来店に無料${dessertName}をプレゼント + +お客様へ + +明日 ${date} のご予約、誠にありがとうございます。 + +明日は雨模様のお天気が予想されますが、 +特別に無料の${dessertName}をご用意しております。 + +ぜひお越しください。スタッフ一同、お待ちしております。 + +※ 本メールは予約システムより自動送信されています。`; +} diff --git a/reference_impl/agents/platform-types.ts b/reference_impl/agents/platform-types.ts new file mode 100644 index 0000000..36c8f67 --- /dev/null +++ b/reference_impl/agents/platform-types.ts @@ -0,0 +1,33 @@ +/** + * Minimal A2A type definitions for reference implementation agents. + * Mirrors platform_impl/src/types/a2a.ts — keep in sync. + */ + +export interface A2ATaskRequest { + messageId: string; + contextId?: string; + senderId: string; + recipientId: string; + timestamp?: string; + locale?: string; + type: 'task_request'; + payload: { + parameters: Record; + history?: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>; + }; +} + +export interface A2ATaskResponse { + messageId: string; + contextId?: string; + senderId: string; + recipientId: string; + timestamp?: string; + type: 'task_response'; + replyToMessageId: string; + status: 'success' | 'error' | 'timeout' | 'cancelled' | 'partial'; + payload?: { + result?: unknown; + error?: { message: string; code?: string }; + }; +} diff --git a/reference_impl/agents/register.ts b/reference_impl/agents/register.ts new file mode 100644 index 0000000..5c9ca21 --- /dev/null +++ b/reference_impl/agents/register.ts @@ -0,0 +1,22 @@ +/** + * Register reference implementation Agent classes with the platform Host. + * Import this module before calling MCPletHost.start() to make the agent + * classes available for instantiation from config. + * + * Usage in platform host entry point: + * import '../../reference_impl/agents/register.js'; + * import { MCPletHost } from '../platform_impl/src/host/mcplet-host.js'; + */ +import { InfoGatheringAgent } from './info-gathering/index.js'; +import { PlanningAgent } from './planning/index.js'; +import { DispatchAgent } from './dispatch/index.js'; + +// Lazy import of registerAgentClass to avoid circular dependency at module level +// In production, this registration is done in the host entry point. +export { InfoGatheringAgent, PlanningAgent, DispatchAgent }; + +export const AGENT_CLASSES: Record unknown> = { + InfoGatheringAgent, + PlanningAgent, + DispatchAgent, +}; diff --git a/reference_impl/config/reference.yaml b/reference_impl/config/reference.yaml new file mode 100644 index 0000000..956da6f --- /dev/null +++ b/reference_impl/config/reference.yaml @@ -0,0 +1,105 @@ +# MCPletA2A Reference Implementation — Configuration +# Cancel-Rate Reduction Scenario (キャンセル率低減シナリオ) + +#llm: +# provider: claude +# model: claude-sonnet-4-6 +# apiKey: ${ANTHROPIC_API_KEY} + +# --- OpenRouter alternative --- +llm: + provider: openrouter + model: anthropic/claude-sonnet-4-5 + apiKey: ${OPENROUTER_API_KEY} + #siteUrl: https://your-site.example.com + #siteName: MCPletA2A + +# Mock service base URL (replace with real service URLs in production) +mockServiceUrl: http://localhost:5100 + +pools: + media-pool: + rateLimitPerMinute: 60 + info-pool: + rateLimitPerMinute: 120 + +# MCPlet server processes (spawned by the Host via stdio transport). +# ${REF_IMPL_DIST} is set by start.sh to the reference_impl/dist directory. +mcpletServers: + - name: crm-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/internal/crm/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: erp-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/internal/erp/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: hr-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/internal/hr/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: web-access-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/info-pool/web-access/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: api-access-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/info-pool/api-access/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: site-access-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/media-pool/site-access/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: email-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/media-pool/email/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + - name: sns-mcplet + command: node + args: ["${REF_IMPL_DIST}/mcplets/media-pool/sns/index.js"] + env: + MOCK_SERVICE_URL: http://localhost:5100 + +agents: + info-gathering-agent: + class: InfoGatheringAgent + accessiblePools: [info-pool] + description: 天気予報・在庫・顧客キャンセル傾向を収集・分析するAgent + planning-agent: + class: PlanningAgent + accessiblePools: [] + description: 収集データを元にキャンペーン施策を立案するAgent + dispatch-agent: + class: DispatchAgent + accessiblePools: [media-pool] + description: 承認済みの施策を実行(Email・SNS送信)するAgent + +directorAgent: + # 毎朝 7:00 にトリガー + schedule: "0 7 * * *" + targetAgentId: info-gathering-agent + promptTemplate: | + 今日の天気予報と在庫情報、キャンセル傾向の高い予約客情報を収集・分析し、 + キャンセル率を下げる施策を立案するためのデータを収集してください。 + 対象日付: {date} + maxRetries: 3 + backoffMs: 5000 + +externalAgents: [] + +passkey: + mode: localhost + rpId: localhost + +dashboard: + port: 4000 + +a2aExternalEndpoint: + port: 4001 diff --git a/reference_impl/mcplets/info-pool/api-access/index.ts b/reference_impl/mcplets/info-pool/api-access/index.ts new file mode 100644 index 0000000..664d4f9 --- /dev/null +++ b/reference_impl/mcplets/info-pool/api-access/index.ts @@ -0,0 +1,48 @@ +/** + * 外部 API アクセス MCPlet + * pool: info-pool | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('api-access-mcplet'); + +server.registerTool({ + name: 'call_external_api', + description: '外部APIを呼び出してデータを取得します。在庫情報や外部データソースの参照に使用します。', + inputSchema: { + type: 'object', + properties: { + api: { + type: 'string', + description: '呼び出すAPI識別子 (例: inventory, customer_stats)', + }, + params: { + type: 'object', + description: 'APIクエリパラメータ', + additionalProperties: true, + }, + }, + required: ['api'], + }, + mcpletType: 'read', + pool: 'info-pool', + visibility: ['model'], + handler: async (args) => { + const api = args['api'] as string; + const params = (args['params'] as Record | undefined) ?? {}; + + if (api === 'inventory') { + const item = params['item'] ?? ''; + const qs = item ? `?item=${encodeURIComponent(item)}` : ''; + const res = await fetch(`${MOCK_SERVICE_URL}/erp/inventory${qs}`); + if (!res.ok) throw new Error(`Inventory API returned ${res.status}`); + return res.json(); + } + + return { api, params, data: `Mock API response for api="${api}"` }; + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/info-pool/web-access/index.ts b/reference_impl/mcplets/info-pool/web-access/index.ts new file mode 100644 index 0000000..397c59b --- /dev/null +++ b/reference_impl/mcplets/info-pool/web-access/index.ts @@ -0,0 +1,45 @@ +/** + * 外部 Web アクセス MCPlet + * pool: info-pool | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('web-access-mcplet'); + +server.registerTool({ + name: 'fetch_web_content', + description: '外部Webサイトのコンテンツを取得します。天気予報など外部情報の収集に使用します。', + inputSchema: { + type: 'object', + properties: { + source: { + type: 'string', + description: '取得する情報ソース (例: weather_forecast, news)', + }, + date: { + type: 'string', + description: '対象日付 (YYYY-MM-DD形式)', + }, + }, + required: ['source'], + }, + mcpletType: 'read', + pool: 'info-pool', + visibility: ['model'], + handler: async (args) => { + const source = args['source'] as string; + const date = (args['date'] as string | undefined) ?? new Date().toISOString().slice(0, 10); + + if (source === 'weather_forecast' || source === 'weather') { + const res = await fetch(`${MOCK_SERVICE_URL}/weather/forecast?date=${date}`); + if (!res.ok) throw new Error(`Weather service returned ${res.status}`); + return res.json(); + } + + return { source, date, content: `Mock web content for source="${source}" on ${date}` }; + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/internal/crm/index.ts b/reference_impl/mcplets/internal/crm/index.ts new file mode 100644 index 0000000..bd8aff7 --- /dev/null +++ b/reference_impl/mcplets/internal/crm/index.ts @@ -0,0 +1,56 @@ +/** + * CRM MCPlet (内部システム) + * pool: なし (pool-less) | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('crm-mcplet'); + +server.registerTool({ + name: 'query_crm', + description: 'CRMシステムから顧客・予約情報を取得します。キャンセル傾向分析や顧客リスト取得に使用します。', + inputSchema: { + type: 'object', + properties: { + entity: { + type: 'string', + enum: ['customers', 'reservations'], + description: '取得するエンティティ種別', + }, + filter: { + type: 'string', + description: 'フィルタ条件 (例: rain_cancel_tendency, date=YYYY-MM-DD)', + }, + }, + required: ['entity'], + }, + mcpletType: 'read', + visibility: ['model'], + handler: async (args) => { + const entity = args['entity'] as string; + const filter = args['filter'] as string | undefined; + + if (entity === 'customers') { + const qs = filter ? `?filter=${encodeURIComponent(filter)}` : ''; + const res = await fetch(`${MOCK_SERVICE_URL}/crm/customers${qs}`); + if (!res.ok) throw new Error(`CRM API returned ${res.status}`); + return res.json(); + } + + if (entity === 'reservations') { + // filter may be "date=2026-03-28" + const dateMatch = filter?.match(/date=(\d{4}-\d{2}-\d{2})/); + const date = dateMatch ? dateMatch[1] : ''; + const qs = date ? `?date=${date}` : ''; + const res = await fetch(`${MOCK_SERVICE_URL}/crm/reservations${qs}`); + if (!res.ok) throw new Error(`CRM API returned ${res.status}`); + return res.json(); + } + + throw new Error(`Unknown CRM entity: ${entity}`); + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/internal/erp/index.ts b/reference_impl/mcplets/internal/erp/index.ts new file mode 100644 index 0000000..816ce80 --- /dev/null +++ b/reference_impl/mcplets/internal/erp/index.ts @@ -0,0 +1,46 @@ +/** + * ERP MCPlet (内部システム) + * pool: なし (pool-less) | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('erp-mcplet'); + +server.registerTool({ + name: 'query_erp', + description: 'ERPシステムから在庫・発注情報を取得します。商品在庫確認や調達状況の把握に使用します。', + inputSchema: { + type: 'object', + properties: { + entity: { + type: 'string', + enum: ['inventory', 'orders'], + description: '取得するエンティティ種別', + }, + item: { + type: 'string', + description: '商品カテゴリ (例: dessert, drink)', + }, + }, + required: ['entity'], + }, + mcpletType: 'read', + visibility: ['model'], + handler: async (args) => { + const entity = args['entity'] as string; + const item = args['item'] as string | undefined; + + if (entity === 'inventory') { + const qs = item ? `?item=${encodeURIComponent(item)}` : ''; + const res = await fetch(`${MOCK_SERVICE_URL}/erp/inventory${qs}`); + if (!res.ok) throw new Error(`ERP API returned ${res.status}`); + return res.json(); + } + + return { entity, message: 'Mock ERP orders data' }; + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/internal/hr/index.ts b/reference_impl/mcplets/internal/hr/index.ts new file mode 100644 index 0000000..7fb3c84 --- /dev/null +++ b/reference_impl/mcplets/internal/hr/index.ts @@ -0,0 +1,57 @@ +/** + * HR MCPlet (内部システム) + * pool: なし (pool-less) | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const server = new MCPletServer('hr-mcplet'); + +server.registerTool({ + name: 'query_hr', + description: 'HRシステムからスタッフ情報・シフトを取得します。施策実行に必要な人員確認に使用します。', + inputSchema: { + type: 'object', + properties: { + entity: { + type: 'string', + enum: ['staff', 'shifts'], + description: '取得するエンティティ種別', + }, + date: { + type: 'string', + description: '対象日付 (YYYY-MM-DD形式)', + }, + }, + required: ['entity'], + }, + mcpletType: 'read', + visibility: ['model'], + handler: async (args) => { + const entity = args['entity'] as string; + const date = (args['date'] as string | undefined) ?? new Date().toISOString().slice(0, 10); + + if (entity === 'staff') { + return { + staff: [ + { staffId: 'S001', name: '中村 りか', role: 'manager', available: true }, + { staffId: 'S002', name: '小林 けん', role: 'waiter', available: true }, + { staffId: 'S003', name: '加藤 みゆ', role: 'waiter', available: false }, + ], + }; + } + + if (entity === 'shifts') { + return { + date, + shifts: [ + { staffId: 'S001', startTime: '17:00', endTime: '23:00' }, + { staffId: 'S002', startTime: '17:00', endTime: '22:00' }, + ], + }; + } + + throw new Error(`Unknown HR entity: ${entity}`); + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/mcplet-server.ts b/reference_impl/mcplets/mcplet-server.ts new file mode 100644 index 0000000..e73b40a --- /dev/null +++ b/reference_impl/mcplets/mcplet-server.ts @@ -0,0 +1,125 @@ +/** + * MCPlet Server base — wraps MCP SDK's low-level Server to include + * _meta.mcpletType in tools/list responses as required by the MCPlet spec. + */ +import { Server } from '@modelcontextprotocol/sdk/server/index.js'; +import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; +import { + CallToolRequestSchema, + ListToolsRequestSchema, +} from '@modelcontextprotocol/sdk/types.js'; + +export type MCPletType = 'read' | 'prepare' | 'action'; +export type Visibility = 'model' | 'app'; + +export interface MCPletToolAuth { + required: 'passkey'; + enforcement: 'strict' | 'workflow' | 'host-only'; + promptMessage?: string; +} + +export interface MCPletToolDef { + name: string; + description: string; + inputSchema: Record; + mcpletType: MCPletType; + pool?: string; + visibility: Visibility[]; + auth?: MCPletToolAuth; + handler: (args: Record, authPayload?: Record) => Promise; +} + +export class MCPletServer { + private readonly server: Server; + private readonly tools = new Map(); + + constructor(private readonly serverName: string, version = '0.1.0') { + this.server = new Server( + { name: serverName, version }, + { capabilities: { tools: {} } }, + ); + this.setupHandlers(); + } + + registerTool(def: MCPletToolDef): this { + this.tools.set(def.name, def); + return this; + } + + async listen(): Promise { + const transport = new StdioServerTransport(); + await this.server.connect(transport); + console.error(`[mcplet-server] ${this.serverName} listening on stdio`); + } + + private setupHandlers(): void { + // tools/list — include _meta for MCPlet discovery (Spec Section 5.3.1) + this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ + tools: [...this.tools.values()].map((t) => ({ + name: t.name, + description: t.description, + inputSchema: t.inputSchema, + _meta: { + mcpletType: t.mcpletType, + pool: t.pool, + visibility: t.visibility, + auth: t.auth ?? null, + }, + })), + })); + + // tools/call + this.server.setRequestHandler(CallToolRequestSchema, async (request) => { + const toolName = request.params.name; + const tool = this.tools.get(toolName); + + if (!tool) { + return { + content: [{ type: 'text', text: this.errorEnvelope(toolName, `Tool "${toolName}" not found`, 'NOT_FOUND') }], + isError: true, + }; + } + + // Extract auth payload injected by Host (Spec Section 7.3.1) + const requestMeta = request.params._meta as Record | undefined; + const authPayload = requestMeta?.mcplet_auth as Record | undefined; + + // Enforce auth requirement ('strict' = per-call ceremony; 'workflow' = cached ceremony per contextId) + if (tool.auth?.required === 'passkey' && + (tool.auth.enforcement === 'strict' || tool.auth.enforcement === 'workflow') && + !authPayload) { + return { + content: [{ type: 'text', text: this.errorEnvelope(toolName, 'Authentication required', 'AUTH_REQUIRED', tool.mcpletType) }], + isError: true, + }; + } + + try { + const args = (request.params.arguments ?? {}) as Record; + const result = await tool.handler(args, authPayload); + const envelope = { + result, + _meta: { + timestamp: new Date().toISOString(), + toolId: toolName, + mcpletType: tool.mcpletType, + visibility: tool.visibility, + }, + }; + return { content: [{ type: 'text', text: JSON.stringify(envelope) }] }; + } catch (err) { + return { + content: [{ type: 'text', text: this.errorEnvelope(toolName, (err as Error).message, 'UNKNOWN_ERROR', tool.mcpletType) }], + isError: true, + }; + } + }); + } + + private errorEnvelope(toolId: string, message: string, code: string, mcpletType: MCPletType = 'read'): string { + return JSON.stringify({ + error: { message, code }, + _meta: { timestamp: new Date().toISOString(), toolId, mcpletType, visibility: ['model'] }, + }); + } +} diff --git a/reference_impl/mcplets/media-pool/email/index.ts b/reference_impl/mcplets/media-pool/email/index.ts new file mode 100644 index 0000000..88699f7 --- /dev/null +++ b/reference_impl/mcplets/media-pool/email/index.ts @@ -0,0 +1,71 @@ +/** + * Email MCPlet + * pool: media-pool | mcpletType: action | visibility: [app] | auth: passkey workflow + * + * visibility: ['app'] means this tool is NOT exposed to the LLM directly. + * It is invoked only through the Host-controlled action-dispatch path + * (Dispatch Agent) after Passkey authentication. + * enforcement: 'workflow' — one Passkey ceremony per Director cycle (contextId), + * not one per individual email send. + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('email-mcplet'); + +server.registerTool({ + name: 'send_email', + description: '指定した宛先にメールを送信します。承認済みキャンペーン通知や予約リマインダーの送信に使用します。', + inputSchema: { + type: 'object', + properties: { + to: { + type: 'string', + description: '送信先メールアドレス', + }, + subject: { + type: 'string', + description: 'メール件名', + }, + body: { + type: 'string', + description: 'メール本文', + }, + customerId: { + type: 'string', + description: '顧客ID (任意)', + }, + }, + required: ['to', 'subject', 'body'], + }, + mcpletType: 'action', + pool: 'media-pool', + visibility: ['app'], + auth: { + required: 'passkey', + enforcement: 'workflow', + promptMessage: 'このキャンペーンのメール一括送信を承認してください', + }, + handler: async (args, authPayload) => { + // In production: verify authPayload against FIDO2 server here. + // For demo: log and proceed if authPayload present. + if (authPayload) { + console.error(`[email-mcplet] Auth verified (challenge: ${authPayload['challenge'] ?? 'n/a'})`); + } + + const res = await fetch(`${MOCK_SERVICE_URL}/email/send`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + to: args['to'], + subject: args['subject'], + body: args['body'], + }), + }); + if (!res.ok) throw new Error(`Email service returned ${res.status}`); + return res.json(); + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/media-pool/site-access/index.ts b/reference_impl/mcplets/media-pool/site-access/index.ts new file mode 100644 index 0000000..c14a92f --- /dev/null +++ b/reference_impl/mcplets/media-pool/site-access/index.ts @@ -0,0 +1,35 @@ +/** + * サイトアクセス MCPlet + * pool: media-pool | mcpletType: read | visibility: [model] + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('site-access-mcplet'); + +server.registerTool({ + name: 'read_site_stats', + description: 'EPARKサイトのアクセス統計を取得します。予約ページの閲覧数やコンバージョン率などを確認できます。', + inputSchema: { + type: 'object', + properties: { + period: { + type: 'string', + enum: ['last_7_days', 'last_30_days', 'today'], + description: '集計期間', + }, + }, + required: [], + }, + mcpletType: 'read', + pool: 'media-pool', + visibility: ['model'], + handler: async (_args) => { + const res = await fetch(`${MOCK_SERVICE_URL}/site/stats`); + if (!res.ok) throw new Error(`Site stats API returned ${res.status}`); + return res.json(); + }, +}); + +await server.listen(); diff --git a/reference_impl/mcplets/media-pool/sns/index.ts b/reference_impl/mcplets/media-pool/sns/index.ts new file mode 100644 index 0000000..3217c01 --- /dev/null +++ b/reference_impl/mcplets/media-pool/sns/index.ts @@ -0,0 +1,60 @@ +/** + * SNS MCPlet + * pool: media-pool | mcpletType: action | visibility: [app] | auth: passkey workflow + */ +import { MCPletServer } from '../../mcplet-server.js'; + +const MOCK_SERVICE_URL = process.env.MOCK_SERVICE_URL ?? 'http://localhost:5100'; + +const server = new MCPletServer('sns-mcplet'); + +server.registerTool({ + name: 'post_sns', + description: 'SNSプラットフォームに投稿します。承認済みキャンペーン告知の拡散に使用します。', + inputSchema: { + type: 'object', + properties: { + platform: { + type: 'string', + enum: ['twitter', 'instagram', 'line'], + description: '投稿するSNSプラットフォーム', + }, + content: { + type: 'string', + description: '投稿内容', + }, + scheduleAt: { + type: 'string', + description: '予約投稿日時 (ISO 8601形式、任意)', + }, + }, + required: ['platform', 'content'], + }, + mcpletType: 'action', + pool: 'media-pool', + visibility: ['app'], + auth: { + required: 'passkey', + enforcement: 'workflow', + promptMessage: 'このキャンペーンのSNS投稿を承認してください', + }, + handler: async (args, authPayload) => { + if (authPayload) { + console.error(`[sns-mcplet] Auth verified (challenge: ${authPayload['challenge'] ?? 'n/a'})`); + } + + const res = await fetch(`${MOCK_SERVICE_URL}/sns/post`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + platform: args['platform'], + content: args['content'], + scheduleAt: args['scheduleAt'], + }), + }); + if (!res.ok) throw new Error(`SNS service returned ${res.status}`); + return res.json(); + }, +}); + +await server.listen(); diff --git a/reference_impl/mock-services/data/customers.json b/reference_impl/mock-services/data/customers.json new file mode 100644 index 0000000..dacd1a0 --- /dev/null +++ b/reference_impl/mock-services/data/customers.json @@ -0,0 +1,42 @@ +[ + { + "customerId": "C001", + "name": "田中 花子", + "email": "hanako.tanaka@example.com", + "cancelTendency": "high", + "cancelTendencyReason": "雨天キャンセル傾向", + "reservations": ["R001", "R003"] + }, + { + "customerId": "C002", + "name": "山田 太郎", + "email": "taro.yamada@example.com", + "cancelTendency": "high", + "cancelTendencyReason": "雨天キャンセル傾向", + "reservations": ["R002"] + }, + { + "customerId": "C003", + "name": "鈴木 一郎", + "email": "ichiro.suzuki@example.com", + "cancelTendency": "high", + "cancelTendencyReason": "雨天キャンセル傾向", + "reservations": ["R004"] + }, + { + "customerId": "C004", + "name": "佐藤 美咲", + "email": "misaki.sato@example.com", + "cancelTendency": "high", + "cancelTendencyReason": "雨天キャンセル傾向", + "reservations": ["R005"] + }, + { + "customerId": "C005", + "name": "伊藤 健", + "email": "ken.ito@example.com", + "cancelTendency": "high", + "cancelTendencyReason": "雨天キャンセル傾向", + "reservations": ["R006"] + } +] diff --git a/reference_impl/mock-services/data/inventory.json b/reference_impl/mock-services/data/inventory.json new file mode 100644 index 0000000..bef5079 --- /dev/null +++ b/reference_impl/mock-services/data/inventory.json @@ -0,0 +1,37 @@ +{ + "items": [ + { + "itemId": "DESSERT_CHOCO", + "name": "チョコレートケーキ", + "category": "dessert", + "stock": 25, + "unit": "個", + "costPerUnit": 350 + }, + { + "itemId": "DESSERT_PUDDING", + "name": "プリン", + "category": "dessert", + "stock": 40, + "unit": "個", + "costPerUnit": 200 + }, + { + "itemId": "DESSERT_TIRAMISU", + "name": "ティラミス", + "category": "dessert", + "stock": 18, + "unit": "個", + "costPerUnit": 420 + }, + { + "itemId": "DRINK_WINE", + "name": "赤ワイン", + "category": "drink", + "stock": 12, + "unit": "本", + "costPerUnit": 1500 + } + ], + "updatedAt": "2026-03-27T06:00:00Z" +} diff --git a/reference_impl/mock-services/data/reservations.json b/reference_impl/mock-services/data/reservations.json new file mode 100644 index 0000000..d77d274 --- /dev/null +++ b/reference_impl/mock-services/data/reservations.json @@ -0,0 +1,62 @@ +[ + { + "reservationId": "R001", + "customerId": "C001", + "customerName": "田中 花子", + "date": "2026-03-28", + "time": "18:00", + "partySize": 2, + "status": "confirmed", + "notes": "" + }, + { + "reservationId": "R002", + "customerId": "C002", + "customerName": "山田 太郎", + "date": "2026-03-28", + "time": "19:00", + "partySize": 4, + "status": "confirmed", + "notes": "" + }, + { + "reservationId": "R003", + "customerId": "C001", + "customerName": "田中 花子", + "date": "2026-03-28", + "time": "19:30", + "partySize": 2, + "status": "confirmed", + "notes": "アレルギー: ナッツ" + }, + { + "reservationId": "R004", + "customerId": "C003", + "customerName": "鈴木 一郎", + "date": "2026-03-28", + "time": "20:00", + "partySize": 3, + "status": "confirmed", + "notes": "" + }, + { + "reservationId": "R005", + "customerId": "C004", + "customerName": "佐藤 美咲", + "date": "2026-03-28", + "time": "18:30", + "partySize": 2, + "status": "confirmed", + "notes": "" + }, + { + "reservationId": "R006", + "customerId": "C005", + "customerName": "伊藤 健", + "date": "2026-03-28", + "time": "21:00", + "partySize": 1, + "status": "confirmed", + "notes": "" + } +] diff --git a/reference_impl/mock-services/data/weather.json b/reference_impl/mock-services/data/weather.json new file mode 100644 index 0000000..36389f7 --- /dev/null +++ b/reference_impl/mock-services/data/weather.json @@ -0,0 +1,16 @@ +{ + "location": "Tokyo", + "forecasts": [ + { + "date": "2026-03-28", + "condition": "rainy", + "conditionJa": "雨", + "tempHigh": 14, + "tempLow": 9, + "precipitationMm": 12, + "precipitationProbability": 90, + "summary": "明日は一日を通して雨が降る見込みです。最高気温14度、傘の持参をお勧めします。" + } + ], + "updatedAt": "2026-03-27T06:00:00Z" +} diff --git a/reference_impl/mock-services/server.ts b/reference_impl/mock-services/server.ts new file mode 100644 index 0000000..a0dcaf1 --- /dev/null +++ b/reference_impl/mock-services/server.ts @@ -0,0 +1,200 @@ +/** + * Mock Service Server — port 5100 + * + * Simulates external/internal enterprise systems for the reference implementation. + * MCPlet handlers call these endpoints; replacing with real services requires only + * updating the mockServiceUrl in reference.yaml. + */ +import http from 'node:http'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const dataDir = path.join(__dirname, 'data'); +const PORT = 5100; + +// ---- Data loaders ---- + +function loadJson(filename: string): T { + return JSON.parse(fs.readFileSync(path.join(dataDir, filename), 'utf-8')) as T; +} + +interface Customer { + customerId: string; + name: string; + email: string; + cancelTendency: string; + cancelTendencyReason: string; + reservations: string[]; +} + +interface Reservation { + reservationId: string; + customerId: string; + customerName: string; + date: string; + time: string; + partySize: number; + status: string; + notes: string; +} + +interface SentEmail { + to: string; + subject: string; + body: string; + sentAt: string; +} + +interface SentPost { + platform: string; + content: string; + postedAt: string; +} + +// In-memory log for mock sends +const sentEmails: SentEmail[] = []; +const sentPosts: SentPost[] = []; + +// ---- Route handlers ---- + +function handleCrmCustomers(url: URL, res: http.ServerResponse): void { + const filter = url.searchParams.get('filter'); + const customers = loadJson('customers.json'); + const result = filter === 'rain_cancel_tendency' + ? customers.filter((c) => c.cancelTendency === 'high') + : customers; + sendJson(res, 200, { customers: result, total: result.length }); +} + +function handleCrmReservations(_url: URL, res: http.ServerResponse): void { + // Fixed mock: return all reservations regardless of date query + const reservations = loadJson('reservations.json'); + sendJson(res, 200, { reservations, total: reservations.length }); +} + +function handleErpInventory(url: URL, res: http.ServerResponse): void { + const item = url.searchParams.get('item'); + const data = loadJson<{ items: Array<{ category: string }> }>('inventory.json'); + const items = item + ? data.items.filter((i) => i.category === item || i.category.includes(item)) + : data.items; + sendJson(res, 200, { items, total: items.length }); +} + +function handleWeatherForecast(_url: URL, res: http.ServerResponse): void { + // Fixed mock: always return rainy forecast regardless of date query + const data = loadJson<{ location: string; forecasts: Array<{ date: string }> }>('weather.json'); + sendJson(res, 200, { location: data.location, forecasts: data.forecasts }); +} + +function handleSiteStats(_url: URL, res: http.ServerResponse): void { + sendJson(res, 200, { + site: 'EPARK', + period: 'last_7_days', + pageViews: 12480, + uniqueVisitors: 3920, + reservationPageViews: 2150, + conversionRate: 0.18, + updatedAt: new Date().toISOString(), + }); +} + +async function handleEmailSend(req: http.IncomingMessage, res: http.ServerResponse): Promise { + const body = await parseJsonBody<{ to: string; subject: string; body: string }>(req); + const entry: SentEmail = { ...body, sentAt: new Date().toISOString() }; + sentEmails.push(entry); + console.log(`[mock-email] Sent to ${body.to}: ${body.subject}`); + sendJson(res, 200, { ok: true, messageId: `mock-${Date.now()}`, sentAt: entry.sentAt }); +} + +async function handleSnsPost(req: http.IncomingMessage, res: http.ServerResponse): Promise { + const body = await parseJsonBody<{ platform: string; content: string }>(req); + const entry: SentPost = { ...body, postedAt: new Date().toISOString() }; + sentPosts.push(entry); + console.log(`[mock-sns] Posted to ${body.platform}: ${body.content.slice(0, 50)}...`); + sendJson(res, 200, { ok: true, postId: `mock-${Date.now()}`, postedAt: entry.postedAt }); +} + +function handleSentEmails(_url: URL, res: http.ServerResponse): void { + sendJson(res, 200, { sentEmails, total: sentEmails.length }); +} + +function handleSentPosts(_url: URL, res: http.ServerResponse): void { + sendJson(res, 200, { sentPosts, total: sentPosts.length }); +} + +// ---- Router ---- + +const server = http.createServer((req, res) => { + const url = new URL(req.url ?? '/', `http://localhost:${PORT}`); + const method = req.method ?? 'GET'; + + try { + if (method === 'GET' && url.pathname === '/crm/customers') { + handleCrmCustomers(url, res); return; + } + if (method === 'GET' && url.pathname === '/crm/reservations') { + handleCrmReservations(url, res); return; + } + if (method === 'GET' && url.pathname === '/erp/inventory') { + handleErpInventory(url, res); return; + } + if (method === 'GET' && url.pathname === '/weather/forecast') { + handleWeatherForecast(url, res); return; + } + if (method === 'GET' && url.pathname === '/site/stats') { + handleSiteStats(url, res); return; + } + if (method === 'POST' && url.pathname === '/email/send') { + void handleEmailSend(req, res); return; + } + if (method === 'POST' && url.pathname === '/sns/post') { + void handleSnsPost(req, res); return; + } + if (method === 'GET' && url.pathname === '/debug/emails') { + handleSentEmails(url, res); return; + } + if (method === 'GET' && url.pathname === '/debug/posts') { + handleSentPosts(url, res); return; + } + + sendJson(res, 404, { error: `Not found: ${method} ${url.pathname}` }); + } catch (err) { + sendJson(res, 500, { error: (err as Error).message }); + } +}); + +server.listen(PORT, () => { + console.log(`[mock-services] Listening on http://localhost:${PORT}`); + console.log('[mock-services] Endpoints:'); + console.log(' GET /crm/customers?filter=rain_cancel_tendency'); + console.log(' GET /crm/reservations?date=YYYY-MM-DD'); + console.log(' GET /erp/inventory?item=dessert'); + console.log(' GET /weather/forecast?date=YYYY-MM-DD'); + console.log(' GET /site/stats'); + console.log(' POST /email/send'); + console.log(' POST /sns/post'); + console.log(' GET /debug/emails (sent email log)'); + console.log(' GET /debug/posts (sent SNS post log)'); +}); + +// ---- Helpers ---- + +function sendJson(res: http.ServerResponse, status: number, body: unknown): void { + res.writeHead(status, { 'Content-Type': 'application/json' }); + res.end(JSON.stringify(body, null, 2)); +} + +function parseJsonBody(req: http.IncomingMessage): Promise { + return new Promise((resolve, reject) => { + let data = ''; + req.on('data', (chunk: Buffer) => { data += chunk.toString(); }); + req.on('end', () => { + try { resolve(JSON.parse(data) as T); } + catch { reject(new Error('Invalid JSON')); } + }); + req.on('error', reject); + }); +} diff --git a/reference_impl/package-lock.json b/reference_impl/package-lock.json new file mode 100644 index 0000000..d146590 --- /dev/null +++ b/reference_impl/package-lock.json @@ -0,0 +1,4866 @@ +{ + "name": "mcplet-a2a-reference", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mcplet-a2a-reference", + "version": "0.1.0", + "dependencies": { + "@modelcontextprotocol/sdk": "^1.10.2", + "js-yaml": "^4.1.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^22.0.0", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.0", + "typescript": "^5.7.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", + "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.0.tgz", + "integrity": "sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", + "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/generator": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz", + "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.0", + "@babel/types": "^7.29.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", + "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", + "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.28.6.tgz", + "integrity": "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", + "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.0.tgz", + "integrity": "sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.0", + "@babel/generator": "^7.29.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.29.0", + "@babel/template": "^7.28.6", + "@babel/types": "^7.29.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", + "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@hono/node-server": { + "version": "1.19.11", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.11.tgz", + "integrity": "sha512-dr8/3zEaB+p0D2n/IUrlPF1HZm586qgJNXK1a9fhg/PzdtkK7Ksd5l312tJX2yBuALqDYBlG20QEbayqPyxn+g==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.28.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.28.0.tgz", + "integrity": "sha512-gmloF+i+flI8ouQK7MWW4mOwuMh4RePBuPFAEPC6+pdqyWOUMDOixb6qZ69owLJpz6XmyllCouc4t8YWO+E2Nw==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.10", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.10.tgz", + "integrity": "sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.15.tgz", + "integrity": "sha512-F0R/h2+dsy5wJAUe3tAU6oqa2qbWY5TpNfL/RGmo1y38hiyO1w3x2jPtt76wmuaJI4DQnOBu21cNXQ2STIUUWg==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.10.11", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.11.tgz", + "integrity": "sha512-DAKrHphkJyiGuau/cFieRYhcTFeK/lBuD++C7cZ6KZHbMhBrisoi+EvhQ5RZrIfV5qwsW8kgQ07JIC+MDJRAhg==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", + "license": "MIT", + "dependencies": { + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001781", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001781.tgz", + "integrity": "sha512-RdwNCyMsNBftLjW6w01z8bKEvT6e/5tpPVEgtn22TiLGlstHOVecsX2KHFkD5e/vRnIE4EGzpuIODb3mtswtkw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", + "license": "MIT", + "engines": { + "node": ">=6.6.0" + } + }, + "node_modules/cors": { + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/dedent": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", + "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.328", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.328.tgz", + "integrity": "sha512-QNQ5l45DzYytThO21403XN3FvK0hOkWDG8viNf6jqS42msJ8I4tGDSpBCgvDRRPnkffafiwAym2X2eHeGD2V0w==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.3.1.tgz", + "integrity": "sha512-D1dKN+cmyPWuvB+G2SREQDzPY1agpBIcTa9sJxOPMCNeH3gwzhqJRDWCXW3gg0y//+LQ/8j52JbMROWyrKdMdw==", + "license": "MIT", + "dependencies": { + "ip-address": "10.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handlebars": { + "version": "4.7.9", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", + "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hono": { + "version": "4.12.9", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.9.tgz", + "integrity": "sha512-wy3T8Zm2bsEvxKZM5w21VdHDDcwVS1yUFFY6i8UobSsKfFceT7TOwhbhfKsDyx7tYQlmRM5FLpIuYvNFyjctiA==", + "license": "MIT", + "engines": { + "node": ">=16.9.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "license": "MIT" + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jose": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.2.2.tgz", + "integrity": "sha512-d7kPDd34KO/YnzaDOlikGpOurfF0ByC2sEV4cANCtdqLlTfBlw2p14O/5d/zv40gJPbIQxfES3nSx1/oYNyuZQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.36", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.36.tgz", + "integrity": "sha512-TdC8FSgHz8Mwtw9g5L4gR/Sh9XhSP/0DEkQxfEFXOpiul5IiHgHan2VhYYb6agDSfp4KuvltmGApc8HMgUrIkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-to-regexp": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.0.tgz", + "integrity": "sha512-PuseHIvAnz3bjrM2rGJtSgo1zjgxapTLZ7x2pjhzWwlp4SJQgK3f3iZIQwkpEnBaKz6seKBADpM4B4ySkuYypg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz", + "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==", + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/semver": { + "version": "7.7.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz", + "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", + "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-to-json-schema": { + "version": "3.25.2", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz", + "integrity": "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25.28 || ^4" + } + } + } +} diff --git a/reference_impl/package.json b/reference_impl/package.json new file mode 100644 index 0000000..6eb1e3f --- /dev/null +++ b/reference_impl/package.json @@ -0,0 +1,33 @@ +{ + "name": "mcplet-a2a-reference", + "version": "0.1.0", + "description": "MCPletA2A reference implementation — cancel-rate reduction scenario", + "type": "module", + "scripts": { + "build": "tsc && cp -r mock-services/data dist/mock-services/data", + "mock": "node dist/mock-services/server.js", + "dev": "tsc --watch", + "test": "jest", + "mcplet:crm": "node dist/mcplets/internal/crm/index.js", + "mcplet:erp": "node dist/mcplets/internal/erp/index.js", + "mcplet:hr": "node dist/mcplets/internal/hr/index.js", + "mcplet:web-access": "node dist/mcplets/info-pool/web-access/index.js", + "mcplet:api-access": "node dist/mcplets/info-pool/api-access/index.js", + "mcplet:site-access": "node dist/mcplets/media-pool/site-access/index.js", + "mcplet:email": "node dist/mcplets/media-pool/email/index.js", + "mcplet:sns": "node dist/mcplets/media-pool/sns/index.js" + }, + "dependencies": { + "@modelcontextprotocol/sdk": "^1.10.2", + "js-yaml": "^4.1.0", + "uuid": "^11.1.0" + }, + "devDependencies": { + "@types/js-yaml": "^4.0.9", + "@types/node": "^22.0.0", + "@types/uuid": "^10.0.0", + "jest": "^29.7.0", + "ts-jest": "^29.2.0", + "typescript": "^5.7.0" + } +} diff --git a/reference_impl/tsconfig.json b/reference_impl/tsconfig.json new file mode 100644 index 0000000..608cec2 --- /dev/null +++ b/reference_impl/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "dist", + "rootDir": ".", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true + }, + "include": ["mcplets/**/*", "agents/**/*", "mock-services/**/*", "config/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/start.sh b/start.sh new file mode 100755 index 0000000..3c5aca1 --- /dev/null +++ b/start.sh @@ -0,0 +1,141 @@ +#!/usr/bin/env bash +# ============================================================================= +# MCPletA2A — start.sh +# Starts: Mock Service (port 5100) + Platform Host (Dashboard :4000, A2A :4001) +# MCPlet servers are spawned automatically by the Host via stdio. +# ============================================================================= +set -euo pipefail + +BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PLATFORM_DIR="$BASE_DIR/platform_impl" +REF_DIR="$BASE_DIR/reference_impl" +PID_DIR="$BASE_DIR/.pids" +LOG_DIR="$BASE_DIR/.logs" + +export REF_IMPL_DIST="$REF_DIR/dist" + +# ---- Colour helpers ---------------------------------------------------------- +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' +info() { echo -e "${CYAN}[start]${RESET} $*"; } +ok() { echo -e "${GREEN}[start]${RESET} $*"; } +warn() { echo -e "${YELLOW}[start]${RESET} $*"; } +die() { echo -e "${RED}[start] ERROR:${RESET} $*" >&2; exit 1; } + +# ---- Pre-flight checks ------------------------------------------------------- +command -v node >/dev/null 2>&1 || die "node is not in PATH" + +[[ -f "$PLATFORM_DIR/dist/index.js" ]] || \ + die "platform_impl not built. Run: cd platform_impl && npm run build" + +[[ -f "$REF_DIR/dist/mock-services/server.js" ]] || \ + die "reference_impl not built. Run: cd reference_impl && npm run build" + +# ---- LLM API key check ------------------------------------------------------- +# Read the provider from reference.yaml (line starting with " provider:") +_llm_provider="$(grep -E '^\s+provider:' "$REF_DIR/config/reference.yaml" | head -1 | awk '{print $2}')" + +case "$_llm_provider" in + openrouter) + if [[ -z "${OPENROUTER_API_KEY:-}" ]]; then + warn "LLM provider is 'openrouter' but OPENROUTER_API_KEY is not set." + warn " → Get a key at https://openrouter.ai/keys" + warn " → Then run: export OPENROUTER_API_KEY=sk-or-..." + warn " LLM calls will fail until the key is set." + fi + ;; + claude|"") + if [[ -z "${ANTHROPIC_API_KEY:-}" ]]; then + warn "LLM provider is 'claude' but ANTHROPIC_API_KEY is not set." + warn " → Get a key at https://console.anthropic.com/settings/keys" + warn " → Then run: export ANTHROPIC_API_KEY=sk-ant-..." + warn " To switch to OpenRouter instead, edit:" + warn " $REF_DIR/config/reference.yaml" + warn " Uncomment the 'provider: openrouter' block and set OPENROUTER_API_KEY." + warn " LLM calls will fail until the key is set." + fi + ;; + *) + warn "Unknown LLM provider '$_llm_provider' in reference.yaml." + warn " Supported values: claude, openrouter" + ;; +esac + +mkdir -p "$PID_DIR" "$LOG_DIR" + +# ---- Check already running --------------------------------------------------- +is_running() { + local pidfile="$PID_DIR/$1.pid" + [[ -f "$pidfile" ]] && kill -0 "$(cat "$pidfile")" 2>/dev/null +} + +if is_running mock-services || is_running platform-host; then + warn "Some services are already running. Run ./stop.sh first." + exit 1 +fi + +# ---- Start Mock Service (port 5100) ----------------------------------------- +info "Starting Mock Service on port 5100 ..." +node "$REF_DIR/dist/mock-services/server.js" \ + >"$LOG_DIR/mock-services.log" 2>&1 & +echo $! > "$PID_DIR/mock-services.pid" + +# Wait until port 5100 is accepting connections (max 10 s) +for i in $(seq 1 20); do + if node -e " + const net = require('net'); + const s = net.createConnection(5100, '127.0.0.1'); + s.on('connect', () => { s.destroy(); process.exit(0); }); + s.on('error', () => { s.destroy(); process.exit(1); }); + " 2>/dev/null; then + ok "Mock Service ready (pid $(cat "$PID_DIR/mock-services.pid"))" + break + fi + sleep 0.5 + if [[ $i -eq 20 ]]; then + die "Mock Service did not start in time. Check $LOG_DIR/mock-services.log" + fi +done + +# ---- Start Platform Host (spawns MCPlet servers internally) ------------------ +info "Starting Platform Host ..." +info " Config : $REF_DIR/config/reference.yaml" +info " Dashboard → http://localhost:4000" +info " A2A ext → http://localhost:4001" + +MCPLET_CONFIG="$REF_DIR/config/reference.yaml" \ + MCPLET_AGENT_MODULE="file://$REF_DIR/dist/agents/register.js" \ + node "$PLATFORM_DIR/dist/index.js" \ + >"$LOG_DIR/platform-host.log" 2>&1 & +echo $! > "$PID_DIR/platform-host.pid" + +# Wait until Dashboard is reachable (max 15 s) +for i in $(seq 1 30); do + if node -e " + const net = require('net'); + const s = net.createConnection(4000, '127.0.0.1'); + s.on('connect', () => { s.destroy(); process.exit(0); }); + s.on('error', () => { s.destroy(); process.exit(1); }); + " 2>/dev/null; then + ok "Platform Host ready (pid $(cat "$PID_DIR/platform-host.pid"))" + break + fi + sleep 0.5 + if [[ $i -eq 30 ]]; then + warn "Platform Host did not expose Dashboard in time." + warn "Check $LOG_DIR/platform-host.log for errors." + fi +done + +# ---- Summary ----------------------------------------------------------------- +echo "" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" +echo -e "${GREEN}${BOLD} MCPletA2A started successfully${RESET}" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" +echo -e " Mock Service → ${CYAN}http://localhost:5100${RESET}" +echo -e " Dashboard → ${CYAN}http://localhost:4000${RESET}" +echo -e " A2A Endpoint → ${CYAN}http://localhost:4001/a2a/task${RESET}" +echo "" +echo -e " Logs : ${LOG_DIR}/" +echo -e " Stop : ${BOLD}./stop.sh${RESET}" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" diff --git a/status.sh b/status.sh new file mode 100755 index 0000000..47f2aab --- /dev/null +++ b/status.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# ============================================================================= +# MCPletA2A — status.sh +# Shows running state of all managed services. +# ============================================================================= +set -uo pipefail + +BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PID_DIR="$BASE_DIR/.pids" +LOG_DIR="$BASE_DIR/.logs" + +GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m' +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' + +check_service() { + local name="$1" + local label="$2" + local url="${3:-}" + local pidfile="$PID_DIR/$name.pid" + + if [[ ! -f "$pidfile" ]]; then + echo -e " ${RED}●${RESET} ${BOLD}$label${RESET} ${RED}(not started)${RESET}" + return + fi + + local pid + pid=$(cat "$pidfile") + + if kill -0 "$pid" 2>/dev/null; then + local url_hint="" + [[ -n "$url" ]] && url_hint=" → ${CYAN}$url${RESET}" + echo -e " ${GREEN}●${RESET} ${BOLD}$label${RESET} pid=${pid}${url_hint}" + else + echo -e " ${YELLOW}●${RESET} ${BOLD}$label${RESET} ${YELLOW}(stale pid $pid — process not found)${RESET}" + fi +} + +tail_log() { + local name="$1" + local logfile="$LOG_DIR/$name.log" + if [[ -f "$logfile" ]]; then + echo -e "\n ${BOLD}Last 5 lines of $name.log:${RESET}" + tail -n 5 "$logfile" | sed 's/^/ /' + fi +} + +echo "" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" +echo -e "${BOLD} MCPletA2A Service Status${RESET}" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" +check_service "mock-services" "Mock Service " "http://localhost:5100" +check_service "platform-host" "Platform Host " "http://localhost:4000 (Dashboard)" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" + +if [[ "${1:-}" == "-l" || "${1:-}" == "--logs" ]]; then + tail_log "mock-services" + tail_log "platform-host" +fi + +echo "" +echo -e " ${CYAN}./start.sh${RESET} start all services" +echo -e " ${CYAN}./stop.sh${RESET} stop all services" +echo -e " ${CYAN}./status.sh -l${RESET} show recent logs" +echo "" diff --git a/stop.sh b/stop.sh new file mode 100755 index 0000000..98cb6de --- /dev/null +++ b/stop.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +# ============================================================================= +# MCPletA2A — stop.sh +# Gracefully stops all managed services (SIGTERM → wait → SIGKILL). +# ============================================================================= +set -uo pipefail + +BASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PID_DIR="$BASE_DIR/.pids" + +GREEN='\033[0;32m'; YELLOW='\033[1;33m'; RED='\033[0;31m' +CYAN='\033[0;36m'; BOLD='\033[1m'; RESET='\033[0m' +info() { echo -e "${CYAN}[stop]${RESET} $*"; } +ok() { echo -e "${GREEN}[stop]${RESET} $*"; } +warn() { echo -e "${YELLOW}[stop]${RESET} $*"; } + +stop_service() { + local name="$1" + local pidfile="$PID_DIR/$name.pid" + + if [[ ! -f "$pidfile" ]]; then + warn "$name: no pid file found (already stopped?)" + return + fi + + local pid + pid=$(cat "$pidfile") + + if ! kill -0 "$pid" 2>/dev/null; then + warn "$name: process $pid is not running (stale pid file removed)" + rm -f "$pidfile" + return + fi + + info "Stopping $name (pid $pid) ..." + kill -TERM "$pid" 2>/dev/null || true + + # Wait up to 5 s for graceful exit + local waited=0 + while kill -0 "$pid" 2>/dev/null && [[ $waited -lt 10 ]]; do + sleep 0.5 + waited=$((waited + 1)) + done + + if kill -0 "$pid" 2>/dev/null; then + warn "$name did not exit gracefully — sending SIGKILL" + kill -KILL "$pid" 2>/dev/null || true + fi + + rm -f "$pidfile" + ok "$name stopped" +} + +if [[ ! -d "$PID_DIR" ]]; then + warn "No .pids directory found — nothing to stop" + exit 0 +fi + +# Stop in reverse start order +stop_service "platform-host" +stop_service "mock-services" + +echo "" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}" +echo -e "${GREEN}${BOLD} MCPletA2A stopped${RESET}" +echo -e "${BOLD}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${RESET}"