From 90d834ca517ab741b96a5309176240284d0ae5f3 Mon Sep 17 00:00:00 2001 From: cjsha <36574350+cjsha@users.noreply.github.com> Date: Tue, 20 Aug 2024 21:42:01 -0400 Subject: [PATCH] Refactor template & implement some of jon's requests (#26) * resolve issues 10, 11, & 32, refactor template & misc. - Rewrite ManagedReference.extensions.js after actually learning js - Remove the title in the input/output boxes of the operator diagram ([ ] -> o -> [ ]) - Remove the dataFrame, contextTask, etc. from the operator page - Remove from reference toc - Rewrite the template to accomodate more sensible view data model structure - Filter out a couple files that were causing broken references from OpenEphys.Onix1.Design in filter.yaml - .css instead of javascript to remove whitespace in tables - add image for transfoermer-operator.svg which was originally made for Shawn - add xcf/webp and write text for Bonsai package uninstallation instructions - use mref.ext.js to add code tags to first column in tables contained in remarks for reformatting formats - address PR review from Brandon & edit the device configuration disclaimer - Add PortStatus.bonsai to avoid broken reference in future commit - Point submodule to earlier commit in latest commit that passes linkchecker --- .../install-configure-bonsai.md | 17 +- filter.yml | 6 +- images/bonsai-uninstall-Bonsai.OpenEphys.webp | Bin 0 -> 25336 bytes images/transform-operator.svg | 58 ++ img-src/bonsai-uninstall-Bonsai.OpenEphys.xcf | Bin 0 -> 120855 bytes src/onix-bonsai-onix1 | 2 +- template/ManagedReference.extension.js | 701 +++--------------- template/partials/class.tmpl.partial | 85 +-- template/partials/diagram.tmpl.partial | 78 +- template/partials/enum.tmpl.partial | 10 +- template/partials/propertyTables.tmpl.partial | 38 +- template/public/main.css | 38 + template/toc.extension.js | 7 +- workflows/operators/PortStatus.bonsai | 14 + 14 files changed, 317 insertions(+), 737 deletions(-) create mode 100644 images/bonsai-uninstall-Bonsai.OpenEphys.webp create mode 100644 images/transform-operator.svg create mode 100644 img-src/bonsai-uninstall-Bonsai.OpenEphys.xcf create mode 100644 workflows/operators/PortStatus.bonsai diff --git a/articles/getting-started/install-configure-bonsai.md b/articles/getting-started/install-configure-bonsai.md index 67bba8e..a07f461 100644 --- a/articles/getting-started/install-configure-bonsai.md +++ b/articles/getting-started/install-configure-bonsai.md @@ -9,7 +9,10 @@ To download Bonsai, select between the portable download and the installer downl * The **Portable** download (.zip) installs a sandboxed version of Bonsai. Portable environments enable users to switch between different environments to prevent package conflicts or confusion between similar packages. * To install from the **Portable** download, extract the downloaded file. You can start the portable Bonsai by running the `Bonsai.exe` that is inside the extracted folder. * The **Installer** download (.exe) installs Bonsai and all its dependencies globally. - * To install from the **Installer** download, run the downloaded `Bonsai-X.X.X.exe` file and agree to the involved licenses. You can start the globally installed Bonsai by launching it from the `Bonsai Setup` window after installing or searching for it in your OS's search function, for example. You can create a shortcut such that the portable Bonsai environment is easy and name it such that it is easy to differentiate between different environments. + * To install from the **Installer** download, run the downloaded `Bonsai-X.X.X.exe` file and agree to the involved licenses. You can start the globally installed Bonsai by launching it from the `Bonsai Setup` window after installing or searching for it in your OS's search function, for example. + +> [!TIP] +> When using multiple environments, create and name shortcuts such that different Bonsai environments are easier to find and distinguish. ## Open Bonsai Package Manager The Bonsai package manager can be accessed from Bonsai's landing window or its workflow editor: @@ -73,6 +76,18 @@ It is good practice to periodically check for package updates. To do this, [open ![Bonsai Update All or Just One Screenshot](../../images/bonsai-update.webp){width=650px} +## Uninstall Packages in Bonsai + +Sometimes it is helpful to uninstall packages. [Open the package manager](#open-bonsai-package-manager) and: + +1. Click the `Installed` tab. +1. Set `Package source` to `All`. +1. Leave the search bar blank if you want to see all installed packages.\ + Alternatively, if you want to uninstall a particular package, you may type that package's name in the search bar. +1. Click a package and click `Uninstall` to uninstall a packages. + +![Bonsai Uninstall](../../images/bonsai-uninstall-Bonsai.OpenEphys.webp){width=650px} + ## Next Steps Now that Bonsai has been installed and configured, it is time to start constructing a workflow to capture data from your ONIX system. The following sections give a high-level understanding of how Bonsai is organized, and some of the ONIX-specific concepts that will be useful for learning how to work with the operators. If you are familiar with Bonsai, you might want to skip to the section. diff --git a/filter.yml b/filter.yml index 3d3d6c9..42550fd 100644 --- a/filter.yml +++ b/filter.yml @@ -1,4 +1,8 @@ apiRules: - exclude: hasAttribute: - uid: System.ObsoleteAttribute \ No newline at end of file + uid: System.ObsoleteAttribute +- exclude: + uidRegex: OpenEphys.Onix1.Design.NeuropixelsV2eChannelConfigurationDialog +- exclude: + uidRegex: OpenEphys.Onix1.Design.ChannelConfigurationDialog diff --git a/images/bonsai-uninstall-Bonsai.OpenEphys.webp b/images/bonsai-uninstall-Bonsai.OpenEphys.webp new file mode 100644 index 0000000000000000000000000000000000000000..0fa0b31309f4240545186430a5b336922e52d5bf GIT binary patch literal 25336 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 Al>h($ literal 0 HcmV?d00001 diff --git a/images/transform-operator.svg b/images/transform-operator.svg new file mode 100644 index 0000000..43846fd --- /dev/null +++ b/images/transform-operator.svg @@ -0,0 +1,58 @@ + + diff --git a/img-src/bonsai-uninstall-Bonsai.OpenEphys.xcf b/img-src/bonsai-uninstall-Bonsai.OpenEphys.xcf new file mode 100644 index 0000000000000000000000000000000000000000..8f77c539ffc47a223ff0432387563f58bc36d2a7 GIT binary patch literal 120855 zcmeFa3!GfVb>Myb_G8|9gI<7UgwO*dp=ZwnN$^REL!7X2?D#YJHoFpMTjz*-7jyHe(?Y9^zpzWUu$z3q;>zEB(6)LMJbvgOMi#|h4N9Ctk) z`TI-UWLzM?V=AtE{Szbe#NnTY3*jc=F13CacnKK{3H~;+UUJ7>x7@aQ$!%NjXaVI& zK7YTkZQH$fZmw;+`_4OB7F8~6y=~Lociz3VcA*AKw%&H@Ew#(^zvYXFzV!mp%WL&N ziH@~>;g(HzY`Lv=`7%QHjtkkqlI>gW*j9VTmQA;BZj%&ux3;!z-d3yWOZ>(=o>+K} z+;+=dcikdB;eOh(rK?u2TD^K%@lTq~nO0KUyEbpTrRA1wewx6^HP^@Py0iA4&0E{< zxO>am1>?%Pn_pUOV^K zVt2GI{S9fzrR(q5*7m8*TR(HlU0=9!^W1d}wftLiEuz4lv;!kg;&$kQhXX%l->sI~@`kRXh=B}$> z-f->m#-EYm_ufZ}Pu+g^w!4>Zkg@j}#t^M}LH=*P>kCV_-O<{*^nz7gb8WHDWEhnE z1^?Ov=5`vmKqe4>*PJkL*TLsm^A8QQ&%i5H#c*L($`G9VTesZ1d28*jZ@qi_ z7iu@%{e^pl?s7{U0m`gYxH|D)e;-d~E>7^0L51}LoVg|b%S!x}CH~qHzc3~F$X_+i z_t%v8C*qg#{J%0hLMQoOW&HqWp7<4iz$;7qzGRU+<_I1qe3$%%o+<_kjbnKUD*8&(QG{8cY9aKaP=C;qjC-?#7?3lCfPwuLDJCxtAO`tUc| zmOo{-2~S;O;b$%U69X?gA-BpPML~2l+=lEL7j%sA#yp z-U-&L2Dd)y$TQy%b?a9<>KeB`*WlofI-{$3i1#{8@nJtTpVI#DIu_ie)bBSs`APd+ zJPl5M{%b)z^-kv3&Z^x1#2a;nw`A4G=RS*nwUdq7<41!7qKslWsDhzZ1)ox~qPbQ(eE@3DpOpx%viBE1YaYw7xN^l zU@6`3l^>lLO&G(?XuTN^6q z_WU)>U$;TgO)DIAL$E&Nq)fBG#JM9ct{QHN0nohj>jb*Ey{QrGCqVoAagN?|8uF4$xuXk;K zB(JFISm=OyYU#wkLB|Cggox0&bh!rdH#Dv-LsdUQ6uzz z#S2PpZFEN6?*cqC3=Pgov z!cq0}oP2%s%92N*zBH7tZ@Q8uAm2uvrs6(RQUJ_O(vH?at+vbKujTQ-6+`~7h^ZdG09e3Y(aoEHPY0jZr zU8_MfHET&|lE^xBC2^_Xps{F&#S2#nf{`8+;Pvu75dFH>ZgwgwG zy${q$>%DI=98^s6bvO~7=ZZ_@7Gl$g&WrnHfimG!3${}YT?tr|Q+J76J))irFj{}7f|gLftDh??9@MRIAN>5>PS+#&q@9Vf zi2ZynqV;0YjT8OG?6Qr^E`=c4=UNhkYLrEW$DlsvOf>Ol5C z81Oj*{-XhCrjUzP`tyLWQhOWNJIHh7Y1F0%A8c*-*}2hd_tB(3w<}awD(yRWva?i8 z`hcAg`yX1)!n^Q&AAEnHPWX;GMQzP!ZKCxVcYR^;LT5$Q7S(DDMJ?I@TrD1}YN42m zQdZtTN|uW1`eI6H`KUAY2YJNvXd!Ps+QG zntY&6*UTUNA6F>tRq8&j_3-&Ft&8}5{Kpmksy-j>KKxbxe7yR{k@ex@>weQQ|2Vn* z8m`VBsk{K}wEh;LJ#ukY;GbvlzYT1{$&s(CFIQZF&mP|3Lkq@*a36(3?!SQ#IpFE*6QAxlbIWji*oA<7P3#4!SKc9y1RTB(y{;(g} z?*7pEB_48wQ)u-+{OBKY2%i&>MezE6!XbxLC)hg9F#s0e{981f#5f{(v(?)O*+B<^M|38XN$W12%sN_cTtazZx8$pCpWX5Dm5Jw@^oaGoZU@lw;aJJRdUyYM?ew%(2D^pf*m}c*%pj zsv0hFCQ!b4>MC%kBGo9K4$U^FL%IB)1*V(hp<(}cXy^38`Op~WL!))nNuLm5t5n;m z)JC@PfaOa4FTf|1`WE0`rM_6}jB!?^=1?Z;S9|}8)l#{U>HqnI#|omQ z*ZUDbKMwEG&-wWFK$1%YwHOhvKoHGA$cP}i0z;QvB3M}B7J#3RtK)p54&ikra2{|W zxKcXt3+-iEn1$5koReLy^R86wfu+piWbv9o9rnj7O0F5qL86pgGq|GUngRLNFErN- z#Jj*=Gnj9$8Pt_rGnmT-gEEd=%{7C0#cKwVaFG#O3q_hWm`p{~k)Iq=H(fUFfbH_q z1GdZk1GYKlfKAt?Y_+aY$t{K2!Yzd>&b_5T^-6CkP`$z}1*#^u6aaEd0U);&7T8+~ zR8rqks2g`n0kLduDNs{;OJQEgEro^lmI8UnEd_wwQUJ)w9Y9X*C_tawT{iCI?(*|a z?x?ysxtlZY$fkW zg|*(jb@Of92j9|yE_P*WtNb_tZEV&1*T#NXl8znZ``axd#g;b||E*ZH>KxrGI$k$h zvHX4OUMuBiEdHNA_^ilVsdoW3(vKs!@{@jo_P|Ssrz>%DIq0h6s7_oh7v<(4&O`*t zMY$_*a#0QmU|~>Sn7a&I5H}mVfg&=4Y8Ebxn+e{)$?8(aIML_ko#Wcw2sb`DjDw>w zPGi;0%;c}jN#9&Kq7@HfjR-mK!^csr9QoBc89A<%W4}4hus*Vtvp@WDY%5pOZbtIR z*{$QqG2rFS5Jb1)x1@9ZKjVrwZ!_e58L!QELBy)zx`n*!&fK0Aa^DH$wE^Z~E{PHvDM||D%EO zETqNX^#2(Anl%QlZME+!dkoz06$}5-z>Nni?6vT?g|gY^@7L@&`L!uF zJlDb%7OuDO(-z)p;Z_TGSol>7zir{e79Oy$*TUl#CJg+9YvB|N=UTYJ!u1w@+QM5c z+-l(t3%_dNw=I0w!UGoeT6o;Tgn_^AS~$hRxfZUlaJ_|}w(wR9w_3Qv!mnERZ3`c^ z@PLKA79O`SVc?Cfg;Ok?YvBqD*IW2$3vab>tA#r({HlfDw(wyK4_Mf1;c*KS2L6U? z;S>w!TDZc(^%j2G!doreYT*tGziQ#PEqvI*0~YpLc-+E-fuD3OoMPcz3s+dU-oj5? zc&mk5E!<(@S1tUug%4YJz`|Y&k6V~9@Hbrxr&u`G!W9NOTzvo4k0<_j{B%VBtYMP0 zKR=!*TsQNtoqbU7|F|Dde7HXXk^cB7yK_&6KfDXNA70MVz8_xh$h*Qd-cr9V^&)XU zgYLt*+$$FvKct*(T|dO!-_IQRV6L!!Fu4fdA52b_Y(0MQOP(K0F1l792tVic>&N*H z=7)55^dd4uTCP-%1eUR?|Dtyt&rPpy2!41u%j)vs<$mti`nZM9U3))n{GZG3uj=#h z()G^mzmHq^SL5yDHQpRngO9QM`ENEB?4@Emp1l6(AEzc1Q11Z|sR!rOmp;60Yd*lZL2qnix8&l-_; z**EZf%kuL#*7)_0_Ek>%CmQ;HK4#&lfd~G@z#sm)fd^kS@W>|(Ja(gj{RTLL|7bje zKeq541JBs@I#X-I*4Tc=zOm$tKGATTq`?P*pV4%Is>ckhdBDI)e_`MyoHz0pxa2Ae zS6ldN7Jk;k%@%IA@J|iA%+xQiOuvH439OQXG4fk|w}FlF#wWsS_gHA^6Ht=g^d<4FBtqK3-N&~<70}Fp>VV{L|+d(wt&y`C#G;pc3PzlD z)!P?u%f!BP&pr2k@5lYClYzt-{%^j~n9L^bx#wGJlDX~ozPTou-~RozJbuh$TmRam z+J+~wZ4KmV+jU8oXL(Z9xz4O)ZohM=DjC=qOy&|TV8`kXB_GULTs!f`_O*grHYJ|jG(0SlX+;tvj*=_IT zS>l9VqXtc}oqCJaBgUwxj@O2X#ZFahv9jD79*ew5h9H-gyKy^&82_@I# z&0e&_>uC0R9IvCpgCyDmd9;fF-Wp5#md>;*+5=ATUCmt`Q7`IsIL)AfFy~Va2xUh{ zfzpdM_cV7jyWUub(-rNSY%@Gj$k3GSHAlTJxNYw6+>S9AEtV~8z9oEV?s<~Jb3Csn z>O@N`^j@0M(3EyV(O;Z?X+8bE|I&$Msv>z!N+#g9-gJ|pRD@9A9`&toGN}DB7bk&Z zHcm<|2D~&OxippEc0z#KHW{4SHU$FzX(nYPIW?7gjA@w)Yz(FH#aS6i)}@%2j|EeC ze_B4au`F2&l8Kqh?XeRx)v_m*Dw&v%rBeRHOffMbf6Rfr?lFI2rc#d;CT42SM$$)8 zSx3_jZ+wj09@7)^l%6uFojX&>WXqmIbtx!Pdz{DIl%AM`LKLLnk5okQXbUD)DyXG} znVhLii$p=|rp)9_r3xjbHtwlQ9cq)d9E6Qf=X6St=kMqJ3_1iT0JJTuw#UW+XqIo)6(mT`oVmU<9f>RgU3v44|82l1_|o_9n5k)KYGkumwbcHTgU({512qqVW+Dn z3OR|GT0K#p@-4}whYZ2VBtvvCf4e%oXtblJC*&wA6e>N<&B1T(7gQH^rIY-&_-CYQMfFp5OkxwLD(rvF+`(akXt-i7Sum6*ivR=Nznx2R4M_ z`Ayr(<70IP3?s$AR>+8Pw!Mgh$XJ0(d zG(N~WbU%n{a@glUUbhc&y}rid`0q15`k)iP z|9&@~+O+#%9ZBlqyPbV*Ty0`~B^06{1$U$(iib@VuRAEIGMfYqof{w8;2hj^e>`3& zCB9*IU0mqTPytFY97zedU_8BPH+<|alJ9nQYjQn%59<03kkBy2o@4_#IGc*}afxZ0 z84r3Ban*6vHZiWevUu35!BxidUfYDY>qRW0A|7B-t%1~FB3`-1_%v?3%yZ+_9zEf; zm6209i9?XP@d_KE+9Ke}z*T|^#Va93F4!!~<5h&Kpfxx*zMKMGQUv3x@P&cpULbx2 zFjBI<`y=nYk5y)A2i?+qjh#57GFLk6vX3l~U{|w0`LhyqJ5Dr5o0%TXGO?H{{AcF$ z$c$;8X!DU=kF!=sdzgjHL7CIC+C$sXER(InssxqZTe`?*7Jpg)MIk^v=xQdROkLLb zf|wW(N@j0?l0?jZ*7+_NYA#IvLWZVn7I|2JPZ1h|DwZv5z6G07u*`RnOrpAo&eB6V zze4Z5LH#Zm4>`+Lv$tK@h8-tSo{T0clB>0=0!~RTO-xQM(QayTL4rY>s7hXvP><3v zb=8T$jlCu({k8VgLT3V_!GFO*KM3S=&vbWA4Jyb>1;*DshyB%kDBH=niEr|sF zmb%^qS%wlLl1c9dVzR{aA`5zV>`3fzdUrc0!I_QwlTJ(G(YjC~Uf0{}^pdu>m!ckR z37Vod>FocZ-|I)%EVC522CzNP#vgn8@we z06I`NAZj}bH~MrU;UsoIL!upI1ZXKsq&fFFZ{B1kTTumStr5%b_31B_D)&}@u;YyDc459 z{E##gqGbm;R3)nt%2@!cNaR~KETs3Ow-x~xCql`}L@;?Zuo}1^5l+_Nt}4JtvLR8H ztWVS=Cno~Q%Ms#RyFv+fS6(NbFBSJOh%DY*bCRIn6(4ig39 zqfJhec7&+TXmCdQ4BlRA8rQgY#0Ok8Mn)n1bUGhw2Q% zLl2bchyJ<8L5oCn9cn>+l!0|9MOLBIh-7eRBQaTG*x9DpU#50ChxRc2QW=y`;+CxJtIM18M2v`0@r zT@NYHMg>#3of}CSs2djL9JN}~rk&JIXh^h^i~ucVsr+LbgQ<)~!^FEg>){N2RBcOrfJqOriH2 z^R7@bSGpNtPN$5tZr3@>SUcLJWWXKOPg_77G?d*<%F*MNDI|oDYC5JBafX+EjV7^b zYU(@+kbKBa{)L=TvH)R7-!71(TZiov_{BO^org$iET|B6r_#5NlM18zWyLRVEG}(D^wNKBk zc;No94v+5J5RY%#glb!gI9O*89(o$H3lhD!iRwDE3H1(T4#kkHLh%vF;NS*gvc#a* zrqM3r_d5q=af@d*?29{_;`{KTcB0gh_Mqs6`!)sRy6g@22Ss%z%7q76+~Qf{SrT$2 zbw%}!-%sG+Zqcgi4w}VH*Fy@lQNeibeipYlvrBYlv|UM?Mn8szMCiL&z^1Zze&2>* zJY&%?@$UU~a22oHhxWV)T~{Z3R}^b>)`Oz>3dhdDh)Ef^e?;(>T~Ffcq(00pQ|4K; zTv^->(gwPfWO1X8rd%6E%MD30vAErj0yI6YoOvjl)8aXA(}sB{rITsTe4S^!A)x59 zVf5ONcO|NC2!*#izQ7Bkl~%^DB3uDnjsAKg?lP^dhERwj@fpOux49bVoT`GI6)J#} zX&UIP#6^B4&h0$YDie}{+te)sm}%NXs+0_4mJ1ooHcPiNrB{>gR@K?s*~t$^I#V)j zIy+fjSY=GX!Oj2$Cy$aHF~l+>!<{T>O*%A=DxlKcO=QJ{KB^*=&5u`f@^M))0a<|| zf}Pe7Wy);SW%``iGKKe}-Eb{+fKXAP(kfhh{)xhQeOr6*hD5*_d^C~R;5a)(bwtAI z!0xLP@1h0@ZUbNkQIGC!Sqyc0Lt+C7h}^)>Pj>V=I~FHW5<=w?@Msvt%^`iNWdo|H zNxuPIYj?|{1ezl`GDUU9jG11B+X{(Wo5(x68xup@I(!d7F+>oWX%Z(O6ol+n(EfvB=ab!vHa4Q`N4sVi zLKJ^7_~}@&Pc*yEm{4MC40PnMI?nV09j zG72Y&Y)-Iu${uE>Y`&te%jQHFmt7S5C7wRr?e!EFTWBaqj&!Tem~K798off|ScaWFjVYzqY`Qfi-OBH_aCB-dwTmiEwlOKC1LPGaWKttfVyD7{Iek_sAtn3fFLDX}KmIDF(n zHbCA?O*tL(K1Vz83ywa<-4%F^Qd69FsDmGVKB_-3uBIn$&XgkJ8@?gII&ECaiv5V1|8a{z>w>4qsQQtLMT)E-PE9?3+Ba+AY#htnFA|p zankojL^mZu@y0~>f==SrB~*NN!i}%Nt;OFS`2Tncw%vI!5iq_$oen>lXfMA(##GsT zDdVe5tYU+@I$55GT33?{C9cF@lPpWr5?6)4HhIN4ZZTGg+3ZaxvY!<=DKSaI$%%={ zYjL6Y)jT8dh4wjtS5ije4Fy*guTNCOS0`r1uPTgg8P&cM?o9pNcq9>JfL6p+;u;MD ziN)Zsu@&GF6vxuAAAhx_Ulgy<@jk2}?M#b%FaAaG$^<65gydI_!g@7IYB^;}+8Neg zP5gB7#3+~$|0VHiYAbw(@Uy?iFKI4`PoUR|ehhWsg(jaMNl>%pl5G`!Q>^hGlFihq6r|2edMlh4`1kNUA0Bceq4c*iP zjSm24rLIiQwyr8A=Mz_QDp5v$SK$OM;{2%`$UsU37*?E8BvuyuQBGHypjg8R21mo> zpfGTS64!D%T%L?1mL!9iKgtt}lT!+A5^*z=#i78kJ+Efvsmh^HYW`3eFp|1T!?M)8 zp@}IqQ~{iIL03KGrlt{BMcS#r%Av4^;h{28XJFvr~bg8X#>p&SAO%gW)Ds zMt6)*BG(GI~HzZ`!#x^)fy8t+nVaQ6LSbZp-*<@tUo>tgbPH zy&32Ab#EZVn)yRj>EKW~ureJ27JIPW zea2JqwX}Q_EmnvBQd(H-@E3wL#7`t{3ebg4to#xd+ERZ7;RzNm{u-vyEZ>8y%^yPM8fUmzs_>92KjLv zvZD#PA<%aVIFFo6*g!YAknkjZb{Rm{ggCVfAZxYPc$W_3%{u<6U65COvz25_AHu zEVwF0SIuxOE|jhso|6vhyu$cv$*Tev(fGjdWDV8u#Po#WYts{l8HvCO=oS9*;c)2) ziQGtUw>x9 ztB}G-y@G#ss)jUW$;(nzv~pSU@>HdUSCGGi=aA>W1#4L`CQ{~H+yvY_ob=XJ^o+py z@Gud-4+Ss1dX=UVyo9CKgBmWvFDr}bb?H?%xdz_X;uhJyoikjO2@ls~t^k$|S7+u7 zS8BLmH~_54%pO*mDZ>*pvxeQwq~S?AJQ=uTxI9DeWUd*mAbl`%HR%Li13m)04!3}` zlcAYU+6luE9iA{;mZ`@tE(+~xT$K3ha81xMsxs|?7l%vc_rxd1DNyafCn>3sQX1f} zUOUEJCNR7Nyl}M`CtO`qfG)XKfe&aXaaU$4bWQ6rmB8}h*>D)r@#VvpWf*^iYY5kn zE=+g=c~xghxC(y9t8m(@%i(Pb?OH+K1!?!o>EjBn; zO(_+mnNONZoDUfXBT?M4OwCB3&`%X@tGBf~&wGKhYrNpuCNF%p5!Zx&4Y*Hv`BpdV z0 zLGsiA%aJIvb*~no!HX^#LMjNYjI^MZ5?mR&O>=)+bt%q$G2EZ;bq#J7wt)T!ws}+} z#DWc=B_Uh5vgf=l_g0(;IUdAC;&CW~%R*n?mm5eNRIyZ7Y26pLN%W#0PH!}s2E&zHVb>x~`zCZ4%o?wi~1;d$)d?N@sFhvo62Jl@(q z&r{pPm3#Tx?=cg;S2tOQa^IW&y`U#g30HU-e4fVx1#BC)8SwFcDuF65`@QMYzc+2X zx0Ix9eDbz(oo^xcwlXhwwoVsbOJPK-v$KG(^)YcyTe11enABCt%!!x2ue+cOjie?y z_U5vrbc+Cxcyhdl|>iwO!tiLR0?E;&P#2Ri;trq zK~<7E1YM9KvfVRg{GjR_M0YibgrYJv3jGgebPGoTuE*fmBXY%MLq?E+%*NCgJ1e9=G{wV2~Sq_$J^h$2S{^RHk8o zGE|$~1{C3j1k`?!ZE)E(2fCn!hRKQ0i5B%y7(}H5H(7^r`)BMAX5=a1icAKdeoP@)nHeR> z|EUD3GTHqzX6&Cf-djr2Ha>YvX@oo>a5H%&S@-QseIKAw{+DROkjv+1ZyhFk_2;>22$s8-FO zVdRV)+Hsz)O0K5_%`F&72O~qR-A!^+gtIl9?xZeI&gRJ7JUivCid z=2YK3DJ0YvSGb9y5q!**x(&gMN!MMPuBqEHs^dt~$!Vjx!4g!SKDFnV-Edl3!-H}> zsITYfgmU(-58&lCi{d(t?gh%%G`4LPOV#;olrDc<;KJQn=yy93&K)8b3YU9)l#&9> zbFQQ4BkoUBY2;jIL@q_pGvmUJQiQ))?#*?EO?`?|=w`RG_$$Y^(_`_$OdG@*Bvw`Qvo`2!s+0U10*1T?~6Cy5nbPEsNR4w9U zmcDcFxtCvi>B-2`qt86|!YloYBR1<+8ANimL!Q#$5oh@8Z$I~wOn$WQiL$4&&%N;W z*DNh3)FreIv|(qg{JBFfBwdwFKmF8!@Y7?@Jb&o9^01$`WkjbEM#9d}^g}PbkWqOx z`s|aD17lA=*K=rA*ymenDOa_G73mnVpMI$4skfPxZ$D9fAp7h~y_e0M8d?`pGArc4JZy>I?TkIH4l5M{ zJgz}8qEiiAID!;~tVn1J$R3WxC^WM-=H~A{^aRXegAcd4UPVz zI+g3acScNg!ty|8jgNn3=%**%{9`wk|4;WtcI5B7w=y=`38Q-le2SrOj(X~!W3dOG zJU$qCH#>OziT}4e#wUSYI50H9Sn69(e&3uaV<#Mcy9kKbbuKMd4Yb%>C-H5 zt)!HpD;bWBLH+t!q^bA%@wY<918-&D9vt{D^norry<_0?o5xNkPQU(!`)2x$*I$3* z&Ev=4IVJHQxX9~7(QCazWsyy-l?8z(w{1H+FV(tEpf#ZKa%E8Fgh)e)>~5WHq+!0b z+lV`n1}2$IVo}-jyyYRwHtSTUjIU1aNu^MVq&VnB{)jYyi!%rU5gpy;-mku?#fyJQ zBnlUzM>20hXbKxizc9Ih1(Dp_O6z-D`qGx`7d1*z5V)NIt+M#Z^qnl5j2Vm4DVm~` zr6v4mYqv?2Yn8&@EEHxLlv&)VuXgEsT`v4dBPBbjq+!w#iEJzO4&u$oHl0oy!?cLo zdD>hIGi`y4hM?OhqSsKNh;DHab4C9LD&_jLl+(|;KGlz~>aVt;Oux$X9aHL9RVkt` zq545ENbCBBEk$2H%3bD|q}F)JCq5`i2Nk)f{$mDzTIl;SDxner1~t$rObpZ)jyWd8 zHaAIHC?z*2We-!fpVw;5Tj?{{m+K!ovsB~VzR}m!m^%IHj6OBUik+BX(PRDU>_~iO z-{>Iu4-VE?v^oOOn{HpWKR(3a;8=Pn-v3&;q3TZDWrv2+ zsZ@D7JDknE7Vb;yJQIV1eSN{fKwn@mr`t6m{g4{U=5y&(WXMhD)!UZ#Sf)rD&^3zm zWfS?t7))l9x=;Ak z)ZQ@iEE7*+)4+x@G@6`gOC3&*#?KCAhP(v7dc@^YBZ--Paw&w@cX`)8&>pB_W^;GF zRsYIixhNa@hYv;Hd=+qpWb34-ifs8#8*NHsw0ee~`zr-VB{#kCGEXM8+=OmL5gaxcP2-i)pcx@8a{TIG7Q0s2rs*QdYQXI8 zECyX(e#Fq(IfELcsevWrqG8jZmIM}KE_^#pS4-`=rQX`T%(jEm)E=l)G?U9s8h&el z@+e|zAsVD&SCK)}5?R_5b#g|rWJfl`k=+j}TaKsfl_9Ot2`CsL0}Aa*wqIrhtLvH-l#|?g=Hm?^ds{IRa*Fy;xa(J zZwn)8jTh|}Y46Y(=tHuJvBl{MBu(iS%k|sRMEZ6;Tf|O;r6j6$-trqjkeWvs0TL%U za5GNU6>3UXi2e+oEgePvQsf#3v)JYQW%xZmON!oEFOyGefpBvj|<5hW9>7P zHtjnlY5gc(!_!JprD=msiZ1DdLVoPv7c7YdBSrX8Qd#0lxF(d6EfrHi_6`K;H+71% zGFv3AA49|N>j+6IjU`b_r1{r4d3AJ}ybVx`6Z9CU#L7TlAVlnsK#INvDn*udLq>UO z!0a*%M%HlM3Z1i*G&DuYVjpq_%qGSlMChKCbs2`NMjj6pCfk<0K_rFgC^$YfuciG!TrvvsX4WdxbLyWD})#LPD5U zkFx_f+!^aU98@{*sLqFB>v2~Xl%^oN6$-12?+wPzD$1rbwnOX8xzt+^uvd0ch;&cX7R6VZi-?=xWxvMd)Mzc`o>|R~};lpO% zr5?YU;@0Aj9YPn9hqR&EJ59Vnoj8`2-3bc4x~xDnU3@j9%ssB#n@yx8P73j1yHkRd z6j6s2#UG|{SEbol*hoo0*XZ1B;vo`C`^esjrq&_ZeX&nV$p*>aR|R831CP@MbP}c6 z#3!ZX;^s(4NwIqmyD>7B9Su&%QNRzY7zLRiRdHkEQrjqYkcSUl4d|q@=L!s*mEE&p&&IHkJ5h@_guc4GvACCff4h~2lCT@9iI z4McL8Df)o@T?y-|`Spm|$PANFYq#uXE~j|e+T_lm$P$k=C&$KRmfgk}5?Erg>)i`$ zHIrRSuBMqt3ko&+52}Z>(8d;n5Q)O-;~ZT?QK%l>t;_HrELeob2@CW;Ot^y!(WzCU zx-XMZnPZ}zNBdAlRj?1u;@FHn)ba$pp&%kH2BECd^l0L!{-98E`>C#M7zRV^1lSjl z`dF}UOz#Sy9;BSUcgUR>9ZN9~>%D{!rWK`T2FWLbxL_v{>f_fO2eff;K1P`q`=%VsZ z@5}cmF0--Ifi-GGo3|Z+d zNU+Zx9LXGGx6z+)DJEUqow$9&$1>zLm|;g9Iw}AkBQhdjb&0euy^v7Hrj_nZLQfV{@B2|HIB;nVYt?X? zsN0>!U!yUVC3t=gjgrUz^P@_Wpy{A~o3jy7HJFC7z_awBb4vawnUas8DN}g|4o+A_ zSD&1S0**lGh8CsQPn6V!cO#TIU+LzTFrr+dP@d!|TCoKbMv+>Bhbvv&DV?%FgkBFr zI<0q3TJ%V`6BXVs^_;X?vo~prEbE+QzaqN2C{2Fi)4E`-!An6>M*@{%K(+;oJ}p`- zt<#Enhkb-yQqVu(5qz2M0X8~Raf$5{`2uBAyYq}urmq!6UCv}s&$RL=A+2U#;rt6# z@l|ns0wXD&CAof1;004;-i&V7Ns3NiP~#VK@B*RUI(AO-HTlxX7mKI}OZ_FH;dO@b zO~6$ZFrq2uP^ZRYeYy~eTK;h!!)QS&hCYcFr3S(}GfAop0jA7YSoNb~YDLg0sHkrI zH(G6|kYtF`EY;pn4D-9Ft)gk3_HFs7joOBb>D}0-zL&c=%b?Csc ztmwDJLI+FJYPHv2cSe%iDBJx6GLS}Im5Ux(24#% z5CI=jBPJfrzl_SEU&G-Nd}#G3Sj;P>p;yEXib^SZq192P zDIq#6`v6hV%s**!O@n^-%;U6tA;AD%Xp8257#EG!U`%p?81cb~Dw& zim^}0!1_($#aI;Cfz;#DHYUOQOC5?m%g&*gxP)^*Ly0WqT;m0^S1L}o!KSXN@aVUR zWtSr)lXpqG37=FK?U&P*(srX0_8xAMO&F~`$yaborqq4dd|A)10*XF2O_ZUG@z-cf zWeFbJDKz{)KdLkdD=tcoF$V_*Ma98lj4~veo@6h^RI)K7Og75z7j+6X3I#>fDE{}! z)9QpKkrYh4B|8@C%ZiQ`>^s4;XiOGGO|&1a8~Wv))k%v~qI^kpgMHpPiLoV%b|Wfc zKT4eD_SE>)!k<GwF^Mtu<&9K53MEgA}4%UAVu zLk?nuPH0SIaLCxB31v`_-Vz@{g=~mPb12`A&W?-5*ourQZS+Q*_*!nMpDuk zL}Y#bro$$fN}QHF{^ErPZ(4toMWw#{Ws~pWo7P{h@}sX~C4YUC5kvB9`lj{YgM|l) z$&K9o5)`UcqEZj8uT|O9-FK(LIwF<&^7@+&rxNiLoYbknFe?P~sl*#F```-&p1D7pJbY8w zuN4iGeB;YEtzYlgns@spQo(f2w#ro9HnvFt(!lNR?|SWl8=M@QSxhXV6|ZzsqPNOB z5=7s%LAI@0hg~V=Yta)$HCrWiX&n$fbColuLvry;HC?Bb!|NQY7Cz^Up@*nWzQ~Tr z5&d5D!)X{%Wk1|`snHfeO?5bhq^KeWGo%>IMQDt<+%6tsY|vJ#AwQ4wIl(soJX~mB}SdpIFwT?d3z5RaooKS^RZDLB~lEagQ78tdMQfO z0P38mm)fQo6sx3BJOw9aQPK7W#PTVLG1#6#MHaiGL7FQkLCui@JyNUZTd5T%V|3YI=d9ky*GC~cUYDQ#0H5ACa<6Mi)ff7uHn zW;^VrV_L0Vi2)G3MKn+TuhJouO05I0>KiczNt9aEzY41yc1Wyps5z_sfS6e^c%fIK z@Tu1Rwz{AfEv3*-A^(=l<>+Z_*V5-*{-Hm*4Y;bkHB}Z4dr~*B<<_XfKoGarFg! zwOqImQ)qY4`4?+oL?`9ufVMr#ajzWo%l{Iz>MVDL1*vU_^7>7!hlvgh@q&i?h`5Z6AehKAleD0W8^Bv*M&nO3LKkU@*KiG7u0Efi^td#>}E zAuU`AFhRKH01Bh6y+(k6vr2vmpf3P$2hcfONTzQJSWbC;Cz?I=u@?vgZCI6yJz^`A z#?i{81mv0k@romGP02NiB3cyka=90<7Oj3A#>DqBU-T=hm@hq1{W>ci#rbl6TyaR9 zA6FckVO~$p*kM}8+opI*NM1!HA>J3IUlzsi?BSx#;b}<68#n|1|O+h zFH4fblnHxjKVv3{7cU0%Yp-~nB%`;dl&x{}WN3=8PbUILr4`hb&}>_dlrs~uIBAZWreAOJnLx>-pBNLQPhq}^0@i} zzPi}xVUG0Wwm`-xdSb;K)Mw3) z=Uxn^Xj=9NUF%EbvB2I@R71|n-PlizzJ-n?+LYF>@N+(X_;FY&qETu)v7a6u6-Dtd z1-@nzYPGePaPQ-y-C=SSZC227)nXtJdkIC3(j{+kqSk3uPb`I?FqR$`P(Vx3<+03R zxgVh$#wwWpF*&(lT_%ax9l1vUk({1O=G3Dc>+d=;U5C-|y-l4!M-}h7lJ|g}GjGO4 zl#Z!!5v4=Z?HFoiaPTTNc`cZEU)PX*&z6iJ3=G8a!W6CFNoE=0wR3RL!8-(V z9pk5kNpjNEj`feK${PapYsBR3VJx2==gx_aadV=>&Iwe4Nw}-efpvYON=%@~u!PyW zrzjqxuV@n>nvops%KuVyq7rjkLR<7O^%@mRj)Fa7{ln^)fnF;s?jYKp(b+2cP@u%B z=POSf`l7|SM(q*x23EMzigKvYV)cWUa?V=O+H%;;tgf1%N3?lxaIjoXIu~OxN9|Kc}%Nh0KD(@8|*?G#xaOlf|$7lueE<5xEk$C#0 za2*r9H?#!RU&S$Rla#kZYQ@GXL%jBI+&6M2c&ImqKweKdh6W`tE1Fc$$?@(v*BRj@ zlFb^ec-Ov62crc=yMi8Xz(Y<4y)5*AB!f-X5Jnu|%bDW!S$_0;7ELOn1Q~@*zrK>8 zOe+7wITK8^$(3A8wM#r2A(x_MESgc$0JBm|$V=%3op`u)rh2a!Mo1vd zsaI3qqoH|^q&$feiiuRWS65fc(A6z^G(w96{a(pJbyaj7-)d?PJ|RsQlO{B;7?jrx z&i4+|^zzAt!Ur3CkN;jp;)Ov9lf0WJc`4C$`Kp36G2J_AJi(4p33s5#2RepIzTz+u zStc)8v@cd<*c!RXGb!JHpks<3a`1`e6^oLQfo_K)l$5tG%Ba`ha+vD#K|N`pATMw< z@RSju`Ynv+<%Cv*B+T}JLGi4X)k2E@sQiQ+~`Ug))yVD(~MwjNeSu<Ba=g(ugo%>&;$70!?FX|qP&LNj-G8(12jYabP(nrz(x{v6Qy{3=M40HaxFaK)qwXan7WnXeCc4_8L>uFbo4g>vEXoQy)p*bnatP-gN7IWoYR6->@hk@85RO925( z7RaTUqmaqW@$)OorD^Wm=0{4hqYs$$&@q)Zo9t+vNRA&QHIB+mDikbrIPwVcKrH*N39~Hn0QRPjr=N zK6ubIw3qcz>k%b^oTn_7n7kIaIe^APgYp3~MKkLK zwkO)CTY-0iHF_CYa?wZ7aa7kzdB-q~gY}DM!j#k#4T%E6`t1j_`cVk5nigVYClS@H zAEWhgwEiPIXW-GT|KiT+F)Aq)5>XGS&)zK5es&4!4?`Zy|GUFXBPS?}+ zROv##F=D-_ZF~9nRkR6JL|zizs3Gr|Hl7hiv#3XOk^V+ji0G9#nqBKP;tzVGMsM*0 z+Ma2tByops^*)%y(dxbY&d|2{E3Z!Pn@QfBt#(LtPxMajqtTnqzM#W2K;O8gl@LRR zN!O*@OTv0&mxRxar(=rr#r&ft1D^q#pKX6ww8fjT4`-U`(G$Y7ZvV%g(>0N5jdwD= zLf|e0^D>sTwK~Y|wRGRq;GLnl#Ej}Siv}uw*~MU_0#7^l6*f#-u@{}0j?`(iPUl;a zn>)f@!r!NeJ}DNZlg;v;e{Eit5+pIIqAr1+&mrAVN2B_^^_0oHGc-(0HtPdsA7xPf zQ&Na1G-(HQ=4|tI)`q65+#8hrl%GNh6;(gz{S*_KS1^5x!Hk5cv1X5Dp4bRLx*dmP zr>Ns~a?NvxJaxP1_9CU0u4G=)UdIKecUo+6Xic45T1sl|IF}$moF>MRNb~m43wi=$ zMWIcnA!#OQUsVZq{&^VanrR^lWgBU}$Vz)q8H3PqG!l?KMU+YBI0zHWB}2_H!LSw4 z67){niVGg-uH5OO+7I9?7z%F_KHOl$4S}49zx_-KuOyIxAzAQxSNd<)cNs-EGyptej?GFda$SW2lx&>NI&sJmvx&!71y zJM;6CF%yD(4#Kbt2c(n5Q&*d()G_Ei0}d{PVTqP{={}H>ppYt?#v&mNBh6%Iu-;gaJM15}*Gasqn% zWSQgGfmm9+kdtBqt|uPDfOD?^Upv*ak@3sq<4LTKASB~jiW-uyH`88-SmsiIoSAw| zNU=6aim<~<1+;tyybM03jl(n&YFPx5W;$tllsJu-^-A&&$iPR!@$pHM;EgDz0?m$y zGs~66NCZw&r8QSFpgF}1IDDDb)<5Ko$f8V5m~{;ELiI-(1`H&Trwm5jlGlkI!}m8P z=n!@QqgXNLn9njRgvUw#hj5v5(*G&>iX@$_YdlG$r+gOoGMSLBCl(Q=oituowRcj6 zkl2w#0^5Tg>Vvot`6vf9dc-ll`3ea0u4u4n@ZQ!eux`o1A)`UcldnneWZh55XwrUd z>2NzvHAfMTK2rGOYd081N4bytOv+3$b{xTA znCB_Ranp1XigxLEx1&$DJOv1eNL?0qS!<1grW*%8c$z3KgF~7~2tqrBftsX#Q+A7)sImulPC*OSJ(-3NqNjU9WvUXW)OM?9o}Xp9dl?@ zC}h)-ko<_yNd$q;Z75xD*!Rl1-^GGQ4CFGaSnH$(4R0D_7!uwX{CWk{YfH5*ie56S zJu^?*)eo06!w3U{j-X2ePQ7kc+FeT0QxDFWdb}P&jb7npM**@D337CJ)boaiFZFnX zwig%;c=_Qh9a4-N8lBB;(JUixbVyk0!LizzWZp1YdBdYwmGwLx36H$9F&4-5;=isJy$wi*wTn5{KHl)qTjWM#CX*|^%$_+oV8QX{$I_BgM z1rrQ%7giJ>>0o`=l-RDYjA%+JDws<`Qd& zm=drM6*Co*U~WvC#|+hlYh){&KXG93KeY!ro^v{?MJiPpy`%Xu=0bC{8X&H^SQUf)sjT>e()l=MBePWIBJmNj7vUV@Guu`LM{<~} zAaswUBSO;Y>D?njln+UXpvjRHzvMSMv``p2n@SHgaJ)&66BnHtMU%w=W>4$V&rc{j zxs1sLlLLfuDk9qliLU4;lAn6cP!lq`-_4;jlNHj&s)RN^NNiB&*AP%5VF)1~R zS{j+8LGLU}f|+s6prmPBR681ng~0tP{328M_z(@TTpsjGsc()qND}D_X;XXSMwE-w zXsO^eMoVJkvBUR}+uip*!b7>tBiNi|;ML}`R28*DhHYRo#wCMQoKOfVgUQjN@{S(z z!Q3!oxe+U*q&A~_c$ZkeN>l1F?2O51EiFUFF{ZsSF-+UkGK|4sqAOxBmxIEn=A+)r z$mZ5L>o!BX0|_aLOSJ1UFVL)Hv`2dw+j4S7C(lN_cu}koQNGbM!WadOi1b*ko9V~G zIxb5$qxZDY-sm>uqNszkdKWh&#`qGwtc>)tK6esrQ9Q^>lki=eP)g;K*s=*_cq2&% zw7NiU0KT@vMuPpD@hqTeROQo|G>V~4NQ$ye+G9fPt; zYMfST4Pnshw=F^}vyZVU5gjr{9eL@zXgdQ;U0PD7wQVCDV`X5=GeDgge7ZW+QW{ql zfp+&V(6d+~nQ1g3!`oh|Df()?Gt$uHL^D{mNi;8tD|UcPH$KS41bDy0J1c@ZxT`kD zdeX%*FC#hIh@2Lj;uKay@)$PoT?V5EJD6P<>ovv<>oG0vi)ma8utChbCHW$g8T-r- zp^{XLa2dS$#?5X4qc~>B?{a*^dmGI8=4cIlz}jPW3W(`wv)t$FiJ|~VCv`;;(>=5h zUqS2P%Yi35^bQXBfWSsql)e#}pqSjblB#Ww| zv_itj^E1Ehc zSd$A3wFmw*cRee&j0P4>R_>_r1=xOqT87Fss#QB$j&RU>*DMkGX%-Nz0?rV*(9GI_ z9l%U(T2&T1S^IRmm`OaHo!XebQK0ifT@^ecz&u4mCCEqhtkUOa$LJ{`lgZz~cl9!i zC=q`2mM(N~T%meJl@B>)WDyl{fM{W9JR^M5JNjwrAconFrILxhebFAA&!Wfsetyw* z6=jG$6wLCC4eg8eXdhkgu%(ny1Mf1J&R7vBGRnv-=L zmhBzQ($n@x6n1aTY{;vK0#gVFoaLI`PHD0WGT zlj$pkYFVzEU(6Gx3NmL0o6oNTOOonYBDv_B812CYA5_BzM8k@9t=4jc{G)i5OII^a zn0zuj8Ld`MiL^4ZNm~j;_Z-vPSRr%0cdcZS5u@dt>>tToT6IicJP-*Y;-`42OC*~# zg5cyUk0z%gg~%G_(=3dH=7NDCI6bZ?X;D-#X>!?|%ZN1l;WK(|(lSt_vG9*|K}DBR zp8oQqG$gZs-ud5&*b2_N?AG4HC+fWH*4)rxei)bJhjIB-a)Kaoz2#ntR}ZG&Sik;_ zG;bfQHrO&R5l{c^3+caIzy87W3xAvDgJGH){1CVn`KevY`t^T1WbxcuOQv6_Sf6_# zovbvZ5zkAd(=F?7de-xvy=i?*I-M%Uq~GAzhtGO1zwABB@A}?I7h+U8xPH`odHwpA zz2JH^9zSC6H@l?~-bJ&zc=6})da-I)9Zu4BPZF&L!bbyZV`{n0?U!-3@ zK<7wa=YD12qce7%IeYe*3yz&<&c6Ke*=H^=cFxM!IeY%tG58COoeO1U$Ib)_y8Z0 zEKvkVlOkIhg%qu%TxFNTB(9V{=!2`SDgpsg1VL5eDk>>uXeIV7$EA!FT8UkWT-FDF zaCOm%T?JKHE>faN!lWcNNsxFAUc`F_n8%$*cVl|Gr}O*$*FNXoe#~&d0ziryVEUf3 z-)pb6_S$Q&z4ktv^B2}OPkni3;>H&q-P}Xk`qH0G3j)zM?)uXFf86-OV@bU5jX%Gq zul4*@cisC{64$?Q4>yugbmgn}{P`=Z&3%LQ|KsUDy=z`zC!3oWE^KZ-bl21Wj1N6{ zh3#PNrf2T{+Ff6o`;QxceAfv+b+Z25yY4=^P^ni9j^8o4`%k}m*H^y$r7wQz?uQO9 z-F5fr|M86}xqqUl?|%87J>Oot``h37 z%K!NbZ%zR|kMYX+H|}}!=4)Nwj$JbbGJ$e7bPj63tFQ6P z`rp6!@KcXH_Fexy{_vN6_suE7w+w!3{(sr?ziuA9G2z+o2yA@)3yZqlDUCyj= zr!cv1{mk0w$=u2L(<_rxr%&^DYLz>$BWUhhJF|A?^eMiDaQ4*6mGzB{^QTWtR=Iw> zQa4DQ=X38DPONa!_rj?YD>F&w_#XSl$x|0NiobSznsDLFIpQbB&hFb>zi{$wUts0* z>dBKQP8>gWq*9i97}ig&ojfsjeB;=W6O>s$zBcLFKmWw$$rH!tj%_^q%sHCj+L))h zq_g+0FP}Jm{MfN)pE<%MBWoAVJh!}Yf2CgK8RBKCJbUc9XP!PjnH+oe?B*kHOsDpf zwzhe0?(7QvK6w)3$@xd$l$5LQTfhIw37=G7KYeEMFx}<<{)jVO ztW4$2zLLWMSAWLmeaz!4f05GkqGXSeeeQ*LRQk?F`>yY9Uz)!>EZ>Ho=F}_mQtxps z#oV{K^j6(W*+1cZ{8nqSsma?42DeBTZp1h+#4a-$jD5xZ2aD&DuewuR5P&yfKy^zd zZ`d*>Q!rKlRYS0YnlvFPqpxF!LUAY%aV|dUGYwC{;E@q#Au}uzp*6UW@LRc%R6ImX|eLeZ*;4hDb?+8J?-M+GpnT(!s=418xls; z3d93K(iSB84g?aIN&lsK=LIIC^*7@1LF>M(#U@EQuT(~rJp|vA&Jih?v2R?t_?rgA zo$16v{VJtZ7nJq^iSc9b0iRGCUH-_X1Wp?G99y`2Lq-G2Q!Ti`SXxcwJ*4jvE*_{N zTk7iDD7rh}Al7hKbhq=kdr)pL)Yku~_8&ZrsO4HC@Y+akAF@A#2^&M}>^1^2o=pXY zpU$`DXR~3=Eas2T*}iO?8KcAM_A$9q?3QYae}{9y1El2cGxUj^h$ zbE~um4=~JYHzH-40ljVd(;vl>EqXXF2lUvL*z`2SNFTfrC*hD?Z`B9RBMk8YZHajE z*)?`$uEP77TnQ4%<{AJ(me*7*53`x)E)^Y#J8j-DKeMkq7}Gg+YZhMDHMn>1lvN>8 z!6$D9z*l?p*)HfED`<20<$u)a65<^9#k;1yR%sUSpM zu26)4{>v*1Jt+#{`N<<)tF7^r?Q;d5xxs0N4LcZ(I9=JV?^d?Y)hG?OK%t&mUD*c# zwAd(9UcubwvMi-U728y70=mHgs){P^GU<7`4N>?*Rwroi;M_k;=Ii3h%r^Vt4O_zt zTf-Xz8UCy+t;Q#Q`PxfimW1Zpsyk2*Qbq-rOW?c~<_`e~bfW-ZTFSh8GS(?3iZ0wl zDDMWX^zVq9P%X@(OOa-0y5SO{T*JYrE_K9Yd$?ofX(^S_z*4n`Xjf1Ev;!ufERd&F z!=r&IMFOB{jbiwl(S2RWhl7(uORVBj9y5pm13hA7=F!2yKNR6(JQ3LJJE5%2rXY#k z4y6Z}J71Hv!IG%EcJde!5%6a>8naIs+1Bzi$>JWSKL`bwoaWel*NedV{N-mQ`_k>T6ktk`xJxKlY%tSd{5I&s16BwTTO)9!_-ZaGKrMmX zVx1l(cUO3GRTJie(5UcN!E%TV>WG%dZ7CxKKE=%T zFoIsW=TKl`fJ=DeMOSP7#cTO>$+>UvBw{pk1(OzU2EbN(RHnHB+mxX4Ib0{qy;~le zZ2r-@Ji;mF?3+xbRa^Dp+$hzsAYtrSp$wce7&hN^1zAhGn+($5!&Q89L1$HA!MlMI z>_c!BWsv^)X37TD`aY8ik9Db*y9$*FS>aMhmvkH^P>xp$MYg?1AHC{j^3d>kkh=i$ zER(B4=RV?@WqVx2^Sg?5S(;76g0_fW3y&vbkq%wL1IPv5Vt#O(@E zd&BXRG}lc2tN}v%Vy5TfDTpp7$YehLiZTdHx_%U$0tTgl48N}Sh7@jkphS-oDY&S- zmJYhKbo2yE5QSH-jX2p-V*B(0L&B055sH}u@(PXdcH4#)@R{%IS-;-rHM6_a;{D!+Sc zk!7PyHOaEZZ&G&Tk^#G1CRRlesSLlSsX~fVq%k>ns2S^4*I|rojPX!{E+bVLRUPV4 zR7n{wK3M&cEK!IAr=w30W(fwys`G4U(LwcyEl-I8VvXo>C53^n6CE>f(WWc<^<9g0 zxw=Z*F@#2|uIz&{lF`6zfnr+iF5+p*{Gd<9 zAOi10+UA|VA{YMONZH~$7AR__X()BffFC(q*+PcM*$OYBn9dNpE96M1TGD7Ju!v^b zKw$vKQ#69J^0gF+Af74DpM8Q~x$zvF9HsAaZ)NFOgcPv?2`(rd8hI2E2boYb3ml(u zH7t98v(!<}F~Q)?Lg1nmfrF;VdBa4n8TmKt+kmN<5!f5)zIa_uEfa~9@!Ub>_f(#q`W8)0X~ctt z*TPI3C)4p9JAjs(ggkzM|G(yAr0xjUIM<>v4fxu}y?__4O~^``+78Zrp&cSc%Xc`O zT@>IBI++9;5tm#U>hTe7x+MHXhnB}K;Om;_GwPNYLSDe6!5BAxf*{W z5YUABGqAYbF&JNk^<^WFvG`7jRLR-{dnJk&S`68`1=?#pl-<>KrURKK#z1qPb%zov zW`Mx$VUGCv;=nfogXhIN&2Y1Vi-GB}-)kp`wJc8%lPxdZvJ+r{CCb@IMHmRef{=5q z+j~(^gN``&yPN@zbEtCEKhiQ#UGzK@s6&n?JE5xEqhTt>2lxIpJQssV;i>}y-a7Rx zjrU74S6_%2#=!MrlH}FmqjUwQcstO#G4i0CKBU((M^hoFZ7FtpYu?4t2>LT_UyJK% zfPm$@ip*YDEJ+FCK_GvCwXk&EJ1i&V>43iRo<1BHS(e( zg8~x6&MpGlsd%4{dLm?ZHi4OQd%BcQsGQ3qXbg)OEr_ad<3@PMsy10Ld5?-t_Fmr17C~QL1~Uq;%~bwyedFc%it6z zxYOH1M^LS-U*$#?G1$|D*g)!bpT-;I!NV(}t@X=&7^$*2(4JKXl{k(>NMz z)lfNcvFDT@dU6!pWpv#r#z>CM331Euzi$BS*?g8$fm3yOLS4~`-$}!WajVhA}{sPI!i=kC>)7w2LPaVDgr6bSJ%0VhS{pX9wCdVkwppY zF~$xt?dYp%kkU&)5U2?;?#ajM4#6ekX1ja;FEitQh|#V{qag>*BJyb^(+03hsNur< ztVO$)gKuOoa|d(+{tD7FMKw?p?i}{Tg<&aUYTbnQ9yO5oiUZvet(~`dW&#$cM!Xl8 z4(|P>$-(^$FQ6N`Y>#9Ey3v^G(RXbcM#3-$G)~2`0!M!cx|?y1L^e1Q0yL$DGRDLq za?*aNt-KGx!ty$kt%sN28<{r1elhmEh#L<%(_G;ms?DWeg1KO%@TBh07tbK zHBL!=!{Y11ofG|wMi5A z%sj8wQnfS(r`{LnhU`ChoUm`*B|#rhk4xJWcL6>cP=6KT6gBk%O6)`2Sz`N_2yM+t zt-HbE-4fMe&gjzQT-p!9&?+mmLQ{f+3R=*xK16BMTL?6nh$4)--JqF6pH(-V21nkr z*9T+nA@g>CX2UPLt6>ifExQo}33YH&jh2@EJKA#pp7>d)yLTAPm3|fpvYqEmH&{1_ z&c=jbcq^$vuo%M50A^u5yw1dK-oU-s4HL?gDA5Ud2ZI@kL0w>kXLq9Z^=Qb@8WV{C zv};8xkRhR_Zpt#{S$gJ%3&VOb!Wpq`HPG7?=K!0Y>>89YXHqA0r9(~kv~Cpm@Oy_6 z*Svi}H=$dAA*#eV`e`x)eCDRBL3FToyID|=41GfT}Jm3m&w}E zw|hb`?{iw;+qXYlt>y#E^4c_Tj*ZYYKow96onv2h{q$)n6>$5cedpq#*_>EK$k_qW zJ*}7TO0@nD-Bev`h)Q4?n^V;f%dN3Tx|zl;w6@0HYVnkSuVYdI#A)VbjZS@VdCh&< zK1fNdPCMc0;PUwcalxE|MDselVeJU}Y1u%)PXpQ;W>dzQY5H zM6tCoPtTT$ZNFV|LG|1n$OhR-n`*PfNNc~_2O@&auRxirS#35@PQQ<_S3`(Xr`>l3 zonX8bu4psL~?omB~b1Z9_86NFNz_(nnd7zHy#L`x+R%jb2xpE0K3E+S ze@TsSPEumCCjuV`-*X^Ypo8pc zkeKXL7A-h8l0<%(qS{Dfus#hVz!t1h-LwwEtE0-{Cp&V8j>-e!-0*_JUY1HpDzr=d zuM8-n?wNcmNr~?>_|pAjB+nKtHVS>1qb^xCES9nz%;J9v^Ot8zH<+i*mcv9!??f1L z_Wb05+2Ufe2iX_sh5>_ls`|-jb!UF?9oAjS)!MITPiV9*P)t%1)GMk8aRa3T!zu}- zVg^aD>=+GQNZ7_7*LX*k3s&aao&s!OKbhMS9V{W71*b#CJEu?9fT#-j^&&18>`r+_ zu(Z^VmsdEgOcPQI3+iV#UK6P@E-b>Yk_%U@EO0I=NlO`nUCUesH-mG6-RW=cCq<| zWs6A(rztAi>X6Qygww8Ky}9PP|IeiDa3wnrAmSgg0AWO0Lh+ow3L(h_!+eJXe>sxN zYkD|%!mRKKT}Y{!5RvhqVABxi1Y5bhLi;CQvu%I`AfW4kYz^!RWMHW4F~LpeNH#ZE z#k;E@+fyFTb`u(GcW{3zXmvw1Q&AH*oMl5cv2gBXcLXpiBJc8Unch$reD(|ugE|WU zf!B985scXF_?;U444uIdbVGmR>r)e_qT%XKP4;eXF0)zA0(7{_YH4{5*ZEZzOD>0( z@xP771Wpq!dd>5s>qpk-v$qN69%Ca|DlMtP$7cte(+4EJV|6>$7IZ$ry?Qr$us~ za`|lxC+Bg|SY2a{l>C;_NPwAvZdS)S@Q5rIj^+4j2(-|pAOT&HPjBLxvCQ-X5Rb20 zkrz?gB)OwGf zx5ddGdba_}CBmNIq)VA!6(`-lxR7^6%2#H$B4@h%IERbkql6oHLGctk(Qmpjah~bg zl6E+hAE9J(lu7>!|1hhtmkZBRU52h`aI#9C>JRgZZZys-Ye9~_HAszhuE1DbH2`a! z#>1V^TWOSGAd)+-$BYC@o?6x0$h*8lBC^(v-qPw7@;C)>NUC0F&tg)cG2TEx=M_Ys zR@aI^*8pVib02FMjqsIs2-!I%Va&m8KfKTN*Dbosy0VH#|5mU4V*6Kb2gYtO^=Oeh zvW`6oXoB1F+ZWFspdC`O($QN`eV7Pxbtc3uXE055E(&nl%o} zwdyxh$r4AJc;le@BJ1s}U^0z2k8t#D7C5S*y>B}QO>r11r~N&XueOB(3kN0&7Apuf zr99d$&P7>J@MdGqBVeO2)I zqgb0&0%$^;$cF%v-H^fI{;#A$|(G!p_ z-n6^G_jFvHsyNJ#(PtOALA_GlKEknW@Eq$Vrak6$wE@>EuIj7E-1rHSl3`Q{nbKXH zfZtJhFL8hkji~GZqq5M@|Ixeg%2Y9F|7w;0E+!yP(5VdPpR4%4O4HMrEYfdI;c4VZ zH=%d6cBauPFb9XX!(RV0pJT~7i}q;z=Wu>%MijBDV-K^UZ}q!dxHr1A{8pEy2p`=4 z`?WNDkJ{ALwL`byJ*0-RXnd_c@#r?pwU`9%;hmN%Mu_AGlPbn3x-48#r*t9mTRVfv zacGd)8;ykAncqPMxu=VRD5E!tN%X(ylK!e}z9(vDAEh#Rb5zNheCgA>T0_&~z&AcP zJmKa`r#>&fpA#C%o^-j4(#c2tKT#K=N4D6=R4Tz z8=iB8BP#nCSJY%0fx-Y+<%3FN(0uga1$)t2rn8~i$<0VWF6`+hxd`2x^uko$cK?*E zihiYE`-i@=b~CfeG%8BLP1Q)3i|h(OF}I@d&z!LS{>j;1_M_|Y*|lDbZ+-8w#Ss*w zb?=Q+>i;;V9#LzczE6IyLp473>Dp`uBN+1GuWoX`Rznz7>b z&aZj1t6eg_A%@;fB*GfVX5eH~7Y&8Ho9O@WHey5p(fGKHZbM{=A^JGWm(U@RHTalb zw5QOVO$9_}05{s+CsmHzg<6}%AVs!?$ ziqs^F#h-j}z4Gp$z8~tp&=jMUM?^O7xOnKfJHibS!rFQ;A%jNtXA^VPWMD5}OrN$N zYOG1saAwSX96Go}=(#&ewuwKcB35e*Tc&M(}Kgy zSkeOLbzb(vZgEAteCMN2#)a_8?+eAi?ZMl{ey`yFh2ryt=D!%`EB*@pUno9bX#Pv$ zKWf*D>}p7zmvm*+KP*0E=!#Qcu|<5Mnm-x0{q*l_zs}^x#bVYcY2156l?7w6(?DRNn^A(i=yzvWWT1RvyRaJUOrLfld!IrDK=F z4i_65i<)dI&Xn$wP{Q>gh|5IaP8~7e@uOTSUn}g-fwf!_x+F~vq&J6)&ivNQJ_9$0 zN!33M$2PWmu_Xv4y1pq0U3c$E(Sf79oaWf4!{_5qQfTMpZ0}M~=U6|kBIP@ClO_W# ztco^bHDD~>!*OlrHu-X$;d>QR;c7^P96SxCJxUR&HYB0Phv(|D9M4V|a$Q1ct`x z^F^2`h&_k32cT*6SWIJ-Nr{H5oD(f4uDP3X8O596Dy;7C1D7DcC^BV*`C?<-xV$Kn ztF6RExp8^V6*g)nYWQL{3P}jT~yv|%4g%0QP znu{Z+TuaPKmnhI!%Q#LAU_3qA-O3p_ISn+n-I3+s>EoLr}twawS}bUk7jRqA={d^)598rCuLo()B@(%r$oI-3%Flxdy_T z1`>btE}Glzsxt&7wfq8Ff-cbq>2BGNk(03}|3tIqidTfGU-c#rlgrOk!sdYOv}Rg< z74D(wdgLVyZ+DpBi{Nggga?@SxL$I`lL#a8#W+gLDyeZgR>%=ipl!_LO<#~Sv)vr`h>TiM>VeNL#YwnJAXjnq zo1c6~r196mtm(bFzAGnXgq&L#F-R5B$3h8;h+TW;&Q-peTHZu+H|J^)I14Vg9{TTr zoXAK*$VgBWHzMwYa8l{sshf#{gHN+DNT@$7*BWQI=2Qd&G3(K6T#TS9BQE^OV{7Ep zrzi1|kHwpjkM-KPHS)2Gara}>OCw<#-|;00U)THDyobkkCVLy@+~f;34Lm)pEtEp0 z)p)2ZeI(-oXiT0#44eW=aB^*cGPE0-rg6?6%?AlY>Bto?qv0P;PN@hu`;NSD#)*9% z`nxMUH}(RIB>GX+I@O>=<6ERkwE9r$3cLmcAa=l)Qd7_b|JEy#7p6VNf#slRmE-b2 zv<@|ZuDvRD9`(XFE{h=53ZI?O-EspT*XIoZln(V^o*|g@7Ee+91FNXpUb>?DmwB5X zzM_ioLw>L+C5V-w5*V$eWS}T6x^Irsc~IF$_8oVm-9)<#YlaH!1C#THkbDdv$;z7-uf zL-_24Z{eBT=Zi!mBm01yv{5h%ELf#A4jSyrGvbmvR^WHFN$*ReRB@1GWcYAFN&9G~ zG7kE~LHxchUKmI@KGkiQ#V>QIe=2@?b*`%`_*$?z!SomPq5efT@)2fhp%Qj*5bR+* zk0w>*EEsU)!h`ry|Lo_0^*iccy|zchTNi_Bv>4YC7bPfn1X9ev$!VaE+mhiH|_5!rscPT*0VoU(_*HjomBKb*<4~(x-|Gj z^f4mF2lxJ0ZDop+qBpG7@)T*|tw>Tz1Z|>tk;*lJxrB|GSmY`YMaPaTZspY#W%)vO z%TYVSQDnR<5eVBc3$>?i`#4L~9R-&MXHqt) z&sC^?$;7ge;UoK=uL z-d)uowzn6#$I;uXoa)dB&8?s-{JdH$cku46!?5* zet^rF3>jBVKw$l27~~}}Q>Z~iJeD@c+JQ#Ds0ke^9Nhbnw#H#7=nsVimN+4z)fH~g z>PTh8d06E{TlA2pn%pH1)b`#%L?C)tS5NaPXvpRo#sb^1r#NAb4HIQqa)xmjj5io4 zTfKKhc9DxA8FV7$tR<;!T2jPJTb&XytLUt`EjnQ2q}7b96rt6NmhCT&binq#WzHTI z*0z?t*e#N-q8KkhDXU5td~3t$?xg z4?ukt4GhP8v`Da+d@(bEPSQCiS{Q9%HGAZYs$XJSK?6?oo7z-Ii@%5`CJI_6FZ{o7 zC&OPZdNW+*^>SYNp>Hbz?WmkK<)&Pf!_&Eo&K}Z4<#7F!9P!<$8H9yIpM$y>H7o_G z@7Zz|i_?k1q4z_Hs>`JtV0o>pngx>Gt;NaFra;%)jEtNVcY!9XwCOu*;b~FvwUu7O z@hZ(R$XKD-Gn6;1nU+{YBj;J9-C1m%Lg2(t&1bxJU1ZR~7u(CxMI~VG2MiZ;xB&alU{V+YxJc&3WtJnRN&-GtJI}p8O5zdcB6<`>QKbb95bzyDh!AWW zphhMIsK}rhMdLXd8#%8gAur5FnyD-c31%(c=bAzo$)tJ%$3_uz60;7Tes>8XZLxOu zlYOAs0G7G&@dCFM3ps%Fnan!dtlfdFwK-hC)v-`s4f+e_8Dm(Aq|8=ZcPm?3#ydoZ zo9X?FmsVC+xzjh$@xuk3jLxgDET!}`A=)Fe)rfB!vEmbDI}_dKc%tD$zyy##bPZ6A zq?8~zOinjY;XHF-6JaHLuH7WC(f9M0~k<_@=mg%)Q-Gs;x04O@0sJ@_Djbm?%9dqlnt@T_C zl(tq4I&ht7pJ@}f^9a~XY_-4`FoXUCQ^(>~SUkW3M{1(kYQ`*po$@b?7Q7pJAqR-3 zZw`ZWmi?bJ!4F?mfMu^jm|1)ppR>fc&GPXY?>XI(6m9P6+=d;D09J<|>Vpwcpt3RL zkZ??h?_`2Y^94f086~1YPOs8>E?sQ_U$Hp%v26nb6C50m%q-5-|;bcc$T< zsC^D%*i(tF1)OREfI)FyYU86Xj*OsDGPTB&gP0ls?iRsW9%J_(Hd*JXnt!+1xAKKG zM74IX6((+(5!B6V@l--H2{55`~hROf=97v0egBDW@#Ms+4Vuyyf(jyhsf0kWm-Id2AlSb;cs;Bw}^ zWB~MNLlQ}Y;oLY=kUH$#INPh-))5X%P(^Y$_CkKlZ;)qdX>3+&?cl1t7rYah8wP^g zpkxjfI4_~lr%E;MY}Q>FbgQI!Rhq0zHC|?o*L$?#e>{ZK=pz9BR_RhBT9tXfglz`$rBF^AZJLNhgN-oZhEFjIZi;iY0L zKlP`B*aF|+`DCt7fP70kLej4+LXy|X&bc-d5x>$`Nk9)xvc^os2ASGq9IdkLdU3PV zw>H>#;z%oLm`U1pk5fEzD@|P0Ra$yc-)POS*183#G&-7v>E&grA*Vdst|V;VuY9?{ zL9v2o2TWD6Z+3~BW2;+Ix2$9<*{{>clRHD;yCyd8$Wl~B zs-@^l$WlzX!*Ov`&97VES3k*|D94Y=H-8EJkvv#ZK+Exo6Q6U(a>Mi;wboCW9PDX5Z0r@h+u_iB}d3m`gCwwmHf4_Mp z^$G^AVBiV{UNQ{)U{3gK_o_Es_jDtZ^Ul}jOT9E9ff4FwF50aWC%mo@t{qIn`0wAq z_Mzom)J!vD{GJV#{dA^mRkaU=t3R6G zmO5^@q9{wNQ8jN-@V2FB58Sqz5_IRliaTJs=bP+yowV5gLN6hdjWh%;yH3FI&~4%= z!deG9{Pn?U?$)8MvfaSwz`5KfH&|j`1LC?wnI!=_36`aR*|4Sfpt|%9PiCZ)Yg#d-`8`ubscHE#8P1f?QgkOeZ-@=20i~giMPtDsa=i2? zK&f==4;NW1Oa#lbE={ylKuAz5vqRs4*2*rE5{TqZPQ-*I=ed%ZK09ot4Y!~BT3APO z?RGLNU&BDNiECOa+6ZCo;8YPAX6Ewk+nRd{-!63(K6j#v+o3WwY=6GK4QBQ;u@s5~ zKj_BhrGm70jdHQ#6-{OWmD99jEUDn4a%b}$c6L59y$^q-rm_*&7{pfVYl%bIiz-mXU6^wsSGBm@L z-|y4Hz_Ph32g?JDQz`K-inC!>K_GFvF9LfXTNjz|$Vhe=MY)hNBm^f7Of5W?SGw_} zio5mt4V239ObwRAgyg$e0vna3(8A%GMcwYrF~JejZ*}@n^n-){+s`mqM6+xt5@$8u zxG${;#)q$2#Rj6b$K_co>Ia5wRqp9%H{z4KUK10mrE6fU_yN6TlR6HQlc`OGqbO@V zjtE-C`JoV8Mmq>kRH&*^7GI4k5FhGvYV^ay%vGI9vK0|CPYGT6+lW(0Qxw9-z$aarto`=iu$hww4#O@6GnDmU#GO-9ihfo!^1*gX_GF}TF1Kf= z4f9tyBEDuj4bM>@==KhLH=d`twvjL*IAGsWOj8zM7iR2jIG0+vn2s-9V-+Vp=XE$@X^sU&i*J!4?9`|~4Ursd=myV}!s1tZ(+o~~%E*ZXhtYTe zgcM@$WAEfFqsx7Q>>5BC#Z*^Hbw0^9u2!UCj-Is7>x_fM$?Vao6!U|%Nm5`o6S-$r z;@8y|+ja&|kTkK=ip3Bg9-=~zVQZn^c*r2($CVY%3JoI#BSqDCiN|w}3ifkMnV=O$ z|MN#_%H&VAUe8BLP-2##1W#IzG@j#}CUJb-l-_jfO(-($ zC_m!Lf28x*(Z>x3XNcr0;##hAuscPOS$Bjq7td&>(%Q(#SD>w)*2tZ)z%zr5-Ibi= zmg`_3uH`2qEp{IdS50vuWD2uLb3jP{(=BJ_r-V*&nS;MZN(s(vNnYGdAWqAo3#SrC zo@a7Skzgccr6!K?QLF$)kuf(}?tKruWP6$7HKk1k@1G?rlbCx$Q(Ee|My-Rrcvx58 zTY4I8WaR7$pbW_5QN~gXtYkY0OQYZ}d6=$zcVVH9j-vrf3g*{B0(rJkQDx*ww2G|Z zsK6WXAg7;*>{iM}t_Z4#o2ssxhvOASl4}wG)On(MwT#XsOi=U;33XNWNkbS#JBN2+O^-J|S14$pWz`kX@;PnFb7q{d;L6H{ zg1PaLa!C=jZQc@*K?A2Tx#8xVdg)|wk?Co)$n*sEou0Uxh$6~i*y{`(ZOQSMLy1)0q>Do2J%d@_aRgP)9J-j%eo|lm(Kr3+tqE9CEL;hYSSFjccP+ zy2EoU!nA1=@uprwDbW_q8t9-vZD*fz+JSdL-~y&VDv=S&b4a+v6ucy=aq6kHQKO@T z41Ptwf<%tiww7Urix8uZ(vkGgnW<<>!q3tW%c(7dgU=X=XmZ`;%`CHpYUix2#>nD` zBd75xe+|!VG=t=&B>MeQp=Wvj4hH1~9oTWep$c`eM^zMDXLdBUf<>S7ynXM!Q?X6!Yz(veq zkRSR~TZILvwi^LcHVOsFQZh9$3yl_;h0w2=g)%0Yg&cga1dI>0#F$TZSAn5!n`4Mt9kmuLiF`cWUCWBvClF!O^PA z*}!X9V3ZSwK6=Tem;&01=UNr6ERaC`)@-ZQYN~AA14CP?6FBck?iiuQLvRGPW7vdU zrZ0;95fjm9@yBSb1PL<{cqMYFrXsIR9{x2L+K-o#Q#>!;oOvq?R9B{48?=akA{F$G zIp56;)CCtu5N}B=Cv{1UVs;713Yk^NG;tG=U!ld(yM5cb%=>ww7)zTAT(rRAZt(xo zG%~2FwCN$Ts|O5bVf=M%j~CyG#8YH-4gAbxT~)n{SX%h$rf<&1)G73?Kk2}*3it0i-gNPPqM%B=o0nPji2F}UGy0G^(cu51Ejg?p zd6%mZ=87H^=#0#&1~(Vp>8Z`2wd#h-inCWlEwmJEVL47FKo%k&Nvw>YfRM&LsS3q0P%487_u?5HQIL&LEW)x$rL0As;zbk z6%kBd6=5qs6Lp}E000IuV{2=S){=13`rVmBX|p9rMKeyTE2TU{qz3z@8xcMJ9&OY{|5H!O8+m7gC9}a%hQ9~uQ*L! z^1||$!cpuKX>s=VrD)|!ofpHvEavO|VmYtGzZ4kQf&VryU-BAr^1P_&7x(&z8M3?f zmt}>XL_ZeA&nGH~Dh576_;cX5=0QK-W3cijb))T^rfX z=2Nw8@tt(7+PVi>?Y=zO($x&YYBs(-F?+`_WH4SpE^Q33a^nByf6*J?Ea_o}w@fW^fib|$yQ$2cWHkN5(>1mc{vivP2mBV!{0 z#wM~>SaOB1FNXKq%SBSJ?e^e^FwZbqY1fQy44<7~yj+;xy`4zR;XhW?yu+WysSzA`cc5r)5L>Ti|KAm{(nG&8?JiuE zG&t?PIKqJ_PTdlD7!za5;;wJ@O5AsFeHCGoO+idAUO@}(VR)F{o88za*vIMnY~O=J zGV_b5aZ?2^FxGhlurj!`XR+$m_iAjr=3*ZyXOGRIS^TUS79As0&f!On@Ys0BvUDmkx3P-IsBM>rgw0MIKwH5tu3q$9(a5@C~G5!!g{q>x>KoU3P zZ>6UJ;J7{)*YO_0<}hFhK1DAm7vto~jhT-UFf7jKdm&e-oN5v=H{m1UBG)XzdBtxf zfuWe0N5OM#&>6uMy1}hj1;ciS*!D}X{t=g}7`h98_*CA(;s2(bVOT6JI12W`Q;vd& zsn|L)LuXKg%iU(B5kwShZ5!=k1$Qc>n4ZDIrQyQkZXmWjOnC|rO5|sQ0?N;iPdQTH zAv!&hO&AmGLJbN=4XJarTaKF}6C@6ZR_nk@ z@5AMcl-j^O0Z4Qz>>mIflDV%8#)$j~K^ebXQN^h6${ec`-5D-4tuLb}eqILGZDwxa z+sT$7nTrmD?1i|cs2&cv!Is~BlShgYq-9|DDIFOo7~ccX<((s=C4zc!1j#GuU65?- zo&lFnHQr`SFk5){5@7H*LQw4UdW#Obyg4`-6aGBXQ9yhKrG@4|RXCoTe47wkggwgZ zr4NR!4HZu3ygIFT&Io~FIDl#}1&Ze;N0V<01yc6ya6Griavp;_9NVZEj^ELZgE)(3 z+GukJ10y@;dZ3(^)Ql|5#7H(ec0%#o#;LyPh?PB)2OXH?aK@09*}?+##iqzlcQ#>% z6G1KgLZA>uJs9$ipdnF!VUk}k%sbTL5OriZ8$zoHHA8hPG@FKgi)1+1*w0l$U}tZwb0R zlP?F$p$44K*0R}36gEm2q7Q{#Km|&=lL$seWCjQ#w&MD%1M(TSXK)8&>OpDv0yeRBWdkoOOm3cv0Ha z%uWD2o0eI@k6W*BC;)5;5^UcoMzrR{y`&St5fKVp6-5iw(DHi_OAe7Kk^8__{}kiW z2A^pn{Hqv9$li*%_h980-UU?m5%;xuQ|dt!(nbRBb>sUD!85p)uzUblC8AV1(wG03*~y1|tAE zWg{zK2U7qKCz8xjtYIV=h(;mcT01zQh{@{5sB@;lM3oyC9A-D2m`^k$fh=b$c!_ey zGB}`EqMAyupWcm-sSZ1&?A$OKgS|3 zaVmipcvmMTssN;^+_<_R&KCJLIaBcmS(F?coPqO$`=6sO=?o@eP%uLM@PI8v0RS@5 zBo8qAMs1}%`~Tj!!%4rM zA@=~Gu3K`u>9*@3kIXTV*%e13?4#&D7a^`V?!_+sRg!=W76D>mZhWSqYVu>9=zW_G z5_wCPR}dNL;i<+2^)ulB9>*B64QiBZ#-)Ndgh>Q0yd#wPCyL1BF(qUCYf;X5T*Sm! zbu@rc58ZaCl+3mx*LQ2(>-osY@;GBD=+e6i!AK=4yDfc$ic37{jdOGN+QjKJts)R> zz!<2%LN7<4ScodFy-WIxl|Hq_Fp!iv&~;DYr0JK5qA&Es(cqu>>{2UcJiq|OH!avr zKlqBL5!?Szs_agm9Lk$g@|7HE556G{oc-s@>yp}VzXR4`*2$f`_o+||T7p!r7Ng$| zYF0;#khIx(XGOK#6M;GEIXYdV0o5op^`dsY0#aN%^U?3sK8#>k|kWB>wL zTvlmPcs3PIqJtbObZolJU~n-yU~qU!DFU;061ODEmQ-qHZs1q+`AdgkVuO;adux)1 zwFRvhxeGimLX`3;mi+tr)~C)Y4aUb8zq#&qN;LByiD9a6O_p zVq}IBw@09L!jHP?lXJW>Y(L3`cLH?GISnMO{QppiZ zIJK$U;mZ~ERmUFI<+n?LQ3;+XdicZUY3-gPI(a+V0d<9AqW95&Jng&J?_Ru@m%_jg zN!llXgTH~#OHj)NP7%ui9PB$zpd52GH;gB4;xgiP_cPl4g$g%yQw{bx9=?f+A-R|# z%T_;v9BZSfpGA+&+sUq6;>ZI^m`8L}GaV-(mR6_|JJhL!>NH7Z5LXc14%-ZxXn}{& zUSJ0J*B@Q*F51US_5X(??J{Wva*J4SE<{3$3+t*0Wld6X6R>sSb}+@Dg1bw!IXkT& z;*fJnK#8R?tngY_N8;pMsftC95KE~9u~3*i1*J-;cnYzwjWnr4ovKxx;%9RbE9Q?# znZ`=XvXbwR`A21B#aU*@_VwoF$Go`P>6hQ`Cw>Xp@Wb%8!}aCz`)~z!lMk%C0A8EL z>|b)+#mslrXI2jG|IFmz_NPvv+vB?M4_Vp|W*hq8{y$(lefN#%mp1+f+j6+(+O6)w z#BFgO-X1O;Og-#-{(V3C%jMMj1I!cM^K#q2(*GB(!(J|Ke?a*LpC}FKhe6YL31PUM zy7{~CiN`T%{Q6h<`S|BJ9edlS9_9;#w|)GxADo=O?bcua?8AIS?}tL^x`K+AgAA9? z72nUqvVEd?$-`HDbFy*l{=0Ab=Bp>`$L@aS{7oBtJMi$c@AmP{H6NSbe9z494I9rN zJ}?;EvT@+>wTXWH#_Hk0of{js9Gb=q5AE5wFb(p$XXE&R!yC5@$a&b(z8-4jyW~T+ zkhXElof`-4JalM-25kHFRO&iIhtAV@Rei(8GhJ5%=kNxh12d3KyM5vAVB*64Pm2)nbad^e4UXm>`}%*l z>5mT1qbs~{G@d)ehkx%peBinU?DOD{{@>Y0(C_(;3tfimeciKh?C^mGCdCis^>8Yf zNk4Gs2K^m~OshOFn|>NJ(ntOd95{6NFx!b!EYEM8>Qgrk-!eEn*wbKpx`PeUq;5!X z_<+qP!wnmohxp(Qoe4lvVGC?8F(RQId~v8pB!F$)d7z7Eh#9u@>o??>;h_@(DJxL6 zy~6z+;2?+k>t`$90tV&*c`(w9tixc-|L4j+iYzdeLa{mkrmd z_|Jdr){owH$LH>P{O2btx7~W{M?ZSoZ6Evi$KH6`8*lx7QVtG2v-#o4yKlYrqqDyi z``VA*bjyb))8C4H(=9*oYagCWe=GLG#MR%66TbS_K0w>k->P-Sd(&+zpy{^TKKjvHZ~fQ{jsIJlgTe5#{Jnip z|9y?eKWXp3#`ABq_xJJq$$FpvE8Ic!pY#5j|Mr$o-16W34-#qjFwwd==w|C24%ilbI{0B6HSLSW{b3Lzu zV%F(@!*9~N9{Nffers> zwdZfP=Wn&=-*3-<(4POOJ%6V?f44nfY?fJR({I~6SXM6tp z_WXQ%ez85j(w<*y&#$-Vx7zcb_I#i{A8yab+ViRQJldYe+w)X=F1P2o_S~rFeZ%(L z+n!gq=d0TDy7qj1d;WNPzNJ0i-kv|zp6_hWo7?lf?fHTBJkXvWYR_M8&%fTDf3rP5 z(w=|2J^xO7{z`lP-S+&|_PnJ%Kh~bNx94xP=ih73-)zs{YR|vlp8udd|51DXPJ8}t zd;VT~{`2 True ', ' True ') + .replace(' False ', ' False '); } -// Strip IObservable and replace 'TSource' with 'Anything' -function replaceIObservableAndTSource(str){ - if (str.includes('IGroupedObservable')){ - const re = new RegExp(' child.type === 'field') + .map(child => ({ + 'field&value': child.syntax.content[0].value, + 'enumDescription': [child.summary, child.remarks].join(''), + })); } -// compile list of data for input --> o --> output diagrams -function defineInputsAndOutputs(model){ - operators = []; - if (model.oe.hubOrDevice === 'hub'){ - const hubChildrenLength = model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children.length; - for (let i = 0; i < hubChildrenLength; i++){ - if (model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].name[0].value.includes('Process')){ - description = [ - model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].summary, - model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].remarks - ].join(''); - } - input = {}; - if (model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters && model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters[0]){ - input = { - 'specName': replaceIObservableAndTSource(model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters[0].type.specName[0].value), - 'name': model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters[0].type.name[0].value.replaceAll(/(IObservable<)|(>)/g, ''), - 'description': removeBottomMargin([ model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters[0].description, - model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.parameters[0].remarks].join(''))}; - input.internal = true; - } - output = {}; - dataFrame = []; - if (model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return){ - output = { - 'specName': replaceIObservableAndTSource(model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return.type.specName[0].value), - 'name': model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return.type.name[0].value.replaceAll(/(IObservable<)|(>)/g, ''), - 'description': removeBottomMargin([ model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return.description, - model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return.remarks].join(''))}; - output.internal = true; - outputYml = [ '~/api/', - model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml'].children[i].syntax.return.type.uid.replaceAll(/(\D*{)|(}$)/g, ''), - '.yml'].join(''); - if (model['__global']['_shared'][outputYml] && model['__global']['_shared'][outputYml]['children'] && (model['__global']['_shared'][outputYml].type === 'class')){ - output.dataFrameDescription = [ - model['__global']['_shared'][outputYml].summary, - model['__global']['_shared'][outputYml].remarks].join(''); - const outputYmlChildrenLength = model['__global']['_shared'][outputYml]['children'].length; - for (let j = 0; j < outputYmlChildrenLength; j++){ - if (model['__global']['_shared'][outputYml]['children'][j].type === 'property'){ - potentialEnumYml = '~/api/' + model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.uid + '.yml'; - let enumFields = []; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - if (enumFields.length > 0){ - output.dataFrameDescription = [ - model['__global']['_shared'][outputYml].summary, - model['__global']['_shared'][outputYml].remarks].join(''), - dataFrame.push({ - 'name': model['__global']['_shared'][outputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][outputYml]['children'][j].summary, - model['__global']['_shared'][outputYml]['children'][j].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true - }); - } - else{ - dataFrame.push({ - 'name': model['__global']['_shared'][outputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][outputYml]['children'][j].summary, - model['__global']['_shared'][outputYml]['children'][j].remarks].join('')) - }); - } - } - } - } - } - } - if (Object.keys(input).length && Object.keys(dataFrame).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasInput': true, 'hasDataFrame': true}); - } - else if (Object.keys(input).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasInput': true}); - } - else if (Object.keys(dataFrame).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasDataFrame': true}); - } - else{ - operators.push({'description': description, 'output': output}); - } - } - else if (model.children){ - const childrenLength = model.children.length; - for (let i = 0; i < childrenLength; i++){ - if (model.children[i].uid.includes('Generate') || model.children[i].uid.includes('Process')){ - description = [model.children[i].summary, model.children[i].remarks].join(''); - input = {}; - if (model.children[i].syntax.parameters && model.children[i].syntax.parameters[0]){ - input = { - 'specName': replaceIObservableAndTSource(model.children[i].syntax.parameters[0].type.specName[0].value), - 'name': model.children[i].syntax.parameters[0].type.name[0].value.replaceAll(/(IObservable<)|(>)/g, ''), - 'description': removeBottomMargin([model.children[i].syntax.parameters[0].description, model.children[i].syntax.parameters[0].remarks].join('')) - }; - input.dataFrame = []; - if (model.__global._shared['~/api/OpenEphys.Onix1.' + input.name + '.yml']){ - input.internal = true; - inputYml = [ '~/api/', - model.children[i].syntax.parameters[0].type.uid.replaceAll(/(\D*{)|(}$)/g, ''), - '.yml'].join(''); - if (model['__global']['_shared'][inputYml] && model['__global']['_shared'][inputYml]['children'] && (model['__global']['_shared'][inputYml].type === 'class')){ - input.dataFrameDescription = [ - model['__global']['_shared'][inputYml].summary, - model['__global']['_shared'][inputYml].remarks - ].join(''); - const inputYmlChildrenLength = model['__global']['_shared'][inputYml]['children'].length; - for (let j = 0; j < inputYmlChildrenLength; j++){ - if (model['__global']['_shared'][inputYml]['children'][j] && model['__global']['_shared'][inputYml]['children'][j].type === 'property'){ - let enumFields = []; - if (model['__global']['_shared'][inputYml]['children'][j].syntax.parameters[0]){ - potentialEnumYml = '~/api/' + model['__global']['_shared'][inputYml]['children'][j].syntax.parameters[0].type.uid + '.yml'; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - } - if (enumFields.length > 0){ - input.dataFrame.push({ - 'name': model['__global']['_shared'][inputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][inputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][inputYml]['children'][j].summary, - model['__global']['_shared'][inputYml]['children'][j].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true - }); - } - else{ - input.dataFrame.push({ - 'name': model['__global']['_shared'][inputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][inputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][inputYml]['children'][j].summary, - model['__global']['_shared'][inputYml]['children'][j].remarks].join('')) - }); - } - } - } - } - else if (model['__global']['_shared'][inputYml] && model['__global']['_shared'][inputYml]['children'] && (model['__global']['_shared'][inputYml].type === 'enum')){ - input.internal = true; - input.dataFrameDescription = [ - model['__global']['_shared'][inputYml].summary, - model['__global']['_shared'][inputYml].remarks - ].join(''); - const inputYmlChildrenLength = model['__global']['_shared'][inputYml]['children'].length; - for (let j = 0; j < inputYmlChildrenLength; j++){ - if (model['__global']['_shared'][inputYml]['children'][j].type === 'property'){ - potentialEnumYml = '~/api/' + model['__global']['_shared'][inputYml]['children'][j].syntax.parameters[0].type.uid + '.yml'; - let enumFields = []; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - if (enumFields.length > 0){ - dataFrame.push({ - 'name': model['__global']['_shared'][inputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][inputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][inputYml]['children'][j].summary, - model['__global']['_shared'][inputYml]['children'][j].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true - }); - } - else{ - dataFrame.push({ - 'name': model['__global']['_shared'][inputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][inputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][inputYml]['children'][j].summary, - model['__global']['_shared'][inputYml]['children'][j].remarks].join('')) - }); - } - } - } - } - } - else { - input.external = true; - } - } - if (model.children[i].syntax.return){ - output = { - 'specName': replaceIObservableAndTSource(model.children[i].syntax.return.type.specName[0].value), - 'name': model.children[i].syntax.return.type.name[0].value.replaceAll(/(IObservable<)|(>)/g, ''), - 'description': removeBottomMargin([model.children[i].syntax.return.description, model.children[i].syntax.return.remarks].join(''))}; - dataFrame = []; - outputYml = [ '~/api/', - model.children[i].syntax.return.type.uid.replaceAll(/(\D*{)|(}$)/g, ''), - '.yml'].join(''); - if (model['__global']['_shared'][outputYml] && model['__global']['_shared'][outputYml]['children'] && (model['__global']['_shared'][outputYml].type === 'class')){ - output.internal = true; - output.dataFrameDescription = [ - model['__global']['_shared'][outputYml].summary, - model['__global']['_shared'][outputYml].remarks].join(''); - const outputYmlChildrenLength = model['__global']['_shared'][outputYml]['children'].length; - for (let j = 0; j < outputYmlChildrenLength; j++){ - if (model['__global']['_shared'][outputYml]['children'][j].type === 'property'){ - potentialEnumYml = '~/api/' + model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.uid + '.yml'; - let enumFields = []; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - if (enumFields.length > 0){ - dataFrame.push({ - 'name': model['__global']['_shared'][outputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][outputYml]['children'][j].summary, - model['__global']['_shared'][outputYml]['children'][j].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true - }); - } - else{ - dataFrame.push({ - 'name': model['__global']['_shared'][outputYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][outputYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([ model['__global']['_shared'][outputYml]['children'][j].summary, - model['__global']['_shared'][outputYml]['children'][j].remarks].join('')) - }); - } - } - } - } - if (dataFrame.length === 0 && input.dataFrame && input.dataFrame.length > 0){ - dataFrame = input.dataFrame; - output.useInputDataFrame = true;; - } - else if (!output.internal) { - output.external = true; - } - if (model['__global']['_shared'][outputYml] && model['__global']['_shared'][outputYml]['inheritedMembers']){ - output.internal = true; - output.external = false; - const inheritedMembersLength = model['__global']['_shared'][outputYml]['inheritedMembers'].length; - for (let j = 0; j < inheritedMembersLength; j++){ - if (model['__global']['_shared'][outputYml]['inheritedMembers'][j].type === 'property'){ - let inheritedMemberYml = '~/api/' + model['__global']['_shared'][outputYml]['inheritedMembers'][j].parent + '.yml'; - if (model['__global']['_shared'][inheritedMemberYml]['children']){ - let inheritedMemberChildrenLength = model['__global']['_shared'][inheritedMemberYml]['children'].length; - for (let k = 0; k < inheritedMemberChildrenLength; k++){ - if (model['__global']['_shared'][outputYml]['inheritedMembers'][j].uid === model['__global']['_shared'][inheritedMemberYml]['children'][k].uid){ - dataFrame.push({ - 'name': model['__global']['_shared'][outputYml]['inheritedMembers'][j].name[0].value, - 'type': model['__global']['_shared'][inheritedMemberYml]['children'][k].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([model['__global']['_shared'][inheritedMemberYml]['children'][k].summary, - model['__global']['_shared'][inheritedMemberYml]['children'][k].remarks].join('')) - }); - } - } - } - } - } - } - else if (model['__global']['_shared'][outputYml] && model['__global']['_shared'][outputYml]['children'] && (model['__global']['_shared'][outputYml].type === 'enum')){ - output.internal = true; - output.external = false; - output.dataFrameDescription = [ - model['__global']['_shared'][outputYml].summary, - model['__global']['_shared'][outputYml].remarks - ].join(''); - output.enumFields = defineEnumFields(model['__global']['_shared'][outputYml]); - output.isEnum = true; - } - else if (!output.internal){ - output.external = true; - } - } - if (Object.keys(input).length && Object.keys(dataFrame).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasInput': true, 'hasDataFrame': true}); - } - else if (Object.keys(input).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasInput': true}); - } - else if (Object.keys(dataFrame).length){ - operators.push({'description': description, 'input': input, 'output': output, 'dataFrame': dataFrame, 'hasDataFrame': true}); - } - else { - operators.push({'description': description, 'output': output}); - } - } - } - } - return operators; +function sortPropertiesData(properties) { + return properties.sort((a, b) => ( + a.name.match(/\D+|\d+$/g)[0] === b.name.match(/\D+|\d+$/g)[0] ? + Number(a.name.match(/\D+|\d+$/g)[1]) - Number(b.name.match(/\D+|\d+$/g)[1]) : + 0 + )); } -// Define source or sink in documentation by checking for an explicit Category tag. If the class does not provide one, -// check the inheritance tree of the class. If the class inherits Bonsai.Sink and Bonsai.Combinator, ignore the Bonsai.Sink -// inheritance overrides the Bonsai.Combinator inheritance for determining whether an operator is a source or a combinator. This -// is because maybe sink operators inherit Bonsai.Combinator in addition to Bonsai.Sink. -function defineOperatorType(model){ - let operatorType = {'source': false, 'sink': false, 'combinator': false}; - if (model.syntax && model.syntax.content[0].value){ - if (model.syntax.content[0].value.includes('[WorkflowElementCategory(ElementCategory.Source)]')){ - operatorType.source = true; - } - else if (model.syntax.content[0].value.includes('[WorkflowElementCategory(ElementCategory.Sink)]')){ - operatorType.sink = true; - } - else if (model.syntax.content[0].value.includes('[WorkflowElementCategory(ElementCategory.Combinator)]')){ - operatorType.combinator = true; - } - } - if (!(operatorType.source || operatorType.sink || operatorType.combinator)){ - if (model.inheritance){ - const inheritanceLength = model.inheritance.length; - for (let i = 0; i < inheritanceLength; i++){ - if (model.inheritance[i].uid.includes('Bonsai.Source')){ - operatorType.source = true; - } - else if (model.inheritance[i].uid.includes('Bonsai.Sink')){ - operatorType.sink = true; - } - else if (model.inheritance[i].uid.includes('Bonsai.Combinator')){ - operatorType.combinator = true; - } - if (model.inheritance[i].uid.includes('OpenEphys.Onix1.MultiDeviceFactory')){ - operatorType.hub = true; - } - else if (model.inheritance[i].uid.includes('OpenEphys.Onix1.SingleDeviceFactory')){ - operatorType.device = true; - } - } +function processChildProperty(child, sharedModel) { + const enumFields = sharedModel[`~/api/${child.syntax.return.type.uid}.yml`]?.type === 'enum' ? + extractEnumData(sharedModel[`~/api/${child.syntax.return.type.uid}.yml`]) : + []; + return { + 'name': child.name[0].value, + 'type': child.syntax.return.type.specName[0].value, + 'propertyDescription': { + 'text': addCodeTag([child.summary, child.remarks].join('')), + 'hasEnum': enumFields.length > 0, + 'enum': enumFields, } } - operatorType.showWorkflow = operatorType.source | operatorType.sink | operatorType.combinator; - return operatorType; } -function defineSubOperators(model){ - let subOperators = [] - if (model.children){ - const childrenLength = model.children.length; - for (let i = 0; i < childrenLength; i++){ - if (model.children[i].type === 'property'){ - potentialSubOperatorYml = '~/api/' + model.children[i].syntax.return.type.uid + '.yml'; - if (model['__global']['_shared'][potentialSubOperatorYml]){ - subOperatorChildrenLength = model['__global']['_shared'][potentialSubOperatorYml]['children'].length; - let subProperties = []; - for (let j = 0; j < subOperatorChildrenLength; j++){ - if (model['__global']['_shared'][potentialSubOperatorYml]['children'][j].type === 'property'){ - let enumFields = []; - potentialEnumYml = '~/api/' + model['__global']['_shared'][potentialSubOperatorYml]['children'][j].syntax.return.type.uid + '.yml'; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - if (enumFields.length > 0){ - subProperties.push({'name': model['__global']['_shared'][potentialSubOperatorYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][potentialSubOperatorYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin( [model['__global']['_shared'][potentialSubOperatorYml]['children'][j].summary, - model['__global']['_shared'][potentialSubOperatorYml]['children'][j].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true}); - } - else{ - subProperties.push({'name': model['__global']['_shared'][potentialSubOperatorYml]['children'][j].name[0].value, - 'type': model['__global']['_shared'][potentialSubOperatorYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin( [model['__global']['_shared'][potentialSubOperatorYml]['children'][j].summary, - model['__global']['_shared'][potentialSubOperatorYml]['children'][j].remarks].join('')) - }); - } - } - } - if (subProperties.length > 0){ - subOperators.push({ - 'object': model.children[i].name[0].value, - 'type': model.children[i].syntax.return.type.specName[0].value, - 'subProperties': subProperties, - 'hasSubProperties': true, - 'subOperator': true - }); - } - else if (model.__global._shared['~/api/' + model.children[i].name[0].value + '.yml']){ - subOperators.push({ - 'object': model.children[i].name[0].value, - 'type': model.children[i].syntax.return.type.specName[0].value, - 'subOperator': true - }); - } - } - } - } - } - return subOperators +function extractPropertiesData(model, sharedModel) { + return model?.children + .filter(child => child.type === 'property' && child.syntax) + .map(child => processChildProperty(child, sharedModel)); } -// compile list of properties -function defineProperties(model){ - properties = []; - if (model.children){ - const childrenLength = model.children.length; - for (let i = 0; i < childrenLength; i++){ - if (model.children[i].type === 'property'){ - potentialEnumYml = '~/api/' + model['children'][i].syntax.return.type.uid + '.yml'; - let enumFields = []; - if (model['__global']['_shared'][potentialEnumYml] && (model['__global']['_shared'][potentialEnumYml]['type'] === 'enum')){ - enumFields = defineEnumFields(model['__global']['_shared'][potentialEnumYml]); - } - if (enumFields.length > 0){ - properties.push({ - 'name': model.children[i].name[0].value, - 'type': model.children[i].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([model.children[i].summary, model.children[i].remarks].join('')), - 'enumFields': enumFields, - 'hasEnum': true - }); - } - else { - properties.push({ - 'name': model.children[i].name[0].value, - 'type': model.children[i].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([model.children[i].summary, model.children[i].remarks].join('')) - }); - } - } - } - } - if (model.inheritedMembers){ - const inheritedMembersLength = model.inheritedMembers.length; - for (let i = 0; i < inheritedMembersLength; i++){ - if (model.inheritedMembers[i].type && (model.inheritedMembers[i].type === 'property')){ - let inheritedMemberYml = '~/api/' + model.inheritedMembers[i].parent + '.yml'; - if (model['__global']['_shared'][inheritedMemberYml]['children']){ - let inheritedMemberChildrenLength = model['__global']['_shared'][inheritedMemberYml]['children'].length; - for (let j = 0; j < inheritedMemberChildrenLength; j++){ - if (model.inheritedMembers[i].uid === model['__global']['_shared'][inheritedMemberYml]['children'][j].uid){ - properties.push( - {'name': model.inheritedMembers[i].name[0].value, - 'type': model['__global']['_shared'][inheritedMemberYml]['children'][j].syntax.return.type.specName[0].value, - 'description': removeBottomMargin([model['__global']['_shared'][inheritedMemberYml]['children'][j].summary, - model['__global']['_shared'][inheritedMemberYml]['children'][j].remarks].join('')) - }); - } - } - } - } - } - } - return properties; +function extractPropertiesFromInheritedMembersData(model, sharedModel) { + return model.inheritedMembers + .filter(inheritedMember => inheritedMember.type === 'property') + .map(inheritedMember => ( + processChildProperty( + sharedModel[`~/api/${inheritedMember.parent}.yml`].children.find(inheritedMemberChild => inheritedMemberChild.uid === inheritedMember.uid), + sharedModel + ) + )); } -function sortProperties(properties){ - let propertyNames = []; - let propertyNamesThatFitPattern = []; - const propertiesLength = properties.length; - for (let i = 0; i < propertiesLength; i++){ - propertyNames.push([properties[i].name, - /\D+\d+$/.test(properties[i].name), - String(properties[i].name.match(/\D+/)), - Number(properties[i].name.match(/\d+$/))]); - } - for (let i = 0; i < propertiesLength; i++){ - if (propertyNames[i][1]){ - if (!propertyNamesThatFitPattern.includes(propertyNames[i][2])){ - propertyNamesThatFitPattern.push(propertyNames[i][2]); - } - } - } - const propertyNamesThatFitPatternLength = propertyNamesThatFitPattern.length; - for (let j = 0; j < propertyNamesThatFitPatternLength; j++){ - for (let i = 1; i < propertiesLength; i++){ - for (let k = i; k > 0; k--){ - if ((propertyNames[k][2] === propertyNamesThatFitPattern[j]) && (propertyNames[k - 1][2] === propertyNamesThatFitPattern[j])){ - if (propertyNames[k][3] < propertyNames[k - 1][3]){ - swapElements(properties, k, k - 1); - swapElements(propertyNames, k, k - 1); // why does this need to be here for this sortProperties function to work? - } - } - } - } - } - return properties; +function extractConstituentOperatorsData(model) { + return model?.children + .filter(child => child.type === 'property' && model.__global._shared?.[`~/api/${child.syntax.return.type.uid}.yml`].type === 'class') + .map(child => { + const deviceModel = model.__global._shared?.[`~/api/${child.syntax.return.type.uid}.yml`]; + const subProperties = sortPropertiesData(extractPropertiesData(deviceModel, model.__global._shared)); + return { + 'object': child.name[0].value, + 'type': child.syntax.return.type.specName[0].value, + 'constituentOperator': true, + 'hasSubProperties': subProperties === undefined || subProperties.length === 0 ? false : true, + 'subProperties': subProperties, + }; + }); } -const swapElements = (array, index1, index2) => { - const temp = array[index1]; - array[index1] = array[index2]; - array[index2] = temp; -}; - -function defineEnumFields(model){ - let enumFields = []; - if (model.children){ - const childrenLength = model.children.length; - for (let i = 0; i < childrenLength; i++){ - if (model.children[i].type === 'field'){ - enumFields.push({ - 'field&value': model.children[i].syntax.content[0].value, - 'description': removeBottomMargin([ model.children[i].summary, - model.children[i].remarks].join('')) - }); - } - } +function extractOperatorData(model) { + + const checkForCategory = (category) => model.syntax?.content[0].value.includes(`[WorkflowElementCategory(ElementCategory.${category})]`); + const checkInheritance = (inheritance) => model.inheritance?.some(inherited => inherited.uid.includes(inheritance)); + source = checkForCategory('Source') || checkInheritance('Bonsai.Source'); + sink = checkForCategory('Sink') || checkInheritance('Bonsai.Sink'); + combinator = checkForCategory('Combinator') || checkInheritance('Bonsai.Combinator'); + transform = checkForCategory('Transform') || checkInheritance('Bonsai.Transform'); + hub = checkInheritance('OpenEphys.Onix1.MultiDeviceFactory'); + configureDevice = checkInheritance('OpenEphys.Onix1.SingleDeviceFactory'); + type = model.uid.includes('DeviceFactory') ? false : sink ? 'sink' : combinator ? 'combinator' : source ? 'source' : transform ? 'transform' : false; + + if (hub) { + model = model.__global._shared['~/api/OpenEphys.Onix1.MultiDeviceFactory.yml']; + } + + overloads = model.children + .filter(child => child.name[0].value.includes('Process') || child.name[0].value.includes('Generate')) + .map(child => ({ + 'overloadsDescription': [child.summary, child.remarks].join(''), + 'input': [child.syntax?.parameters[0].description, child.syntax?.parameters[0].remarks].join(''), + 'output': [child.syntax.return.description, child.syntax.return.remarks].join(''), + })); + + return { + 'type': type, + 'hub': hub, + 'configureDevice': configureDevice, + 'workflow': type.length > 0, + 'overloads': overloads, } - return enumFields; } - /** * This method will be called at the start of exports.transform in ManagedReference.html.primary.js */ exports.preTransform = function (model) { - - model.oe = {}; - - model.oe.description = [model.summary, model.remarks].join(''); - - operatorType = defineOperatorType(model); - if (operatorType.source){ - model.oe.operatorType = 'source'; - } - else if (operatorType.sink){ - model.oe.operatorType = 'sink'; - } - else if (operatorType.combinator){ - model.oe.operatorType = 'combinator'; - } - - if (operatorType.showWorkflow) { - model.showWorkflow = operatorType.showWorkflow; - } - else { - - } - - if (operatorType.device) { - model.oe.hubOrDevice = 'device'; - model.oe.device = true; - } - else if (operatorType.hub){ - model.oe.hubOrDevice = 'hub'; - model.oe.hub = true; - } - - operators = defineInputsAndOutputs(model); - if (operators.length > 0){ - model.oe.operators = operators; - } - - properties = defineProperties(model); - if (properties.length > 0){ - model.oe.hasProperties = true; - model.oe.properties = sortProperties(properties); - } - - subOperators = defineSubOperators(model); - if (subOperators.length > 0){ - model.oe.hasSubOperators = true; - model.oe.subOperators = subOperators; - } - - if (model.oe.hasProperties && model.oe.hasSubOperators){ - subPropertyNames = []; - hubProperties = []; - const subOperatorsLength = model.oe.subOperators.length; - for (let i = 0; i < subOperatorsLength; i++){ - subPropertyNames.push(model.oe.subOperators[i].object); - } - const propertiesLength = model.oe.properties.length; - for (let i = 0; i < propertiesLength; i++){ - const subPropertyNamesLength = subPropertyNames.length; - propertyNotInSubOperator = false; - for (let j = 0; j < subPropertyNamesLength; j++){ - if (model.oe.properties[i].name === subPropertyNames[j]){ - propertyNotInSubOperator = true; - } - } - if (!propertyNotInSubOperator){ - hubProperties.push(model.oe.properties[i]); - } - } - if (hubProperties.length > 0){ - model.oe.subOperators.push({ + if (model.type === 'class') { + operator = extractOperatorData(model); + if (operator.hub) { + properties = extractConstituentOperatorsData(model); + properties.push({ 'object': 'Misc', - 'subProperties': hubProperties, + 'constituentOperator': false, 'hasSubProperties': true, - 'subOperator': false - }) - } - } - - enumFields = defineEnumFields(model); - if (enumFields.length > 0){ - model.oe.hasEnumFields = true; - model.oe.enumFields = enumFields; - } - - if (model.uid.includes('DeviceFactory')){ - model.showWorkflow = false; + 'subProperties': sortPropertiesData([ + ...extractPropertiesData(model, model.__global._shared), + ...extractPropertiesFromInheritedMembersData(model, model.__global._shared), + ]).filter(modelProperty => !properties.map(property => property.object).includes(modelProperty?.name)) + }); + } + else { + properties = sortPropertiesData([ + ...extractPropertiesData(model, model.__global._shared), + ...extractPropertiesFromInheritedMembersData(model, model.__global._shared), + ]); + } + model.oe = { + 'name': model.name[0].value, + 'uid': model.uid, + 'description': [model.summary, model.remarks].join(''), + 'operator': operator, + 'properties': properties + }; + } + else if (model.type === 'enum') { + model.oe = { + 'name': model.name[0].value, + 'uid': model.uid, + 'description': [model.summary, model.remarks].join(''), + 'enum': extractEnumData(model), + }; } return model; diff --git a/template/partials/class.tmpl.partial b/template/partials/class.tmpl.partial index 0e25a93..681db95 100644 --- a/template/partials/class.tmpl.partial +++ b/template/partials/class.tmpl.partial @@ -1,61 +1,61 @@ {{#isClass}} -
-

- {{name.0.value}} - {{#sourceurl}}{{/sourceurl}} -

- {{#oe.operatorType}} -

- {{oe.operatorType}} Operator -

- {{/oe.operatorType}} -
- -{{#oe.device}} +{{#oe.operator.configureDevice}}
- This operator is a device operator. If you are using Open Ephys hardware, use an aggregate operator that corresponds to your particular headstage(s) instead. Aggregate operators confer the following benefits: + This is a device configuration operator. If you are using Open Ephys hardware, use an aggregate configuration operator that corresponds to your particular headstage(s) instead. Aggregate operators confer the following benefits:
    -
  • The address properties of aggregate operators are automatically configured whereas a device operators requires manual configuration of its address property. This improves ease of using Open Ephys hardware.
  • -
  • All devices that belong to a hub (which is a collection of devices i.e. a headstage or breakout board) are automatically included, excluding the possibility of omitting configuration of a device that belongs to a hub. This improves ease of using Open Ephys hardware.
  • -
  • The workflow is less cluttered with configuration operators as one aggregate operator can correspond to multiple device operators. This improves workflow readability.
  • +
  • The address and name properties of aggregate configuration operators undergo automatic configuration which reduces the risk of erroneous configuration.
  • +
  • The workflow is less cluttered with configuration operators as one aggregate configuration operator corresponds to multiple device operators. This improves workflow legibility and expedites the workflow scripting process.
-{{/oe.device}} +{{/oe.operator.configureDevice}} + +
+

+ {{oe.name}} + {{#sourceurl}}{{/sourceurl}} +

+ {{#oe.operator.type}} +

+ {{oe.operator.type}} Operator +

+ {{/oe.operator.type}} +
{{{oe.description}}}
-{{#showWorkflow}} -

{{name.0.value}} Workflow

-{{/showWorkflow}} +{{#oe.operator.workflow}} -{{#oe.operatorType}} +

{{oe.name}} Workflow

+{{#oe.operator}}

Inputs & Outputs

- {{>partials/diagram}} +{{/oe.operator}} -{{/oe.operatorType}} - -{{#oe.hasSubOperators}} +{{/oe.operator.workflow}}

Properties

-
{{name.0.value}} is a aggregate operator. It comprises of the following sub-operators:
-
+{{#oe.operator.hub}} + +

{{oe.name}} is an aggregate operator. Its properties comprise of the following operators' properties:

-{{#oe.subOperators}} +{{#oe.properties}}

{{{object}}}

-{{#subOperator}} -
{{{object}}} is a {{{type}}} operator encapsulated by the {{name.0.value}} operator.
-{{/subOperator}} +{{#constituentOperator}} +

{{{object}}} is a {{{type}}} operator encapsulated by the {{oe.name}} operator.

+{{/constituentOperator}} -{{#hasSubProperties}} +{{^constituentOperator}} +

These properties do not derive from a constituent operator.

+{{/constituentOperator}} +{{#hasSubProperties}} @@ -69,24 +69,17 @@ {{/subProperties}}
- {{/hasSubProperties}} {{^hasSubProperties}} - -
This subclass has no public properties.
- +

This operator does not have any configuration options.

{{/hasSubProperties}} -{{/oe.subOperators}} - -{{/oe.hasSubOperators}} +{{/oe.properties}} -{{^oe.hasSubOperators}} +{{/oe.operator.hub}} -{{#oe.hasProperties}} - -

Properties

+{{^oe.operator.hub}} @@ -102,8 +95,6 @@
-{{/oe.hasProperties}} - -{{/oe.hasSubOperators}} +{{/oe.operator.hub}} {{/isClass}} \ No newline at end of file diff --git a/template/partials/diagram.tmpl.partial b/template/partials/diagram.tmpl.partial index c87f104..f273d26 100644 --- a/template/partials/diagram.tmpl.partial +++ b/template/partials/diagram.tmpl.partial @@ -1,6 +1,6 @@ -{{#oe.operators}} +{{#overloads}} -
{{{description}}}
+
{{{overloadsDescription}}}
@@ -12,9 +12,7 @@ {{#input}} @@ -39,9 +37,7 @@ right-arrow
- {{#internal}}
{{{name}}}
{{/internal}} - {{#external}}
{{{specName}}}
{{/external}} - {{{description}}} + {{{input}}}
right-arrow @@ -27,7 +25,7 @@ - representation of a source, sink, or combinator operator + representation of a {{type}} operator - {{#output.internal}}
{{{output.name}}}
{{/output.internal}} - {{#output.external}}
{{{output.specName}}}
{{/output.external}} -
{{{output.description}}}
+
{{{output}}}
@@ -49,66 +45,4 @@ -{{/oe.operators}} - -{{#oe.operators.0.hasDataFrame}} -{{^oe.operators.0.output.useInputDataFrame}} - -

{{{oe.operators.0.output.name}}}

-
{{{oe.operators.0.output.dataFrameDescription}}}
- -{{/oe.operators.0.output.useInputDataFrame}} - -{{#oe.operators.0.output.useInputDataFrame}} - -

{{{oe.operators.0.input.name}}}

-
{{{oe.operators.0.input.dataFrameDescription}}}
- -{{/oe.operators.0.output.useInputDataFrame}} - - - - - - - - - - {{#oe.operators.0.dataFrame}} - {{>partials/propertyTables}} - {{/oe.operators.0.dataFrame}} - -
Data Frame MemberTypeDescription
- -{{/oe.operators.0.hasDataFrame}} - -{{#oe.operators.0.output.isEnum}} - -

{{{oe.operators.0.output.name}}}

- -
{{{oe.operators.0.output.dataFrameDescription}}}
- - - - - - - - - {{#oe.operators.0.output.enumFields}} - - - - - {{/oe.operators.0.output.enumFields}} - -
Field & ValueDescription
- - {{{field&value}}} - - - {{{description}}} -
- -{{/oe.operators.0.output.isEnum}} - +{{/overloads}} \ No newline at end of file diff --git a/template/partials/enum.tmpl.partial b/template/partials/enum.tmpl.partial index 66b28c6..1aaf6d8 100644 --- a/template/partials/enum.tmpl.partial +++ b/template/partials/enum.tmpl.partial @@ -1,14 +1,12 @@ {{#isEnum}}

- {{name.0.value}} + {{oe.name}} {{#sourceurl}}{{/sourceurl}}

{{{oe.description}}} -{{#oe.hasEnumFields}} -

Fields

@@ -18,7 +16,7 @@ - {{#oe.enumFields}} + {{#oe.enum}} - {{/oe.enumFields}} + {{/oe.enum}}
Description
@@ -29,10 +27,8 @@ {{{description}}}
-{{/oe.hasEnumFields}} - {{/isEnum}} \ No newline at end of file diff --git a/template/partials/propertyTables.tmpl.partial b/template/partials/propertyTables.tmpl.partial index 84d3b9e..16135ee 100644 --- a/template/partials/propertyTables.tmpl.partial +++ b/template/partials/propertyTables.tmpl.partial @@ -1,37 +1,29 @@ - {{{name}}} - - {{{type}}} - - - {{{description}}} - - {{#hasEnum}} - -
- - {{#enumFields}} - -
{{{field&value}}}
- -
{{{description}}}
- - {{/enumFields}} - -
- - {{/hasEnum}} - +
+ {{#propertyDescription}} + {{{propertyDescription.text}}} + {{#hasEnum}} + + {{#enum}} + + + + + {{/enum}} +
{{{field&value}}}{{{description}}}
+ {{/hasEnum}} + {{/propertyDescription}} +
\ No newline at end of file diff --git a/template/public/main.css b/template/public/main.css index 47c3b67..ecfcea1 100644 --- a/template/public/main.css +++ b/template/public/main.css @@ -1,9 +1,47 @@ @import "workflow.css"; +div.tableFormat *:last-child { + margin-bottom: 0; +} + +div.tableFormat table { + display: grid; + grid-template-columns: auto; + margin-top: 1rem; + margin: 0; + padding: 0; + border: 0 hidden; + border-collapse: collapse; +} + +div.tableFormat td { + padding: 0; + border: 0 hidden; +} + +div.tableFormat td.term { + /* !important tag prevents overrides from dotnet.css associated with: + body[data-yaml-mime="ManagedReference"] article td.term, body[data-yaml-mime="ApiPage"] article td.term + important tags not good practice*/ + font-weight: var(--bs-body-font-weight) !important; + white-space: nowrap; +} + +div.tableFormat td.description { + padding-left: 1rem; +} + .quick-links > .table-responsive > table.table.table-bordered.table-condensed { border: 0px hidden transparent; } +/* div .tableFormat td .term { + margin: 0; + padding: 0; + border: 0 hidden; + border-collapse: collapse; +} */ + /* .inputs-and-outputs > .table { border: 0px hidden transparent; table-layout: fixed; diff --git a/template/toc.extension.js b/template/toc.extension.js index cac0e81..690e17a 100644 --- a/template/toc.extension.js +++ b/template/toc.extension.js @@ -20,13 +20,16 @@ exports.preTransform = function (model) { }]; for (let i = 0; i < itemsItemsLength; i++) { globalYml = '~/api/' + model.items[0].items[i].topicUid + '.yml'; - if (model.items[0].items[i].name.includes('DataFrame') || + if (model.items[0].items[i].name.includes('Frame') || model.items[0].items[i].name.includes('DeviceFactory') || model.items[0].items[i].name.includes('ContextTask') || model.items[0].items[i].name.includes('DeviceNameConverter') || model.items[0].items[i].name.includes('ConfigureDS90UB9x') || model.items[0].items[i].name.includes('ConfigureFmcLinkController') || - model.items[0].items[i].name.includes('DeviceContext')){ + model.items[0].items[i].name.includes('DeviceContext') || + model.items[0].items[i].name.includes('NeuropixelsV2QuadShankElectrode') || + model.items[0].items[i].name.includes('NeuropixelsV2QuadShankProbeConfiguration') || + model.items[0].items[i].name.includes('NeuropixelsV1eAdc')){ model.items[0].items[i].hide = true; } else if (model.__global._shared[globalYml] && model.__global._shared[globalYml].type === 'enum') { diff --git a/workflows/operators/PortStatus.bonsai b/workflows/operators/PortStatus.bonsai new file mode 100644 index 0000000..52ccacf --- /dev/null +++ b/workflows/operators/PortStatus.bonsai @@ -0,0 +1,14 @@ + + + + + + + + + + + \ No newline at end of file