From 19bcdb955ae84e26cf63328502451ba1d9bc0233 Mon Sep 17 00:00:00 2001 From: Dalton Cherry Date: Fri, 15 May 2026 11:21:39 -0500 Subject: [PATCH] Add Figma Desktop Bridge plugin WASM plugin that connects to a companion Figma Desktop plugin via WebSocket/HTTP bridge to access the Figma Plugin API. Provides 15 tools for write operations: creating frames, text, rectangles, components, instances, auto layout, fills, strokes, and arbitrary plugin code execution. Requires the Figma Desktop app with a bridge plugin running on port 9223. Co-Authored-By: Claude --- Cargo.lock | 124 ++++++++++ README.md | 2 +- dist/figma_bridge.wasm | Bin 0 -> 172703 bytes manifest.json | 16 +- plugins/figma-bridge/Cargo.toml | 12 + plugins/figma-bridge/src/lib.rs | 384 ++++++++++++++++++++++++++++++ plugins/figma-bridge/src/tools.rs | 180 ++++++++++++++ 7 files changed, 716 insertions(+), 2 deletions(-) create mode 100644 Cargo.lock create mode 100755 dist/figma_bridge.wasm create mode 100644 plugins/figma-bridge/Cargo.toml create mode 100644 plugins/figma-bridge/src/lib.rs create mode 100644 plugins/figma-bridge/src/tools.rs diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..830ca8d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,124 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "figma-bridge-wasm" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", + "switchboard-guest-sdk", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "switchboard-guest-sdk" +version = "0.1.0" +source = "git+https://github.com/daltoniam/switchboard.git#62423750d8f845cca1e14e840a81d0775e094c54" +dependencies = [ + "base64", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/README.md b/README.md index dda39b4..71dafc6 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A home for integrations that make more sense as standalone WASM modules than as | Plugin | Tools | Description | |--------|-------|-------------| -| _none yet_ | | | +| `figma_bridge` | 15 | Figma Desktop Bridge — write to canvas via the Plugin API (create frames, components, auto layout, execute arbitrary plugin code) | Prebuilt binaries live in [`dist/`](dist/) and are referenced by [`manifest.json`](manifest.json). diff --git a/dist/figma_bridge.wasm b/dist/figma_bridge.wasm new file mode 100755 index 0000000000000000000000000000000000000000..494fc0b94e431e7acb49d8306456a635e56971ce GIT binary patch literal 172703 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

4l7NP|WM!8!?K^C-7upU^_mVWaV zxJMtqT644wh|Be%l~R}$j`v8UVN4Z>lF=9*GO{E-#*qG!EGtef?V>bG3@{4?jkW$G zoeDWRMM({=g*rOLGe)PV{J*4A$TsYCG-4S;*N9~u5@6){Vf|rVr+)_lvh|0(?CpPC zf3)NLi2%!x@)H66G!)FNh6J>8%_!t=tU91zFlf0|2U6>=R~---$rxPd><*JSsE!nV zXyX59(P5SGI~PAMI@mIB|A^QaSJNJomLA&Fa6+GG9qOBQ>A}_)#|v1nAI9>F)rM^v z^n?&}Y{8~21J)WG0-?1A5{_GIpmDObhRui`tu;h>G+3;iTo160k^shz9FYeaB?!zx zWoR!&cmYWX0Sr|E0RnK%YK8TH3ISc5`V2TRK+by&Lo*-el=2h#=<* zktthBSBd#JI4E4gRz@DZm5{we8b_RAtiU@I5&lLenTcD)@@|WjO&3WKG+TOSpk}v%$CiU>Nf!fPG>3(&ye!t*7_r0A0QE!T zzzu62^Qn>994H`ot*{2ouzt&Rz(g+-#9Doy>i~mi6InJI$ilxG4c96mf+H(J0^8=Y z^_4J1G7TO|y)s0gET0xK&G11j&^15?G{w3VfrwMH3xUihWRU@dSc*(<)E~|-5z=u< z!`Wq&Fs;V{uCdVpkx<8ey&8~xuEK^xt9UWiAh1!9`2o3BXg%PX;&_KEj&g)4nlV}t z@Qd^)MJoc+>+sByo{>&i<_3g12NIz&gaTAT9j4i^G%64yR&1- zD97o|s6zC|>Qyj`YV~I1X!H^M)RabV#xsrHOfTsuuQzi#3*iTq*oc_k%$5;yG?Mrs z>VwsdkZubToknja-A1c7>)4YmuYe9ztks)gLZlU!MS_@edNUf+>CJ2?|4MCvy#$E< zk&6F9Z>H!Sh(FX}+h%qLDyGAXL|YoYS&I%5Wmwp-+ol?z;xgQ^4APrf2FKWJS{W8} ziZZ6Hyl^IU;wMEJ;pxB+Cwp~>p*2iH8UI>QW<69;l+njeiZa)SMnr0nPt(Au09r+v z2$bfr0u>6piR*qX8h_fqRh&&I%BaX}G1LYTCTpl7VQLg*N*=jiStL*vd9^ zf0r;;z z!E$C>hp^PSqC^~YoQlj$|7u&doTXObz5+U4)HOPGkT^OCk`BM$0hmL%-*W*He&QNv2YE5g=RkpR4V3g&%Z~W1Ps<^s8e*PM2x^1yiqS9{7X_FY7PDsM-D$g+Y4UWTG!b z@KBfdaikGM1-7&q0uNxDj`=;oquZ$peueR97R-3;ii?cKID&0ky~KX@3ZT4PhiTPe%d;-UR+e0-x2j98WnWCVTl64*l>NV9bRm&HADv z2bc-V;Z&CE9}6n^27I2>H3dL9nu3RQ1;H>N5jF%GYA+5{lNo%R(Xbpx4KSd+EGKc@iMjY@ zY=wE8ogFngPH@&0`s1CBf8xvm|iyKbJ(`^p+w(q5B0Lg#TetgOQ}%59qLk#0L)y)9Lgh zR~7;X=NEoa7O&ezN!GM2ruA11LSMtwfcD`Uz$^$E258KT>M*r5X7q|eLX%H|a;ut{ zr_u;TnlmPC*c5Pr5;dt6`WU4A#{FIp z;2oKDW3{C7aa6R7C%GZ%N{_+zY&a^QcMWmBEBG@n5*4uGOr{Z$Ljlyx zFk}-+M*wRwjL*#~_=U4vXa=KsFBvo0l8~wgBofO)zM)kLt${U@IEQ|ejm7^UU*nFX zVt|u%Oo&0pnkJ}Y62qh&papirnn^RsBVQ$SKe9L)4?sf#bHN?*uX>UerZzgDOCbAn=^Q}Nv^Buc2IXXjt zO$8kRGnqL!v=`^5$}+{Oba|3IGew-Rm!E+0iTP@o zSe_}B<%#!J6U$X%MYdY3NERn5vNNSfCI6~mBPy7wP>Utvq*RHLD=bmww-(FQlqJtp z$)z&!UPG}RwXYKI)weHeYA@fD{`0C4DB8|dYKc;<5=+$Ly=LM>zyR2}Bu@ig1;9MT z>QtFH9pgcFdn>UT^n@D;J>%^)qSn&onGBF5MS6BdCLUK(N-|SqV%DE_;I`UPb9u=M zB}0>pU`8J)>Qq#;I8AJ zM4m2_8jAr+GLCo^)tWzL0WXR)8Osbx zl4LS+N=lNcFze#zRHaNJ6^AI2BVQM8l+h z%(FAoG8MU*Vzok%UZLY8rA#WzRLdplDlx%FnN$yudLat7t4V~zoz$~jT3l*ybkBw5aYM49iTRQ($|NX}6IlZI4kDT7m$ zuX0x9XC^skWUFO)&Y6mMHJb(1zpHVsxp?43lKx}!F`!hHvs99(vw@ONGndFh!Jh6H67Rk;O{FAn{w82fCGn=}9M|(tT za)mRS9Oqn#O8!q8En_uK)c%vUv;)qPWXhA$Ah-WXV`YH-ECVtnIr0<`^FL`{M>*L5 zRw0!+XF)WoC5h?(sMUW7HF{wX|Hqg~(>_UEXQ?bp<(w)}r6wvN(H+6m9!{=|Rg{uk z=M07P--0}1lYiKjmTExK|FESpO}lXc`Wdb2$5tO&=}We@P%Ia_> zkx8KOLA~c$WXM%2s-G;ErAxVIR?_S&=-m)K<)1q9s%exU(!-JznVC#2g$CsABo4?_ zWh-S&Zi=)n2|mPd|W^E4#gh4ooFS z!^RHihm>;Mqd?URS%yNHFJ>HoQA2Bm_Pw{gnA<^UG*(rbJS&Svlqg9`Qv(k&F%x?9 zNUab{aum?7vlMDh(Gx3WN!dyj+A{vD_RTA{&okvDKQwaMiU>T7_ck-;ct@!&ZD>r0jgOsZwH%CLFHE<+A@GLep#OPQ8W_rX%MukEjkrmjk+4y0{>rmz^K z&Fu@s5>ORwSg5J8dX+TwlF}8KvM{u&tw;o>DGd!(t?lPD`Xqc{To@3*$;(g1;Nn&C zJ~Al%p!8^zrW)lzFY8ZV)1Oq9E>p7(HCvN%V@cDFg>728$Y>kIm5R^h5;AoZx1rHO zOT*MORB@nMxOZ#d&Xr5msi~|L4%|S@k1P}4^6;jh0|3Z261b1Rj)-uh!YpS2Pi)}2 z`wH`b*Y+^{aE%9NV(XikgsCj6SH2%9CWCdNn@4Z$*s~;LImnVorMO@xo05sC^~qK% zLL~VR>E#EmYo+4Qb#2zE0F$2<7G3@g4Q`0C{1oX5CEdhBUMQ5@Fd_jYHuC8*uwfQ< zx%q5&sH^`@Qy%~lmLfET%7dt_SOG$|ki>HfNjwmx&Q|%+ip7MVMl6zO;ys z#zZEUAE2-c_E$NGiHdL`n*lDGA3VwsLlwT!Ppf-TP0^w-%ct^mSm@^#V+=- zzkJ$-_=N_XCC`&#Gq0=Q?&4w}#Q5k}xy_LKD|ksT=)h%Cg0S!_aK*3=XiQrYu?mJ8 zIo4GyH%#u3jG={-glYtP!q6rT_Qy(?MI)1>JHT4O#-<`tD33_{K-3hI#QGKJt{%UH zoEVkyfDU}!6V`Vajf2S%9f}(3_@=S_UqNZlAy`+(wG6Elo{>dIlCD!aSyj655$rbe$6wYBjbJWX`pZP|7o4f)q4sx;I0V3_ zjDi_35~WfC%p`L~vLv7+$YaKC-TT@Sr`UShMumq2``bF$GErgc+1FNS>*?xXn_}zf z;$WMIzy15iRpc7NzeaVU{<+)#0Rl}S4u&YEiitVZtPIm-lDJ}j8tpcKQ*xmYB+9Y3 z015+{c{qaYGQ~a-!Qu{*97$A?Ql3S!9)yEch}J~R5Ze$zk;ZeZ0eNaCG4`HJE=Z&~ zq;N?gxMZ+jVkO|5CrJvh4IYCi6=+0>=~SevoPO*Aw5EYiYzJeASi%{}@tAr}VAGZ$ zPDxiJ!dA{vhkdGAo#pB5?CRD6rcl^TJX^WBHKXR^NeV(#s(>yS&BdA_M{-^Rj;h?m zkW@r6Dju(4O-o)w=u%RNS|V4)GlL!0J2Zj~s7kAi^LQ>OV~Vc`UsrtH@WoHt=sr;Q zc<%V(hj3UKDu-V)(tRi&Kj5YNP`V|)8ci%)nO>eeF(M}yZf^W5Zbk1DPSznvrUBkPz<1gq(!9q!BVx@M&j=g1`*X$d1C_(8M%)$DzVBr1UB#96iF zk_?&^6{ZDtkksr%Cv>B+cq6a8IV7HIQ56~-{mY3glbtl&3Z3b;_TSWt)G z8g)%k(+MSX1x6+Y z!2%n!$LF^&=c7kG6Mh3DezJ(K51<4!1R|j&-dQ0K=<_Z3JRwh1OITY_2cCJpfgxXD zV#Ieud)We8evVKiFyiYAuL1x-Yd|du4E2o#d>1EyX%&%+u}Ij+$P^*H0{xcALN&dX zh62HKAtI#=s5_yc#GA)IP>&}Z!%q>LJFyZkU;i^p!L%Jr? zhxNGpF5oHR7neL2SGQ*F%{^MQY~|zY=N}O0AhxqJCN|aaXj|O3!`B;MabK~xud%p4 zhV%dG2cZ1J4^ib`e}q4LMD!`wV|OPfr#Pf@fzNPUll6JLs^!v?e@IXHA*}-P?aGy> zG}(*bhJ+JboDj}-XP%zfnYl_ymYsb9r{pArLFrE5wgEiwJa4c_%$uN>z>BL~%&TNA zu4^hzsQbbpp=lGBTTK;PT)!zw9N630K^XnX^;UnO7?5BKv)Q7v7b6U3s_W$F9Cpulv(` zw|ks^D2WsEp7(soFNo)X-XQ@5dIkmpLqj8hv7U**Tx1Dit)y4ERuz6#fwiE9SuMTV zhIJtedWq5mnSwRKb%LFOQo-+nbEfBwE(k6PuJCW^-4;CH{~>xPcrJb^`XKnE_nB|n zxOLmG@NskJ&g(mB($od(w+~&XZ(!u%)wc8N)4z+VRQG7nxl6(F)oXS&zg212h_Q1; zX69Cv>|NbG0|J9PgoR6GBS()Jw|U=zgC)l=^w_+`rj~)Bu}Kwck5-;bmtDGS)MEUE zr3S{W+a}A$O|(+P?|J^BTjI9uZ@zqwik>;k$+@vz%$(x+zb#y{bk+8q2lY)%tJd~x z7tm?(k`pJ34QkZ1ZP>Qm%|D*L_>iLVzn-nhB zZy;(QvNLoy2@|@T4s2mm&DgMd>ws3mBts*YYIwo5jh;=TmZFY&&LU$2BLi=7W09$m zhtN~6rh&-RAR@R$GqYv}PKL(%jfAxg1%;<0E%gnJ>Ny!UsaCU5tt!?=Vd%`?tcHQH zevn~fqihr3woUX~>ly2J(&y`03iV844F$Cm>jW7Z7cTB;8(?CrZ&uk;-&ns&EeDZx z;kGu?DAOP#4w-B16<5pmtuXu~_^kI$_}yq#UjC>t3tYN%9W{DE1J5DjPFl8EPCldh_1>mu6N0!BSaa(fXac_ng1@ z^3~uWqZTgSz30&3(koYkrtdmga;h{qEWAr>&-f8z$F1AEWzW8n!xycpS$FU8?)|s# zg&DnX+%&J7si;*uzW;#LYi`^O-LbQpb)C9_?Zd)}X$BN*I&|**wU@8nDplju*^Qi> zm#o>c=Wyx8n=^Ud)26$Ot9$BuSa`SY28I@vjh&yr$W*lOYUdjem6Cnr=;_}tUH;?S zcb+)jcF;}HAb&#}k-pWymF9&j@WTcJYYA%@@PAFzy}&3n^IE7*h(HuVR}%+OO??w#;YwtMR4II8*hXj} zYzytGsotRPR@DuitsI56=JhNJM~eo{tY%Vm_+&k2=mY}u>PCgTZPliQ7itc))GNGg z^yge*3!{NOsuXTDEWBQ&jnG)XrD33ftzFYh$(7VqT`Ie)Lme_H?V_440Z z3c=g(TT37pHb7vJ?9-;VAx-{lZ5nLMt6VN^gf#7mwE22SlU+%hwm_Qf8rt+?v=>k= zy#i^nZ|FjSalb)i$xFobJ@V?6OMgb1Y$e)!#8g+v$G(xtVQoJ3?NF|K6{L-jE^iC- zLE0DJU)jR6`GA!62vbD)U5 zyvQAytW7$KUA6T$YwBy$+kZ%78_f&-B|He7b;8)}?5TCBO3fv-?L-@Jduna^G&YR& z(T+A<8GF12zijtcaFa)-9Ps7Z5u#n1Q!PHb0)CobZMquL&gIhcasTUn8G>L!rSP42 z7F`bmvmI96c#P5>L1rwkB--ht_Npv|-)|On{!DO>r&_jblR-$j`#* zwFNX0jGR%OMLUrhU8#WIK^N|1*CX2nA4j^l2HL~6jw1>`A&b*b(q#GK48#zM6JJXib%yGu*BtCOO``%l8Nn75GNHT2_uX(b#|0z zCfk#f4(uqQ=m;?)rj!Z_@FaUM`9?W}z^x$1k%SboF=t51QrbbPvNLsX(MbciR>~^F zyURs0fg&=Xy~*;DWQb{(g66dHuLtO{y!^~Wx(4zcj6KCuP8@q}U|d&fyne;Ik+QpS z8F9xiI7B>2%JW&=rMJzfZEy-IlmLo3UW44MS+Ew*A77H!f%ukx-X7^7 ze5oEMp=gRY%YAMtLfmlTBRN^7Jnd%5?9tXJhvs=tk=FJX3mHMY2=L)9CRjLvQxW$IjoGOhfha*eQ{E((q+ z7fA;npOVftfEv(&Hbq6?QIe;ZZ&Zq4S46y~;c!cqJWHklUy_dArTLh2NCTD5dm+wM zWFxdM5uQ$*dmzs)7kYzGI`aONrF4%OB4im^>U?U@QIQGXCOmvHL?n`X67;On9Jt7k zN#)rYL?-1mkO?gfyhc`TSJ*86fU7xLp-l_VCP-GgE^pYDJuin5cA}P>^S4 z;hc}oo1|q=ay6;t=$j7Za5LUVrc`7qba0UeRi={3(#TMkjUXgh8sU$Pg4kA~;|$g- z{9f?ZB0K;SpvYDx5$&k*IiH%Y9(yJQLI{ybN`*@0D3#^V`6MrZ%P3(eP5De>Bk(p99Srn_ORAy)4#1G)k&dP$DhHii4d1_B1Cb_Uk zkPQMSQiy~&Um;_^>`aQ|Oi?HiHzMUY67)_VY{M9Tb-*=A-;x)NYZ$(?=Y%w5wc`=C z0MbKTVOg0F4mNgg(+fmp;Uc^dwr;t&9rTrkN-cvP&vgWg%t&kmw*V zt_bcg@PuU%n|3&QiB%D$;3o&h6|Yus%mIcb2LMr>5A(RQVyL3SQ%~HN$0zCA+7HmpOTZTd2qOp?Lm2BL229IL zkP^)MUv5=l+7EaUx;M4800XqeRhyoUG|e&hdD)J;Ht^=IvE0>r9CsalfV=kkz^;Ww zPCh(*PFG4|*P@Hl*j0A&BwfYv#R6YkALazLpzDIkH8XJazCYV#0j}fg9Nc*USNBG5 z(@gz%g|}MdAMo+x6<-?C#XZN5cO)z&W8Vrtp4WtgdtGn)d5_+dS9?uW|A-fNF5Iix z(SPFkQ2o-Eh5qk4+&(OD+~mJ;&gFc+yvP0%1a=NhMu`KO3*EN7Srr{1DEfA<_vH}* z11r^a{-g2UfO;1ne7fcOCgAbt;#RS3?E@REH5~q8OnjhqrrxGaTPFq1J{o9yckz)x zVZTd{XPy2QI4Jb6QsUdJ{atZ>>BmZ`?QP^;{I*)pZNF}QwI*jzooQdY!|XT11{nk` z>T%$eeUewuA2n*W_!OrMk`&)MnD=&ZQ2vqX?=Gyr78KIIG`8f0Rq)&%elNGA1qPQi zi+;LDzh7{V;*A>`7p)6c9hqP3djEd#IL~8-1A5wYm?<4_$lRt=hrM5~=bVuY>EP0T zN|pB8w|8ipc|ARS~@2WK3{6|dQ_uZ$7Nm-cU&XJcdQ(GuUlK`!H!)L z=DZ5+|FL7nR#E2sYtAA5ulL`(_b4f(>e|<}d)}KKVlz8yQFiUpkO`9HVREG~^zFxX zkA&eZLzN%K-94C?8QT7HEAt&+7lhX6bL4mXT^B>=P4^5`uQUsj&bznb$SB`1ufx|b zYDI?~9)$P25PDh%!cdjvQa;HAc_pP|O^Ju5^eO-^6RO3Y+e&w`# ztc`nQtJT{xl(zE7!?E^87HRV$YhT(Xd$izeWP>ofJ->}Ij9Ml6bM@%eZKF*4cX?** zsEP{jvFc&mhb2)-8!jbgzq=k)C+l#W(e_Hw4MSRO8kO2U+G*af1*?7gNB2K4x#6nd z_0c`ve9WwV?LoAv_tuehCe@007`UO@>#Ln&7F18T_9Aj<%&|IoXIK2OBc@&DrqbhC zuVTzEHTU{sd_764u7`YiZ{*t) zU3b_Qw!Cxpx2{dxi%YH?xzx3}Pf(uKXY<&7c8*UT_wb8-rTnm{p?hBJs&P3M&OWPS zPt;g0-}UfLY`fwr2cIsm?iPNe#@i*MLc6)ucKH~TJE+@$2K`#tRNc~Tu48w-#4As` z4f@j6ufL&f_upDOPo6!pbNA84t+)9(j_y9~!NI5wv-frP5^sLkL-?+H=+e8k?nO;| zxCEb?QtT$_(eJ9yj-Y}mJ-SC$dR+77u^#!Vj%Tut^WwTh+|UpG<{p=EZ%WWDuU>Hn zSI0T7OfHVguDPjYm%?*#l_YocGm4FRuILxqz+dFu^TO2x#~3|z&l8ol7F{Hu7Qw42xeh<~=_ zctDr)wG-Y%&KuQvQDnlp#>1Reh7ALE*m-ub-IXAi7F(3l{Lh2~Ula|`?QbM`^ZB^b z2vrYBUjKHxnje`UxzJ;rgP&)K#MFJm`?E(rONQ}I_bG~VO?R{OQ^m*#D7iL4TkFYSD5XL9V+HBt{#k6Z6|-Ie-{^ShM2s=BO- zDmv`!r7+pk!*48$+7FgJ{ODR$R%5G7k~g5+?z+!qUMAx{TsUi+Yy zfA4#*G07j-?s$GPaes2lIlUfF`}{6>sK4I*{@Wc=&UL82X6zeD%81%eyRGj%HRVZz zC9mq3pGc{kYuM%NaDM8=$;TWFpEOT3^ZeT4m@F+d$p2g7+`98qyPe_QHkt%u~7rahu?q%XJ;6UT_L8fC5#BGdA|NU^wncK%tOfUIZ;{C|| zaC(caAI8@gd`+*fn&sKKo?FI~aNnaVmL+FAxI1x2wdmOyS*KbzAG`7Q4AcE1_phs` zpE*wH*sRX-)|oR>zTAxL&^xnW;OA+7%wCjvQ}U^QJ<-)nhyFXCPrhTR$eEqi#M34~ zF?q25Cd0%&3a?5HdI$7ht2j|DSd-BaUWHQ?79R^rUZxlS-5LeyTBH0@cZ! z?x$Vuc&G+OD@D6zrmIe?58H0OHD4u)%wKW0>jl-&#a*V>dSRlja^&6h-q}9t>V4EP zr_N-n=T86q@xb;g)Jfm>yR9?5t!}eNRd7ALYPQLmh@0nr>yVw2G0{Y}xG;OKVQ$#B z(v8`#j#atyRromj!ncrB1AN6fquUmDtrHcU;~aM6`Tdj;IXfhMdfnW&C#P!v(F>Yh zex1{8w)3c*QoG!&!Ji$Yh4HzK+;+{bk~k@M?SQ8TW_TXS?J@TcckkeDxgYmi);sdd zEpO}VXnW6PDS3-rmTwq7X--~B&kkA5`<=<-zw2?r*Tx`!P&0Kwyj)kp_0{bXdwM-Z}s&5}zdi{PLE!OoZ zXzySn8gjo+&)E0%0v^=tdv%&;^CzVdeb0D}5IhhL=^Hqv>EN6G+xv#J{JhR2?PcG1 z{XTO~4QbHt-LUF`zDr{JeTptk8(}!UU&|&3N>&&j?05K$YHMe+kNrNp8lSu}!nuFz zX*KtzO-$-<>{V~Ae(v=CA*1bk9GQHo|JwI6T79i0956eZH@wZg76XKnc*{Fp&lqs0 zyLX511P z)2^cIgMBH5qy`~MGE%0(p(YiMebNb>RBV0_ZJMZ%=F>MmQKFK0xc{O!w+nPH7r*)k z`lzqzLc70_Ag!rfG5l46oqZOz_^ArKWFj3KMmjktNtELpF1szaXF*tKszRBH%>f;Q zq4$^oTJqc`!n~)(0ULyrYTh;x59=Xq{p6YP6c@~r+5;ilyd)WHS~Nyxmw~B)8$JTd z6&YeOKKWp$3zH4@RoF_B1ro2Zpu-~Ep34zia_lTPyD^#VRIp~!wo8h0Pg!IjjE2vH z_A6=l(jKugYyz~uyUFM5gJjdz?xFrw{H{d1FZ-WOgJo8Y^nBh{^v7%gCR}_ex?>-7 z&wMf3SS(CDj{f`@i-qH?*nMeYvDiM0J8`DllIhxN!8NN(C;gBHDtJZkMJ40f0-ckM zF)GH-FCZ$)%{REc58e6r`$qdJ3b;Vd1_pfl*=M{sEoC!f|QR5-O3 z4b0*%^1B9yQ*K~Lco#qx5J^~y2#5@g2#yF~eXu{esbHz-Sd{PyYab999vBrxC8Hw! zf`HeMfau`R0RQlq=;*G|zEQDV*-)a%$3?v(uAbSj6-n$QmJ~!fe05KgB^h#9pD0sj6?6hGaOTQvyevXv zBWCA7%It~djK5BPWmasht+<@k(8(7DBxVlPN->3!J;V7x6-1bmKWFV^hR$+kQm1h3 zp#=n{AbJE5lTN@~5?oX``NkcA#v576cTT22lq&Z~V^y#C2xj%NA!;qJ8gn+A5`aX9 z!8q50)?%(ba^Msyf!hJz3V9M)12vPPv6rBN?L1giV94%*_aY8&6?4daGN5W?_I7gRGQDkRjKxljm)L#XgzEiZ$8cpXk+3UJsgHKdoLE;S5 z+_1`~oC^%%EYs*xR;~pY?p02q95s|HK=>kaBKHW^Y^N}dNuP{%a8;C_RgLF^j42og{uAc-6!oCku)i*xRKM|6_RCMmt0tuCELmYZWsh@VugB{nC{&Jo1)4!}sz@1}5FzE=Wm;<0GBA0e zbc5Ci#`3J8b7?t6(@9}Qv*d?z^83-*1nR{hV$wZ5#eU^fO5jEXrzc+D2QlOX-6s&ci*9le|M9=YVSYV&40Aju4EYWF+QMpIUUsBk+6Dj4 z?xTGIrY~Ebmo}oZ@nF*nX+AF|blx3xzH>?1^b_^R9WSv;^LYAf>By&BhVI_u(5hXn zCxQhVCNI12+O5jP_k9h*?=BiV^47Mf6KmUDKJoU-QQIEl8m#L2F!lTFaTeYie&0Q1 z#$}K678B;z-M`Jq(6YYc=kMeE+Yi|^a*3OrsqwiLA3uKIP<6(GJL#R;xs5YDTCMe$ zg7K^Bo*r{|VoJf~C0?sLe4h7adSm}}vvYlJmRg;hQTx+j*8SL=k-aK2K6%VZhLO`_|!1l zJK5oFhfP=@dbrp>x0~S3@@`Rg&6ar_*IRJ9YSrF@XU4eN_2_g~*ml@4|L)z)CKR5p zGvjilqWwcBe>2YS`f&5Dk;&i3Suav9ZM8deT4v(i>5kstRdJ`rRXXBW&&&Ap*n(Qa z3sOH7&M=v?(>?h?Kjpmoz2*s8%`Xf)_+;Pry0yZFt@Lm2H|(f5aZ~d8?~Q-6U3Rf* zjVg~mFWsKVoA>=y$4y5UuNt?q_nc)Ly%G+z%T?I+vz)QP`qaU*^+H>2w1_$0bXIgh z@f`lUpk4`q^P`#!_HSAxS*_oO$l{q+1h~r0nud;Q7qIFzQx=j2;do6+_AggNWFK!^)7#uj=1l9<#Eks;nRa!DjrWAUoYoH+>tXc+a>Mprf;%n z=f-7GY1w@Yo>_d(cy&1R)RWtj?Mf=e20uKz>)yNBFB6)L>2Z0-ii?iDrBCO$A9QF{ zxOPM7@~NTuV|Jw+@_C!vzW7@4;FvGP7hgV2unGRS+~M8`f90k*2ZvUB(<*V+mh&y* zR-Qj)dnntkmg`~9K@E=&QC}Q2D9vM%TT=g>(%$dqo?SY0nyXMS`+MB#C%Zy74K<8f z`sM3j!Qg_omy;dmCoVmfa;ERs1_zREDo-cuTWR5i&$ z!w2e@Lv~+|?3~;w>tXl&lcVZROmFNoKIPp_x4_<)(+W37UH$D+t?j(m)Amd|Svs_M zq1~Ai<_jMdzU;r|>)ydjkDOeuUs&m+tt36p#%tZeGoJ>=8;ZLWrsXHqbS-(l_`vM7 zt@YF%E_aWAN!XRUeEgdOvq$P%`G2{(yY;q}RnKpH^~T>ZsA|mTiO&zc9_6TKWj&)q ztx(6R*KM*lzkHq-c)rJ;xTNB|Zs!uu+*{eidb+Xu3-^9Us`Vc6d8qlyKIZd=7EUP+ z^;-R)dEB{5U22>OTzYG}(fkv!34_%mF0Pz6wCkDak2)T0m(_CN?@jej)Q`>`{Cz^{ z^~Qm}=_mCy+~Z&$BQ4nMdw!jD$dT4Hk3G*-_42BFZ&HW3wd1!R6SsZaWO(AxNn>X} zAEfNNaX|E#_05}nPHDN`Z+ZRjnUcAWTpHlsw> z&yMllIrv7;td{LZRW(^1a4u+F#EJ$}b4Kgecz$KfsL^t!|Ra;x{{i=WF)$C)nhTMB;Wq5gU2bW#L1D*W8CM~X= zQLV$c@lI`Xsy?0FVeYqKZlbWUu`{=yJX^D||Mf#(?b{8x{py9c-M-U?lzou>*kH}tk=Z|i;bKQ*LulCJs zeEh%z|7-WREU9Xd@OJ99y&rmdTCT9avB>IbrLF6C{_%42yP$Jb)txOaOt4PA`J~<| zseAWe8>=Zt8}2wYFKv?h)7`wwX6uf9Zv8^Oe^}sF-zCqz!#l-!eKJlHZLsh9pi-wM zR=+LUXnO6z{yP>m-;Z0N-2QmTA1~WaDpp;cbnDHA&K7c6O1)>XTZc!S*;@V2TMkhN z+U}F5x~O85gH_?vMt`pCdAPc-Po2`oVbX~DyViV~ZuoKT#NY1^UX<9sLHf$8t@d=- z68JvgrgBN#si_A#ju^aUtlQ}Aqte2y-VW@yaqbGK%&ndCvP}I2G0FwABttLk`u5Gd zZnctuv<++V0!%`xeXR?WUes+GvJ> z-p4VnbxZC~epI^Sdt_EYaA5AMuV-gje0?Q3Kd;&17tcmL-u&&zps0SC+m9XIJ1*^! z(<14&zDcPz#`0Ys*Q!c>>vQU>mt)&{ofb=~%?>l{vDkF}ZvCxeBNfzzg->CZA*@4T92z4(`((z?iOf2^@FU6(a>g*BX-yCTKUzq z4LjZy#EweYySV9d2dA#j`WN?7zp&oo-7@IvUB+ zUr$V~TIc@7;;9d@Mn!3s<D%Y!$+S5WH#k{s>9DFK>gbv2 z>HCKI=O*+yFP(E~%hJ9Edk*)0II2UxbiMe*VaniD(u=j)TRFzfI$ZM3b6M%EOI~L8 zrk~GuAC#ZBam3jJ`@_aq*8bk%c*3iW$1OdIwzulkwTbfPsc&1K)%iBrZ;{<_+4GHI z)AqM*ylk;opUJ1(9)Gh>wDnRA+iE{N`9!UO@saJi^>40kxU`Xblfv&w^WQfrU3+c6 z!Ldk}eeMb0cOKpJQgD6Jh7n&<`n~dL+0Nn1ot1v)^2955?0x28KX}QkIc6cti#ks3 zc;0nc(d(oMf%gEs3;Mqd=@z!5u_`AnrqT8Zqlbh|ReZ2K|G}V_ z=i@bYn_o1#vtyJ;jPd&sq7nD6uK#Vt+AEKpiXNX(uMB9aI2s<9w))7#ITI`Kj*c>E zeSF7VYyB&Iw)nTO_TG_s%4pZ}YjcK;kG)@2ueN0`W8V{-A1~V<{i(}1$NH5z3<_K} zPb!Ok{pf?^hL0R0vCOeWescy@5e@F}r#w_SPmG+?a9iugyfqO!lf7i=6}W#g0Tg5y`M z1};7GWs~ss@*49S&D*~#^1^~hgMPpH&p00+{4%gv#vdIQO)7GHaI9d+RmaYz-V3u7 zW4GSlI&as_#gW_6EFw;Z9ADq4?h=Dl(@rm05?Fa5PdvamPj#fhiJpUw*qM$_=A9ec zy7Tx?js@=)d~&mJF650+9!qo2|5#_^@onGFcous%4c|F*;KePC=6_qdXIStN%XfD? z-mHD#wza{$qZi*e_CI#n%+EEhxZQ(iB|8wSQp+o1!sPzy;id7*J~WwdYFbjr!t8#h zf;Qd0DxbBz=Iyq-*9<*sBba4-CDMO?s$|BgRox$cUa;S1#rTx-e;(M@&Uc3L&Zk8+ zjMBCz9GX`1T*}dT!%kkaNI0(dXzS)(;-mX^412_juH3S1`}!#jo~5>4zx+{szP-ua zp{6-|Jto(atua<^F8+9G*3xm4vi!Hn+jbvge$Vj3{{0hGTSrg%Lu9_*rBZE^&D*xM z4tkxtYyAEoMbD;xmaMZ|+M(vl^G`Rvu4&@2d3DP=Zjsl;=_Yn}*4`d-An8g;!}zF? zlj|GAjxk@=vfF^5*+a1vv&yr$hFQVWu_M}6 z{rLR(Z-ZAh5V@q5M%8FKw%eBFk4G=O=&0Am_rTKl&91Jpn1*XlhUV)Zuk>bO3#&bC z<72GH7M?b_w|ms39d|Bdnr~?`XI=3@^Es`4D^-3A5x=`==v z_rxJpKUYdQ|MKOX3(vi(AKctm^=x)p!jP#KLIYz$>SQnMcG~XX(5;QygxsFC{HAPT zXm3%ow@Z^`+Rd={{x(*)H1Ph^_?bm{SI6yXc6ygm6gmAyzxR6= zbv~nd;q9L>Zb)+5sjFsAZ=92~bjs2W3-c@U{zm-E*Scww zgO)w+^@`}XrT@&Wqwk8k&+IdD+gRWAt0s<3c%56T%OZW8=kR&!2oea@D%0+b6dQ zSXF0T>7N}2E_zn|M#`HnejOb)oEmuXRMxP`rH>0;zf|e@KHhi17(wW={J{<9w{1PM z`P=trj=A_1SMGW*)5z=?Z}6X+hJF1KHN1M}oMWSc2Hcvk<#+Ym{_ZiQ(gi(pugvM1 z(@?)s$((^rgx@-NOzCv!`PtROroI>1z8$>l`e4t<*4h3itL&cX+dN-6wb#UhjYm$L z!kd|~Z_*%Zi#B>&ve!Ah-(JW&`l@Bp^-7~k8bm$sdqo{lTzi_Z=dmZ%zPvm8xTe)a zsp0*dMQ?X5uC?RM@I{g-oBMaD^Yp%3`surmT$>ui)t)%^`NT=3^ZXK>+`fATZ(Qi% zwmf(1{$b}nZTq&{sQc~EgS#hBd9Y#Gi2T&uP9c|9uJwH1ul9IL<98kTE#_EQT_%**Qsw0uG)kS?`H0=+B9v^Mh~C(tPw6QQ$7qgPIdiqN>XH% zdt!xGzwI7P&GvuY>D%Z2`N?}OgxJVMIpf{DHp$c1=d-aAmD-QsaxiWqIKb z_czPy#19{h!Kv^E!&C7O=_5a+KUGY7&#st`I8ZU&;7x^e;ne9B(&C-FE2Qnxo>xeJ z6ig|f_TJ*Ry?oko(Yc4^(@p*;nourX_(uF-Q@M1p>$3Q}<CicwvYIYkb!ZNk7QfWH8{$!^ zMvFsS+Ah7s=GKAEH;dkJX}7~YtkONFnpB?2(%uDaHdHk@+V|A7y)11xucP>C(2kn> zcfDlkb3^OA8E&>IVn)tXN*DT9sqFeB;?BZ$Rd!OkIOekT*M|3Njt#Hzgwlp9O5=97 zC_TOP_ZJf>egD|}ZmaZ!dW}m~Y(dg{u2+XwH4gigtlcv8KGLW4PR`Cy^myF&l-q!D zNH3_*8+32f>w7f^?TOof-bOkUF1ViQGIxHWbMsp`HnXaQ*yMb`4Z)&0UiC)fe9Q^k zH;n==Oz|_<8)LtQhhLs-x-M&KNZ)gv0$;wq!t=I@&$({e#^Pjy*G+RS4d)%{^;vE_ zd{Gqd`HRhy%vbRG1oRP^Jsz7{_-Mt#mS@fvUb-+nVEjU*&&%FVl9PTL648EWLDMUX z+jmM2TkPG&bV-BDDe;@fkDnnkxKkR@vGjCCsn7en8{d4N=l^VArEvoXEvz@9kNK+) zdk#-YwY~Ufz2D4wHLVfp_h_y6XD=PQxB$Y46u>U3cCep2_M?H1hC#+i=y55x@6vP^9qijXP87H3qK}>J}Aw ztjp%NnO9yiFOl%_FL&VLXP>kkmlHoCKkluur@ih{>*%etoa)|>-d49ps$R+X9vLj+ zxLeFMI;OIZfBtEcXq>@l*P$_kq?E+NGhFjqb>y^z&BiVFC%+i*BlU@oh~ z{epJRcB;dp)_M%jPHAU2X49S))pRed$nZ_;A&w*XM#*pAS+t zyadZ^{{>f_a*6BZmp-mE=R?R zUftV^8LbYwYGnD@#<16ZMAq*Gug*ZBS&2z_^`;|rtlr`F16O*?=QPZw~k8Q zj$@0gU{8HGzKMBg^2lIaMgNH7-Z7QiBT3Wgy}QS;{*MkL7*Ibm;n)3l2`rHZyHd|;};dhKszoygra5->8V`A&7ZG*Wxt zo6%mfajx+W;j>fWnww9%ds~hF)oHAa$dw(}C?KEuCohSR!G+^YN5*O?OUyls{AyI#mDUWlw+8hUY6U zrg7drds}QvcZ6KR$0Ne;o{NkANMXWj7x!|hr{WwL>8dMst!ym$eE*Dr zAUjpe(dvciFIAPo7Ht;x?aH{PYwz5ii|FcH_+Tu+eLNONY?gnPk6Wj<@XjgA=pLPP znRn}#?a~{PubtxK(OD^Pdh*1F2u;(B!JF1rc(UiMa^c;vPtsku3^SWmFjw>I*>=`+ z6A|%SinM%;OT`Rok0}q!-Fhoe3N6SxFta$1yT|(vM^RX7`QGIIW4VjA(zQvFS|i1^ z*T;4a(3Co_NishuPqOgD=yd(tgY7ioZIZ3ZS&-}=5sry zxC;sVw^e$482{1KN$3mb>>I>o%6-_7;pZUqrB16*%g8n55p#wZigvQmtP=gO#=9?>O# z<$z+*ds&AM35`h=kEr4k==7t`^0Mp1`mbUon^3=G^06)VNa`RNp6WN}+sxOBH%qqWa>8)AkPxk7>gcseB?=GB7Z}Zi8abavPjbrnc5id2()dwHh zb#EI~qUEjGm3ZGQojD?LgT{mS=oJEsUzpoy+JhaB$L`$d&PQXj7?I*3y-Mq2gY3M& zz)ranB~l^Ds!En=E7|uDC#=|a3kS|M4x9NcZshJ1W51oa zu^?8A!@^XsP2Vu6B+@M)PTuNLy8?0Mskp-^Gg<}F6~NW&)#Tu!u1YA`DEk7!pGOgxnkpF;oTb_PFg?ByB)giVP<^4 zlHnaTy^EnaM)Hrxc)C~L(c0&6(uVOX-{Ohkp+xoi6*-K_t<@e~R*URG6E|KdTw+rqm$59L4onc{<(YSlB!JD{g|UQHrQCj`#tuMHNB2IKdUY~ zqT3R9^I=+YNO`BzbF!H_zxd5B7vFNQ*-feT6uRk$9h4Lg~iV(i5+@I zxU?C8>`J#5)AKVc>QxGgaV;eLyQqiTspL+_J6jMq^yH~ZM_hF?q}eYk-}T37&9+c| zStVu~wI8jP0fN^A?%L+T3w(bRB%Ak1^FN zo9uc@r&(#T>iu17yHXW7J!dkJQE1lL>rIVD#KpwwYnjrqm5(C>av2U>(M`DVtwSrw zb2hb%7{BIK&`h1#Hx=T{@E46q8D*BI`O_}6-Kv}ICQq@4DP8oo#oJykZ%!IKnel03 z@tMOyCrdexS~9X4UgR2!8?|_2bKzsR{@M@T`=8Y}xdkWfOq0{7?(%vkR7+l=l=vu+ z#L=>If5^G;f+rOoTx$o&G+i~hH|MHi*up!SGU)^2_~;J=hDC8#opfMP(pJtnl*;%j zx0rg{9ub~fojEZ*+|5j`hUv0GTkS2nlP|^JZ0PrF_%fo*0uiX7l9)z!u7(>C3+V_RlF{wM6_KrFLJhjh+j$>AScGlq3 z+?vL5hRv-=GS(%JQ3lL?%R55Wh~DOi~H&6!&zUWRJhYc6rc0w z-ZGxRzwMTgO^k257CE1J_d0I;Kp6WyuYnb-gruU6xR2?E2=MqGxgWR6%O>Dy55M4} zf{BDrahla$BP}_fJ2EYeO&>6)8*!90PbLI}?-);d8+-0Wnq=4cnhfUYl1afvO?tWo z4&Pv}#m?Z#@r=(a#}6O++SL}7%R|3!Cd7Bva2@l5A|)o-_{779uM~bF7jJ0Va4wov z{bs$+8`YuFigTMi^{QNVsn7I8np*~DNA_iZmRJzGYL?sK?7lWHwv3w(@AFu49c_Hz zmVwuOO89$2k`GducDp3(WzVGbTXP_B!b7=w$IKT07pJ)^vsjpqj}P+hx18QZD9Y-y ze#5S|&3tRJa=?bD1G(eAsouV7U&?YlUv1zme|0zYa%g(yjvR}vX|AyYlTUp#m?YXa zS;qPAZs~u1iF2MK)YIrj;0+_&YYD>kH@jz}=ZEc6@`k>JZS*hf64kJFn@iaA+UVYX z2R=(d^=_hh&=~=|n-0H+U&xI;uQjOU^DQPE63CxSCJO{Ty>_{tNMIi4dF8fSCd1Tf z=kCa?X=Ag`tj-o+cdXIhu{TOuX9`y_5f9qXegwqgS9=^PG;LZd;O|&KkYM_%yy@Z zofl#^%+S*Y`?}`^cL|6F4EDz}M{alFTAw{}?ZxHmpAC3wo1T2UYrvx?%(YP0IU$jV zQ<@m@kuVnDYw#HNg2R24)cISit!{6rX^USwKaNgRs#h%HJd)Td>%RL?+)lUS(Q;8E zw>Q_XY5p+NCAW7{#X0p|5Ot39^M3!r7aa5%AN1MV^JVmd_VQSn?TcoNik**S{?N3? zn%JxN88*A2ngxK~atPI~oxs_2*X}9iVd}=9gDt3L}of?(|jq`iI|1Crr(iYVzw9 z^1m#)UQ|~z_#rIH`c^*IYl`Ept~BZceVa?lHHzLF&?~&PW(%V^rZqHXnRfQ=*BVXE zYQ{HIDz+*iRl_ojn;gkZ3w5C`?>Q3-3f`;vZPTS~TyVLzmG{lDK~rAANum5_3ib^z z*)6>r0;J$SUAXa`hq)D;xQ+`c5VcthR8J zvG2hvLy1FlOeZWPn~8f}a9QoF{l|@J8g?D6J48+2=hR)Vshwc&uyQ6qk4f5HXsx&N zmpT3i4`}A6#e*97ZC~Fv$eH~V(NSSzxr$Pm*{am`n9n-hNrlXLkk*CkLS?N-&N_zG z0YQ9z5zp@SD%q4J^K~d6v!V=VN#*-QMRVYrhL7vT2d+ra5twXoDjU1wif??Ju<>bS z$K<#&pT$t+J#5ukf4-bYEaT?yhM4-r>o9r`f;pc_i&byU#13Isrvv{qVJ_=p->Y&t zUYOd`AN$II?n&<{MO~9Ey55jO37L`B3z@FD~eq6kTZEJ6_x7Zni|6%`Z3ixNbMq9jqW zC`D9UOhimn4Bm?ZuNozak;KSi6ftqU2woH~hR5Rxcp{#JC*vu2ae@dzlpsdH69@z% zfkYq^C-af%2xx;^HVByB45Y^=KYJ zb%@Y1%5bg$>j27aLacIW9xXEgv<-Rq3;WgwcHl%53NVXj^>y5kJ_PisQ>c1N36zvakh#+0t5jG z$bpmKEN}*4;65k@RiG0LgVl$bvE4udpfQfXR2N(Xz90^if_5+nsFmTl2T)r)Ol5%q zumyo28B~BTfZ+%;wiyTkec%pazzfg~rUBJaW^64G017}8oCkIQ?ZX?UG2j7s0#v`} zlCi&LP%+u>8Q7%+9QGs2hVpNhQJpmlNRXi@Aa-Oa3TSC*gZ(GLjQuZ3JLvO0h54V@ z<w*zZXG7zs9cuj@a*c+8@O$ zQF8lND^xP!0=&l!MXP_yP(#P>RU1)c5BpF24*LHk=ZF0zUWv*4id>^}3e{$9AdzTv z`L|Q|GxqmqCa#LM&&#$P}hHDfPY;!f6Jm{e@)V2 z$1eXTp!(Z)zZ{sy{>cCStf>oiIp8pUiy8kOF~gYuM7!!v774*eq|Bp01ru^^R_pf39nvVUo89h^eCZPXZ{WChebRfT$mM`(Y zRXtd`g?^-~f8Gm!?&Dwib8LC}w}knhH`|Xp^G726_iaD&>gap;d*mEb{h81Hnay5a zhmPvk%3n{*zf@oN?V|XtA^^Imew3~KQ5qLJ{zv&*Oc{!yn3_P*U8u_Zz5WaKzb1m= zPtoO%71a@}8P`Me2;Ot!OFK%%PBVesqQ+5EXdmF5aYw0zX*OX^v~d^<^(N{vTsQS9 zEDhe8V@UN0XGBY&@`3k7?WR6V(@T4YYKDf3b`@OQQT`Z`Sw zmO^bqyOruZ?i@8AO)8BnHjhikT&Q)iet3~xFpW0NPD~Rgjtj)fXd`hlRPwlKT1+Y` ZybNPNf0;lZ$EBa}0|y9<%uAJl{s&Z!8%O{E literal 0 HcmV?d00001 diff --git a/manifest.json b/manifest.json index db60b1b..947a75e 100644 --- a/manifest.json +++ b/manifest.json @@ -2,5 +2,19 @@ "schema_version": 1, "name": "daltoniam-plugins", "description": "Third-party Switchboard WASM plugins by @daltoniam", - "plugins": [] + "plugins": [ + { + "name": "figma_bridge", + "description": "Figma Desktop Bridge — access the Figma Plugin API for write operations (create frames, components, auto layout, etc.) via a companion plugin running in Figma Desktop.", + "versions": [ + { + "version": "0.1.0", + "sha256": "d9ef1dc78172583a8e254dbb984c099320e87c3ae2c789df89846d21358d0c4d", + "size": 172703, + "released_at": "2025-05-15T00:00:00Z", + "url": "https://raw.githubusercontent.com/daltoniam/switchboard_plugins/main/dist/figma_bridge.wasm" + } + ] + } + ] } diff --git a/plugins/figma-bridge/Cargo.toml b/plugins/figma-bridge/Cargo.toml new file mode 100644 index 0000000..fb4af01 --- /dev/null +++ b/plugins/figma-bridge/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "figma-bridge-wasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +switchboard-guest-sdk = { git = "https://github.com/daltoniam/switchboard.git" } +serde = { version = "1", features = ["derive"] } +serde_json = "1" diff --git a/plugins/figma-bridge/src/lib.rs b/plugins/figma-bridge/src/lib.rs new file mode 100644 index 0000000..26413cf --- /dev/null +++ b/plugins/figma-bridge/src/lib.rs @@ -0,0 +1,384 @@ +mod tools; + +use std::collections::HashMap; +use std::sync::Mutex; +use switchboard_guest_sdk as sdk; + +static CONFIG: Mutex> = Mutex::new(None); + +struct Config { + bridge_url: String, +} + +fn with_config(f: F) -> R +where + F: FnOnce(&Config) -> R, +{ + let guard = CONFIG.lock().unwrap(); + f(guard.as_ref().expect("not configured")) +} + +fn bridge_url() -> String { + with_config(|c| c.bridge_url.clone()) +} + +#[no_mangle] +pub extern "C" fn name() -> u64 { + sdk::leaked_string("figma_bridge") +} + +#[no_mangle] +pub extern "C" fn tools() -> u64 { + let defs = tools::tool_definitions(); + let data = serde_json::to_vec(&defs).unwrap_or_default(); + sdk::leaked_result(&data) +} + +#[no_mangle] +pub extern "C" fn configure(ptr_size: u64) -> u64 { + let input = sdk::read_input(ptr_size); + let creds: HashMap = match serde_json::from_slice(&input) { + Ok(c) => c, + Err(e) => return sdk::leaked_string(&format!("invalid credentials JSON: {e}")), + }; + + let url = creds + .get("bridge_url") + .map(|s| s.trim_end_matches('/').to_string()) + .unwrap_or_else(|| "http://127.0.0.1:9223".into()); + + *CONFIG.lock().unwrap() = Some(Config { bridge_url: url }); + 0 +} + +#[no_mangle] +pub extern "C" fn execute(ptr_size: u64) -> u64 { + let input = sdk::read_input(ptr_size); + let req: sdk::ExecuteRequest = match serde_json::from_slice(&input) { + Ok(r) => r, + Err(e) => { + let r = sdk::err_result(&format!("invalid request: {e}")); + let data = serde_json::to_vec(&r).unwrap_or_default(); + return sdk::leaked_result(&data); + } + }; + + let result = dispatch(&req.tool_name, req.args); + let data = serde_json::to_vec(&result).unwrap_or_default(); + sdk::leaked_result(&data) +} + +#[no_mangle] +pub extern "C" fn healthy() -> i32 { + match bridge_request("status", &serde_json::Value::Null) { + Ok(_) => 1, + Err(_) => 0, + } +} + +#[no_mangle] +pub extern "C" fn metadata() -> u64 { + sdk::leaked_metadata(&sdk::PluginMetadata { + name: "figma_bridge".into(), + version: "0.1.0".into(), + abi_version: 1, + description: "Figma Desktop Bridge — access the Figma Plugin API for write operations (create frames, components, auto layout, etc.) via a companion plugin running in Figma Desktop.".into(), + author: "daltoniam".into(), + homepage: "https://github.com/daltoniam/switchboard_plugins".into(), + license: "MIT".into(), + capabilities: vec!["http".into()], + credential_keys: vec!["bridge_url".into()], + plain_text_keys: vec!["bridge_url".into()], + optional_keys: vec!["bridge_url".into()], + placeholders: HashMap::from([( + "bridge_url".into(), + "http://127.0.0.1:9223 (default — Figma Desktop Bridge port)".into(), + )]), + }) +} + +// ── Dispatch ──────────────────────────────────────────────────────────────── + +type HandlerFn = fn(HashMap) -> sdk::ToolResult; + +fn dispatch(tool_name: &str, args: HashMap) -> sdk::ToolResult { + let handler: Option = match tool_name { + "figma_bridge_status" => Some(handle_status), + "figma_bridge_get_selection" => Some(handle_get_selection), + "figma_bridge_get_page_nodes" => Some(handle_get_page_nodes), + "figma_bridge_create_frame" => Some(handle_create_frame), + "figma_bridge_create_text" => Some(handle_create_text), + "figma_bridge_create_rectangle" => Some(handle_create_rectangle), + "figma_bridge_set_node_property" => Some(handle_set_node_property), + "figma_bridge_delete_node" => Some(handle_delete_node), + "figma_bridge_clone_node" => Some(handle_clone_node), + "figma_bridge_create_component" => Some(handle_create_component), + "figma_bridge_create_instance" => Some(handle_create_instance), + "figma_bridge_set_auto_layout" => Some(handle_set_auto_layout), + "figma_bridge_set_fills" => Some(handle_set_fills), + "figma_bridge_set_strokes" => Some(handle_set_strokes), + "figma_bridge_execute" => Some(handle_execute), + _ => None, + }; + + match handler { + Some(f) => f(args), + None => sdk::err_result(&format!("unknown tool: {tool_name}")), + } +} + +// ── Bridge Communication ──────────────────────────────────────────────────── + +fn bridge_request(command: &str, params: &serde_json::Value) -> Result { + let body = serde_json::json!({ + "command": command, + "params": params + }); + + let req = sdk::HttpRequest { + method: "POST".into(), + url: format!("{}/api/command", bridge_url()), + headers: { + let mut h = HashMap::new(); + h.insert("Content-Type".into(), "application/json".into()); + h + }, + body: body.to_string(), + body_base64: String::new(), + }; + + let resp = sdk::host_http_request(&req)?; + if resp.status >= 400 { + return Err(format!( + "Figma Bridge error ({}): {}", + resp.status, resp.body + )); + } + Ok(resp.body) +} + +// ── Handlers ──────────────────────────────────────────────────────────────── + +fn handle_status(_args: HashMap) -> sdk::ToolResult { + match bridge_request("status", &serde_json::Value::Null) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&format!( + "Bridge not connected: {e}. Ensure the Figma Desktop Bridge plugin is running." + )), + } +} + +fn handle_get_selection(_args: HashMap) -> sdk::ToolResult { + match bridge_request("getSelection", &serde_json::Value::Null) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_get_page_nodes(_args: HashMap) -> sdk::ToolResult { + match bridge_request("getPageNodes", &serde_json::Value::Null) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_create_frame(args: HashMap) -> sdk::ToolResult { + let name = sdk::arg_str(&args, "name"); + if name.is_empty() { + return sdk::err_result("name is required"); + } + let params = serde_json::json!({ + "name": name, + "x": sdk::arg_int(&args, "x").unwrap_or(0), + "y": sdk::arg_int(&args, "y").unwrap_or(0), + "width": sdk::arg_int(&args, "width").unwrap_or(400), + "height": sdk::arg_int(&args, "height").unwrap_or(300), + }); + match bridge_request("createFrame", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_create_text(args: HashMap) -> sdk::ToolResult { + let text = sdk::arg_str(&args, "text"); + if text.is_empty() { + return sdk::err_result("text is required"); + } + let params = serde_json::json!({ + "text": text, + "parentId": sdk::arg_str(&args, "parent_id"), + "x": sdk::arg_int(&args, "x").unwrap_or(0), + "y": sdk::arg_int(&args, "y").unwrap_or(0), + "fontSize": sdk::arg_int(&args, "font_size").unwrap_or(16), + }); + match bridge_request("createText", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_create_rectangle(args: HashMap) -> sdk::ToolResult { + let params = serde_json::json!({ + "name": sdk::arg_str(&args, "name"), + "parentId": sdk::arg_str(&args, "parent_id"), + "x": sdk::arg_int(&args, "x").unwrap_or(0), + "y": sdk::arg_int(&args, "y").unwrap_or(0), + "width": sdk::arg_int(&args, "width").unwrap_or(100), + "height": sdk::arg_int(&args, "height").unwrap_or(100), + "fillColor": sdk::arg_str(&args, "fill_color"), + }); + match bridge_request("createRectangle", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_set_node_property(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + let property = sdk::arg_str(&args, "property"); + let value = sdk::arg_str(&args, "value"); + if node_id.is_empty() || property.is_empty() { + return sdk::err_result("node_id and property are required"); + } + let parsed_value: serde_json::Value = + serde_json::from_str(&value).unwrap_or(serde_json::Value::String(value)); + let params = serde_json::json!({ + "nodeId": node_id, + "property": property, + "value": parsed_value, + }); + match bridge_request("setNodeProperty", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_delete_node(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + if node_id.is_empty() { + return sdk::err_result("node_id is required"); + } + let params = serde_json::json!({ "nodeId": node_id }); + match bridge_request("deleteNode", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_clone_node(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + if node_id.is_empty() { + return sdk::err_result("node_id is required"); + } + let params = serde_json::json!({ "nodeId": node_id }); + match bridge_request("cloneNode", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_create_component(args: HashMap) -> sdk::ToolResult { + let name = sdk::arg_str(&args, "name"); + if name.is_empty() { + return sdk::err_result("name is required"); + } + let params = serde_json::json!({ + "nodeId": sdk::arg_str(&args, "node_id"), + "name": name, + "width": sdk::arg_int(&args, "width").unwrap_or(100), + "height": sdk::arg_int(&args, "height").unwrap_or(100), + }); + match bridge_request("createComponent", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_create_instance(args: HashMap) -> sdk::ToolResult { + let component_id = sdk::arg_str(&args, "component_id"); + if component_id.is_empty() { + return sdk::err_result("component_id is required"); + } + let params = serde_json::json!({ + "componentId": component_id, + "x": sdk::arg_int(&args, "x").unwrap_or(0), + "y": sdk::arg_int(&args, "y").unwrap_or(0), + }); + match bridge_request("createInstance", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_set_auto_layout(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + let direction = sdk::arg_str(&args, "direction"); + if node_id.is_empty() || direction.is_empty() { + return sdk::err_result("node_id and direction are required"); + } + let params = serde_json::json!({ + "nodeId": node_id, + "direction": direction, + "spacing": sdk::arg_int(&args, "spacing").unwrap_or(0), + "padding": sdk::arg_str(&args, "padding"), + "align": sdk::arg_str(&args, "align"), + }); + match bridge_request("setAutoLayout", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_set_fills(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + let fills_str = sdk::arg_str(&args, "fills"); + if node_id.is_empty() || fills_str.is_empty() { + return sdk::err_result("node_id and fills are required"); + } + let fills: serde_json::Value = match serde_json::from_str(&fills_str) { + Ok(v) => v, + Err(e) => return sdk::err_result(&format!("invalid JSON for fills: {e}")), + }; + let params = serde_json::json!({ + "nodeId": node_id, + "fills": fills, + }); + match bridge_request("setFills", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_set_strokes(args: HashMap) -> sdk::ToolResult { + let node_id = sdk::arg_str(&args, "node_id"); + let strokes_str = sdk::arg_str(&args, "strokes"); + if node_id.is_empty() || strokes_str.is_empty() { + return sdk::err_result("node_id and strokes are required"); + } + let strokes: serde_json::Value = match serde_json::from_str(&strokes_str) { + Ok(v) => v, + Err(e) => return sdk::err_result(&format!("invalid JSON for strokes: {e}")), + }; + let params = serde_json::json!({ + "nodeId": node_id, + "strokes": strokes, + "strokeWeight": sdk::arg_int(&args, "stroke_weight"), + }); + match bridge_request("setStrokes", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} + +fn handle_execute(args: HashMap) -> sdk::ToolResult { + let code = sdk::arg_str(&args, "code"); + if code.is_empty() { + return sdk::err_result("code is required"); + } + let params = serde_json::json!({ "code": code }); + match bridge_request("execute", ¶ms) { + Ok(data) => sdk::raw_result(data), + Err(e) => sdk::err_result(&e), + } +} diff --git a/plugins/figma-bridge/src/tools.rs b/plugins/figma-bridge/src/tools.rs new file mode 100644 index 0000000..e7bfbef --- /dev/null +++ b/plugins/figma-bridge/src/tools.rs @@ -0,0 +1,180 @@ +use std::collections::HashMap; +use switchboard_guest_sdk::ToolDefinition; + +pub fn tool_definitions() -> Vec { + vec![ + // ── Connection ────────────────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_status".into(), + description: "Check the connection status to the Figma Desktop Bridge plugin. Start here to verify the bridge is running.".into(), + parameters: HashMap::new(), + required: vec![], + }, + // ── File & Selection ──────────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_get_selection".into(), + description: "Get the currently selected nodes in Figma Desktop (IDs, names, types, properties)".into(), + parameters: HashMap::new(), + required: vec![], + }, + ToolDefinition { + name: "figma_bridge_get_page_nodes".into(), + description: "Get all top-level nodes on the current page".into(), + parameters: HashMap::new(), + required: vec![], + }, + // ── Node Manipulation ─────────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_create_frame".into(), + description: "Create a new frame on the current page".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("name".into(), "Frame name".into()); + m.insert("x".into(), "X position (default 0)".into()); + m.insert("y".into(), "Y position (default 0)".into()); + m.insert("width".into(), "Width in pixels (default 400)".into()); + m.insert("height".into(), "Height in pixels (default 300)".into()); + m + }, + required: vec!["name".into()], + }, + ToolDefinition { + name: "figma_bridge_create_text".into(), + description: "Create a text node on the current page or inside a specified parent".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("text".into(), "Text content".into()); + m.insert("parent_id".into(), "Parent node ID (optional, defaults to current page)".into()); + m.insert("x".into(), "X position (default 0)".into()); + m.insert("y".into(), "Y position (default 0)".into()); + m.insert("font_size".into(), "Font size in pixels (default 16)".into()); + m + }, + required: vec!["text".into()], + }, + ToolDefinition { + name: "figma_bridge_create_rectangle".into(), + description: "Create a rectangle node".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("name".into(), "Node name (default 'Rectangle')".into()); + m.insert("parent_id".into(), "Parent node ID (optional)".into()); + m.insert("x".into(), "X position (default 0)".into()); + m.insert("y".into(), "Y position (default 0)".into()); + m.insert("width".into(), "Width (default 100)".into()); + m.insert("height".into(), "Height (default 100)".into()); + m.insert("fill_color".into(), "Fill color as hex (e.g. #FF5733)".into()); + m + }, + required: vec![], + }, + ToolDefinition { + name: "figma_bridge_set_node_property".into(), + description: "Set a property on an existing node (position, size, name, opacity, fills, etc.)".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Target node ID".into()); + m.insert("property".into(), "Property name (e.g. name, x, y, width, height, opacity, visible)".into()); + m.insert("value".into(), "New value (JSON for complex types, string/number for simple)".into()); + m + }, + required: vec!["node_id".into(), "property".into(), "value".into()], + }, + ToolDefinition { + name: "figma_bridge_delete_node".into(), + description: "Delete a node by ID".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Node ID to delete".into()); + m + }, + required: vec!["node_id".into()], + }, + ToolDefinition { + name: "figma_bridge_clone_node".into(), + description: "Clone/duplicate a node by ID".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Node ID to clone".into()); + m + }, + required: vec!["node_id".into()], + }, + // ── Components & Instances ────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_create_component".into(), + description: "Convert a frame/group into a component, or create a new component".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Existing node ID to convert (optional)".into()); + m.insert("name".into(), "Component name".into()); + m.insert("width".into(), "Width if creating new (default 100)".into()); + m.insert("height".into(), "Height if creating new (default 100)".into()); + m + }, + required: vec!["name".into()], + }, + ToolDefinition { + name: "figma_bridge_create_instance".into(), + description: "Create an instance of a local component by its ID".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("component_id".into(), "Component node ID".into()); + m.insert("x".into(), "X position (default 0)".into()); + m.insert("y".into(), "Y position (default 0)".into()); + m + }, + required: vec!["component_id".into()], + }, + // ── Auto Layout ───────────────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_set_auto_layout".into(), + description: "Apply or modify auto layout on a frame".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Frame node ID".into()); + m.insert("direction".into(), "HORIZONTAL or VERTICAL".into()); + m.insert("spacing".into(), "Item spacing in pixels".into()); + m.insert("padding".into(), "Padding (single number for all sides, or JSON object with top/right/bottom/left)".into()); + m.insert("align".into(), "Primary axis alignment: MIN, CENTER, MAX, SPACE_BETWEEN".into()); + m + }, + required: vec!["node_id".into(), "direction".into()], + }, + // ── Styles & Variables ────────────────────────────────────────── + ToolDefinition { + name: "figma_bridge_set_fills".into(), + description: "Set fill colors on a node".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Target node ID".into()); + m.insert("fills".into(), "JSON array of fill paints (e.g. [{\"type\":\"SOLID\",\"color\":{\"r\":1,\"g\":0,\"b\":0}}])".into()); + m + }, + required: vec!["node_id".into(), "fills".into()], + }, + ToolDefinition { + name: "figma_bridge_set_strokes".into(), + description: "Set stroke colors on a node".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("node_id".into(), "Target node ID".into()); + m.insert("strokes".into(), "JSON array of stroke paints".into()); + m.insert("stroke_weight".into(), "Stroke weight in pixels (optional)".into()); + m + }, + required: vec!["node_id".into(), "strokes".into()], + }, + // ── Execute Raw Plugin Code ───────────────────────────────────── + ToolDefinition { + name: "figma_bridge_execute".into(), + description: "Execute arbitrary Figma Plugin API JavaScript code in the desktop app context. Use for advanced operations not covered by other tools.".into(), + parameters: { + let mut m = HashMap::new(); + m.insert("code".into(), "JavaScript code to execute (has access to the `figma` global object)".into()); + m + }, + required: vec!["code".into()], + }, + ] +}