From c3bd55b868c85c17c02d0c9389e779da4b6f2c20 Mon Sep 17 00:00:00 2001 From: Bart Jablonski Date: Sun, 21 Dec 2025 21:32:33 +0100 Subject: [PATCH] SAS Packages Framework, version 20251221 SAS Packages Framework, version 20251221 Changes: - 3 new macros: `%relocatePackage()`, `%SasPackagesFrameworkNotes()`, and `%isPackagesFilerefOK()` added. - Documentation updated. --- README.md | 3 +- ...(a how to)- Paper 4725-2020 - extended.pdf | Bin 336361 -> 342744 bytes SPF/Macros/extendpackagesfileref.sas | 4 +- SPF/Macros/generatepackage.sas | 16 +- SPF/Macros/helppackage.sas | 4 +- SPF/Macros/installpackage.sas | 6 +- SPF/Macros/ispackagesfilerefok.sas | 149 +++ SPF/Macros/listpackages.sas | 6 +- SPF/Macros/loadpackage.sas | 4 +- SPF/Macros/loadpackageaddcnt.sas | 6 +- SPF/Macros/loadpackages.sas | 4 +- SPF/Macros/previewpackage.sas | 4 +- SPF/Macros/relocatepackage.sas | 683 +++++++++++ SPF/Macros/saspackagesframeworknotes.sas | 165 +++ SPF/Macros/splitcodeforpackage.sas | 12 +- SPF/Macros/unloadpackage.sas | 4 +- SPF/Macros/verifypackage.sas | 4 +- SPF/SPFinit.md | 253 +++- SPF/SPFinit.sas | 1078 ++++++++++++++++- SPF/license.sas | 2 +- 20 files changed, 2308 insertions(+), 99 deletions(-) create mode 100644 SPF/Macros/ispackagesfilerefok.sas create mode 100644 SPF/Macros/relocatepackage.sas create mode 100644 SPF/Macros/saspackagesframeworknotes.sas diff --git a/README.md b/README.md index 5a28502..70f168e 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ Don't forget to give the repository a **STAR** and become [stargazer](https://gi ### Current version: -**The latest version** of the **SAS Packages Framework** is **`20251126`**. +**The latest version** of the **SAS Packages Framework** is **`20251221`**. --- @@ -190,6 +190,7 @@ The SAS Packages Framework [(short) documentation](https://github.com/yabwon/SAS --- ### Updates worth mentioning: +**Update**\[December 21st, 2025\]**:** `%relocatePackage()`, `%SasPackagesFrameworkNotes()`, and `%isPackagesFilerefOK()` **utility macros are available. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241221 "splitCodeForPackage"))**. **Update**\[October 27th, 2024\]**:** `%splitCodeForPackage()` **utility macro is available. (see [here](https://github.com/yabwon/SAS_PACKAGES/releases/tag/20241027 "splitCodeForPackage"))**. diff --git a/SPF/Documentation/SAS(r) packages - the way to share (a how to)- Paper 4725-2020 - extended.pdf b/SPF/Documentation/SAS(r) packages - the way to share (a how to)- Paper 4725-2020 - extended.pdf index dfa399e0e8b8bb2d37857369f34d959b7758e025..ba9ca2d7fe0eaa448c6f506566fc79b4b72e003c 100644 GIT binary patch delta 86249 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 Cg~^ft delta 80505 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

VU+hC*Kg%y2HYijy{nt@OPn*=aS*tz z$1CX{VizIMFYG+-lH6rVX%~Z0RJ_w}Hj4eLatyuSVa*ys`RZFk%N1)x(jRV2#l7Hl?t)i4TALf228)W34c4XP+zZSCM+*jOU^CX~0#FWB`fzGTUL-OZd|+O;|O zeyY7^@u}00CxYa*fZ9%WIs5&s804vI&d^l6#J6A1GIPNhUuO zl5#gulTPG?lAeA@VX^W4tM!TZAJ(VWyZq0ouK$b5cczV|v@{NUpo8AU(q)}m?-iU( zp*7sN{VwwINz-V&lFCJoyfR!W7B9pt|KR?vABiG$tldr3rf<3LY}~CDA-s88ANK+smjff ztu$rHECe_!RP#CV_?mc}7CD)6iOpsr$muXqcBsfP8yzQ2ZY?LEeS_pt9NlM8VoS`Z z&t`_s5TGNCYZ+Z>`^F?SBsLL9fZE zS~eqwT^npzIl-S(h5Xv0zmW0X(Tw>Ep+xAaKGNL{7~s&ZNB>Gw1wg% z0+J;Wi+a&9BLDRWzWS(z(eFfr@kT45A5M#0FQ*2Q2l1^NM4y^5%)DZzNvEPujj$k` z5r7IZ%8ZmTplXya9)ZzEzgCgK$ml(}^w!5|AE>t;P0dEpC|(Ix9m=pA22>>%K^a~c zl9GHo&ploSMNWNaG(@l}8QwV6rtZ)yS@9Q*rV})5z|@Hpm_WM6z6g3m2M9l zC0mKqOT2Yh)?~}PosNCa(2&3bF3C7d3O+$8bcnY$$$>!$a5qQCjJTC5VG*tVT3+p28fHihE(g_(}(X>tK|$$ul> zQ)0pMOS2g)0rO5bBY`WF?=KL}I^H(GNKYl%(+N8#iRDs`xqljcif8&W3hL~OdrXoL ztdqcEgF@6g&+hk)@GDxj)H=P{($b6KFdymu`C`WrdBVEUQJ)%iaMBbs3i8C~WPCFr zSPkt3-AL4TbM23F7^(;N`9D!}`pBOw7_*ljl4zA`rtg+3j#xD3TsA=C%vF{g(BB^p zsX<~iWr_ifLyd5ucSoyZNo}TJ7iZgnK9J4%2e!7zOw#9>p`Ab2@6>o5FD8BR`hTao5D*Q`>w z9=cbr_-VxyjW8sPyo6xmP%MH~z$e%5?pfB<?O=|?}Ljh#5SpTJt3}pRXN2Z7ReZkl5 z_W!e%`0vyKBRC8afC3iG1HgmJpaF+a7?aK5WEemU)Bw+AGZic#0~$aH?nVUQ0$6`f z3i~f=<39@vAS>9}9>7Gw_8(^TSE>TY`d7;vxcV8I?7t}=sNi}efD$At&nxCb2CRS# z5Q5?O-FcYA_W0(v2N}r5`g@MxC1e05fE9d#44{K#<^BIV-DGG0cJm?%02S~Ge6>dd zAE5$BK>%@>q_nefu`!d$^NSdU}M2Lt>0Zm=+%>HAZ4As z?+Lb<*^9$_H!N~vKRz;EcaTR*=m*|+ZZagbyC^wITg=&j==Cv>SZb8qYIVh%i9>r4*nx**F?lBtHuwHttKT|nIn!tq{Va1A| zXjxalzMS#&0bT(12%046Vs#EOD9MknKB&8tTLx{O?1fB#qG>wmdw=(mq;o`@p1iew zBBh}d+2^+ae+f>7ZNcoz=SdeUwT}?@qY6LcmQ$;G5EIEP^#d$py3qw&CHFGV8{PoU~ zhyDj}@`2Xl-owpqIA47?d-n5o?5MlwvLaoCSE(r4gV4PiXvoQO*I6s{3RbEacxaCx?i}x_PlKMA z1a?Fg9B0}U?n<4=*ISkxM9T2RX`l#6lGs%(=gr>)l5+T)ro`K62~+odpWO{SMerd( z!x5;9P}ck;gKSM-?e#dog0t2MBu-phK4W#uA zm<%oAd!-MVYgh#~G{{sob5=PQ+8X>)dt7z`yQ;!0D~n%yxd*-lV)@Wk7 z0BBA8Y*JLgCN7!oQ^&z=2yb&vG}Ev?=;FukI`=exGQBHpHU$O?MU>20YPS#WHxu!=+G{x^FeG9lVQwvew$3cSZN;x)?pJF6;YHAWi?Q&6;K|R=UA6&f8~UI zXY#(nE=2oKG5OQjJ0{DTu=Zv?vc>7H_mC<*xNGiD99S10Je~HeSAg3ed_JNsbMB2V zSxug%`&mHadf$1mR)^w;?31m*hr7JMr07yp0U8Qm!uLWK8Qsu83c8J#!-`xs99aDJ zh#@346FekzI>+%du!NRVy5C)q;d;B-3@E@CH+f8@qHy`)?HmWWknLhzF}8zC9NWrV zG4|WE-=*LxZl2+K@C#=^3A|eW{>hsr2oBuWS9L*uT%#zVQw!q+g3wRVs*pZ}R^DXG6e!Hn7Tsv3y zw^r%;WF#^m3J;h_Y3pINuKu8fW*e?i_Cc=(dqi?#{l>u0$~yWRA(Um$q8jgQr0NFP z*uZZRoo<%+=!V$${2o!Wcu*u;nBSUViH}iRn-^w^E}_5}N1Sc@cd>4x4EGdVjQ2@T zi5lDt#s#P#KqZ!99MzAS(cilVjxx%9&qwCZMUPtrsVAs^6QLfZuL!VKX@cs#*Oitv zAt|=s0?QfGebz!{SlMM*?k%h$)5Cz?rWOg06*Jt0V5eAa?WDt}E`v+K-`CrHz)>l{ z%zh_ul=->eausg-6_MT%ZaiPSqrO}gqL@g zD`Ni!WVq9&lusz^_Tj;Z4*}fWM`MkRvrntS(j&#Wd4?+ARt6C@>n-#NCyT<=Y2qRc zZ+|n5o|$B~O(QMVMg7?r>;$fvkTYrA(u#(1Xe`!_@>U_NIN4fz?pUPoG-=&r_Ej?C z9aNs5S}6apgxj8wzJ(3s(y)dImkQFrGS>J8a+Ez!rKFjzykEI}pKfn)n{*sYlcELJ zvJn4+v)EB4*H+g-PBvTM0-fc+?fkCeJ;RnV01K^BzlidRvQlt4+XR8bMH<{XAL;4I zS~A8pWxc%bj3_*|LpOEQk?qe*2X#HIpx6W$k=l2Ls7~^JHJX$9Bte@ zsJ0b4F`qdOK21Gl9kD3a1V-vI|TQ{Np!3uY-=iC-`*iQg~ zt~)O|-vjvaTGvAu(x3BEelN27E@Y#ZQoV-=J`8MLa((Bb$*PUUvGei0}Ngqw|&uw#rBOyc+SV7sHn< zQE%5K^o`rnL`-NM?MW0-W=D5}(~5kS2V{ zl(CiS8;rBkO{kfN@@;`Ttc&+_8`2RvZc>dV)DPZE6Mha=D=0S`Pawz@0P@<3_{oe~ zpqP$@kl3{Z#w%&HD~Q+A2O;{+Zlf0E7ub|{<{Unwg6h#oEvgMS?6_E(R`JxU;n4$c znVe%!N_pUP7$%*SsHm!<;xL!zfRR>AKq8N%s?_`z{k$4ifz}jLKhN7)U~tT!A4A|Z zeHGw-LWw5cNXX!V<}5`Lq+g{UM|YAtQ@x^8j{2_T*iTdpoii-h_9xSEc;(#=LfI+N zKt!R%M&ggFdOa&yo4w7f45aYh+6(bH7}MdCtxwGGy4QDj%*D%{3ui4m$NgJI2|Wmd zc%fp~W&(jb1#{TrM?z>dC7m&(0sG&QjvY#jPq}oPJU=(*D6!Tr zEw*=_l3O!>b}Vr7%djlH!~8zx3h``nT3f`m%e}!N9rwlLGUM^Zhjj6|2kajz!;mB0 z-A7sXb!H*}0M~(_^m;PT-R=3}VRYiH%#IXei5s2W63&WL4mprj%~X@_6!P$r7KcF? zTodq4%eE_64W@NQ#%j|~#Y^Cy=7L!12D@eM#A z_wT_`{Cm{<57;G;{V({XK6r%)pb4hn2Ppkn=yv|sC>p9A^7 z*8%?7BKl7Y%+3M67XZ9Kk>^@B{}2R-!9sy1CBbZbfWPt)6xjcsj$r?tj$ot#{(~>{ zPYe9&HvOB80m%L*;egG?^Dl}2*AKw>5&#Cs*K55_;D1HjzT@Ja%G zb)kbFB>)dl+_(PCcai{c6sXJ>z+dC${j>HQ|7O7jvj4W={>Op8x@rGq;D0>0U?_FK zE3Ak&>0J^%7*62zZ}3`z`QLzZ{`S!P&6)AnkMh?O#K8gnr4GOWi_}8Wg9SAJBOr^F zyPg3se)Ii{>-o}6TH2)r80@O-D3 zpT==qpI3+MYoukd%R`Vkck@YX+(*bFRbkvjrSRYqTnQ1HrrQ1{`=f{XQWL1)nh_2s z-(%dny^O#Jc+36}bDc@>{z%B&e2m(st^1*_ImWy|dq`GOf~5!+k^6Y$OtaFYY!Yji z;CNS5!H&-x`Ou(H^KyF!S)8;wBr%X$ApdTY1mX=HugI_ij{+DLGMy1# zXF%ePnp(M@`2jm}3D6Z_ECq5B=aUf)F4bm5)axZ4iAoy^YP#Gws;RoTNw zo1o89`Hblr%@+0gOW)Ds2U2#2GnS;K^)h0^gCUqLdATDhORl1)hcgGb6jCiw9I!$* zZF&lz*vDi}h8m|IXrDk;Hbc&5HRnRrMsb$83M`|KOrJUabk;Dy+TQ zdx;PQ!eI2=5f-(>DEh7}NypUmDg4 z-|wWnqe}$$AeQ*rP=9eDKO0J06xaYTT9PgwC4BiA~p)Z_iW45RqXn6BBHEY** z2_+Xudd3DNqHbY|vuZi-F-UG}xzL0%1J_4dO`GFRn+goL+c?DGf2N`i@D55V zmdJ~PZZ;h+&PiU#+p~j@K5%$pEyhd-T7+8qK7L8}l3+3@iUO%#_Y{oW=sX6SYoBXD z4Oit7SR8_y$6SMfc@Ma3DY^OqUOX&qhyQZmbClz8X)1%lru&3 zrleU!^3p6@chS&=CIZ)7iFx8!80535U1|fJ(Q#m6rl_^q+=r<&(J&D{Jh#sh`63sNgzkzaFwBPfcRv`hdl?fo(nY+4?6QhjEOnS(~q`X$Q6O zClpu^fHKL+{>gzR5GkJdfET>x?$gNuM_;=0(MVk%J9xe6wZL`aVsIK>K79$95^lsG z8=u1Q5Y(pj!6XV#TfGP+@3JX1p*@!e$&_Jo`|1WDXJ03gF~oVRl#-wK5EL1}p@`5N z$`-0`_wr0{I^uGJ;QJVk+4u%!lMFPUw2fYdXV9{GIZ+EFHcVVPQPZuCPr zG`v2RrS20WWjwecX*fsxF}RFCV`64t%ZNTAyll0ImX*puDH@(Z5iv4SgRS;UtiX6M zbKsGK@u0Js{}i+03y<;F299DjT8=)tIlcW1gG1Y>iIJxbMkc`K+X%%v|q1oviVA5KjyRQ8?V259bPiljDNl7)EbJ`Q-X1Kx7~-`KGs+3{yEPN zh*wIANCn0oMZLKf#-umud4-?T6O6!=46YF)x#9Yzz^A@wke$QBbdIMSrBu!s$J?m) zpPM!bY=k2L&G|2EEO-xB6-cf@P?o3;Nj$-(ybV;iGZKLuK~r}u zaQEl)!sloX)&@CHhLti@k+{S4^*rEyqd+RT-J%ZP4!LaR*moV~Sgn?VE$UCBo~<`m z9ODvs&ZR$oK$!2qHQ>+lsJYFU04s_~it>Iyi?)`G^V+LpbPF3|bk~%E;8}e&Z~&(I z5@g*`w{u)-vD?w!;31PbMN?{mm=1yrGGbkR$0*>>cW&pAaRy0)m_9pFf!|x7S~y|% z=K3;hgV_Y&+q3wPPZRW=!<;GY@z=FbS(4J`VB1!4p^m+0jvE8VP4q}3ZK4|jyGv2R z->ru>S6hj-=vvWQAx$^C&lj}v&{ ztJy(q?rl2T)6&>^$zF3Z0#vx-!Ei@`{e6N@c#f}dH5J-Rrv`=B50WwCU@_xf;_j3j zD>b2!w~u;S-1#(eI>Ryo3qJWp2eR{OaKxfRZM8RH3vnEJ0**n8{LGyaJKR4RdBQZ| zukImO;d@7L`QPEXOuuvFs`dKdL`kO3}TnKlcv?w3)7Gwh~gdaszktBD@z>#Uq z;=S>+5z%i<&Olyofz{O`{JvvyBmEvSg^<4CJDyVCx55KRGf!af@*t-{V(GXrfh&W5 zY8&b*(%nuHTK_7FeJc3v_1B`29Gx#;%l||szl?KJ=Za&Y}ox8QJN01A@4 zxr3#f6&a9|hx@f*lpc&?3K#^T7boj-zdK*kTguxxZaD2Wai=f;iY$1<*`{;PA*MBh zENaMJXdfyXUpI+l)PHv~z%dY7Jv3G>+B0h+0+pj2)F8SxuRXH67eeEmR-(i}6=iW$ zUMWPkMI@Ncxy{DdN)axUbfs4^3c=3W7amAN=(0>a&iE4t)(M3pGx8J(>-jp8l3O> zjSgHnzTnh692fFYU9(5WEdkfN1I3ezXQ^nF*Gt@(RB zP{nq_e!EY$Wz;NCW@_{}vGQWlh3N-YXK1%XefST$2XPJvuH?jvewnm`J%+aq)&f(J zZWA+;QH0?7H+nUo5~#i~UC`1{+lS|$-A+XnIp(Er?AD4UbR>}G;5=kVmni&=kZuDF zQ#@*Vt`<5p8xbOxekE&QOV(cFzI1;0x&2XQ?L6)&x!&Rqqg_%aNFYC{2B-aHpvy%{ zutD%a0ZWu|fu>10chbZK=Z;ya!Bni>Gp8gf(eKE*dVu%{bhu;P+L2`v?bftm`svBe zvsZ%2v$sl?Gj~UzO~y6F*hqQJ`FRG8nK08;DyvSKt$ztHc)%y8HryM7+b~_ZTUj7^ zeG0|EVSl%3T`P7&c42NxfP=m9@IA#`QE;@>Dvv&Uf`*<4TXYd1qRo(&00~G?aeQ67TQFu@{{j@SLRQ6os#d1lM=|G`B72+b$D*xJ-<^VR z{zX%$_#!ri)!9)r&j&?PC$z9>gH;-@-g>81eR8Z1jqzw@OJsxlW)p|m90L~viJ#QT=9bhvd%o`g|BVCuI9(T}REj2~;{ zeCfy*S5jPo(N6v9ag~gD%BSzH=0d0^h}TeM0!vY3jK9!yx=|IBc47&YhgYEsnB^`| z;;d9?9EW`$GS@MupKUa@fub?%W`!b{RyeVaIR62$eyNvLiumDbR7wrt+OAF>%*=!2Ot_n!XOfX7i^;hWArhH&j z05UYk8#n{E9_31B()TJLuIS}7rB&ZWOJd9oI%~t;U?1x1cm>;6Vn#)9Ij-sPS=1BI0D|B=aEiM&WhiK;Ku$<=s zV3XD3L8N9^vJ}rVMmanF{wBRW^h4yIDQ`6&;JnRLSqr9%fi}EaZw6Ly-D{A`rRyjr z!7}MJFvKkwpf9;?Gar3qAz;idiz3^;8eDp|c^h0vJFdagw(K4>$#E^64SJ*xh227- ze48B-q!se_L00;BGL|%(qhx?8HAHk3*DOxh!$#V#R@dDvs7(d=&0CU9QUG%eg48hE zT%u`d|HE-|aZ~6Gk=W=O{|4Bmf}`6MC8R1Xt_sI1BTC>d|`q@_&t3ei-8$ zu*~?>mKcuyl+bK=hu_k=r0e#p!sk3xtd%8f=FwvCnR{xxp>($M0nf1eSKH>jL&c($Guh=w8w02bS-*Gwq<|m_93bZ(9{1mjGn`rB`KQ2yi{U*8CE1iXDE{QW-&hks_|{VfspHx=;@t?A(2+Nh1G7+LPw z4dCd^&{K??n#xw4YSiCwAsTc4QvU2!;xZH!+O_3F=Vwu|lUPsjmY|i=U&FrIlCR13 zqsmuy{i#TzFw~QPMgMqw`9ctm9RlN|;}NKHbIB<>Xu#8dh{A(ey&Lt^C08e-gLl{ zswYb=vw5hIYYleCe~gqNSTKk~Z^xUF$AKCd zIkk9BixfFFwFTAzh#W&<&ZZN4I{q9FeD)Tlrkdn&me!gz6vYwqcjT ze%X&$8Ot{){_>O0tN+n8`!aF<4`#BP!hh2UU0V#Cw&m|$jB`Ot$T#DF-MXB>b}N=%gCrNK@nP1$DE-|a%0e^ zC?!mL4r#l*i)yzI-tycoY1PYJP$k^&-+0I76D!xKKEx6pk##)2#nFDRjh4UEirkys z@vWEBZ>NKPLh#o0RIfkIjdAv}e8tN!vwfZB>uH61Ngs^Jz$lcWL;Q z3>V=i{_RWy&;DM|7Te3LJv!t&dj8%+&+g?WBvTcXtyJM2es35d@1P)1YhAfyPn6pw z@Rv;lJPfbhtgvVj8^xvo0Tr(^Dm*oO(Wt01Z4@5I`>!$@Ac0loAq!p)PDFlR%EY}R zrq8tAm;-NN39LAu=`@d3J*qiozN9JFYvdc0GQA6xNZ?{Kd5BEwOh{nmgHiP+9A3E= zYemfMO4zMnoX{2(-1d#HDEO4r&is}@p9wk}Wm4~wiy%;VKygEBpR$U!f;THwVb902 zJ}WVfM>eUWRmBFod@VcOd8Kjb%Zqky9Y%d1?kB;aSWqSF4R-`F%IEGG-rTx0ZRakc zZ}rOzQ^TcQrUENfS&u{3DYNS%c+--@R1o3{CwqZ++&~t&v)%9NT zq6PUF4w&97+Ox>r-GyIqIOLikpO{?-Xp{0+x5RnUIca_L6_d4V_Qhq4Gcrr-%%17? zD#wSDj6iM))uq!{*z$n$wgQy_xvz=hTTQLc!@2!34wR~LU+uSdqco`=sTgFO^^F(7 zf-><==M8@JT919gp--1v*4wAkA0?JpDD`&N=l+Yw7(5LOduGEGxYpG8)Gy`RDlyn`+Xgs3uot z4iV51PDYbQ;x3_Q*yr3QwQqU0rS^Kv-Ft8CcUL1FrzhTKu38nh#KW2dtQvjt$eD59 zd_BhMg)UL#O95q4oRF)|hAk|gIU7b3mrl~|3Jq;ts7g!PNOJ{o@k4Zx56XjsJ@$Qj z(~d_Ra~$uGlxq>LbH{gvWLq23(sW2wJHNO9N{Ab9aH6J>!gxg>^29|obPO3qQ7nJW zSzbhxj)coojNA%v>RXMHVP^BwcC1#SOG+!qAnJ!hPwL}3Gyh`!WDI$x>N;bb(IoJ) zJI67g>OBiO5#R8R1p>ULezEKRQINao#M1|(>S_L(5o8>22YWKEk$WF> z;Iio;Ti=oaWlp#dMD4_{amOm{g#*qPcGE^e?}@swbTn$opn)*!67e?lC}Bjun{;>Rx1{k^vZZO!RWff6xij0;`;lnKF#A5$ zylM~XAwA2n%HvytWhfcjWkVbIX)lP&WZ=56zOp^SfrDmC#f- z#c^VPO8+x= zvr|i4z9G7~1M>6xBlpsqV<90^`_*qu=#w~*JbGNt)p$)%RT>()$hIV_@HIi;_W|SORBqc>~(|CwrfLPEtvU2bg(H(nYuwt9k<~RF-x4xgC^TtOFx>e_Erc!{=u!ykY-R{Rd zH@s!mv(em=TOh;?@`iUcO0NHsei0^6d91?zQY!g5$26Me%gg;C;fqnW0y45Pjg_`{ z)^xw{Fkv;};VP|8%)YGSyC68HBG>~o!!>-H^iR1WzAOzviM4)7=jN5RB-M8@YLtGA z)AI3=ki(RfrXM-RJ+ZK^7@f)@#KfQNHHDVV&NT!lsDX~M+Z-QHdN5{UrW0SwR-U1= z?a%}~6#}Yoem+d!VzN0uTL(9Aq}@}uc;q6)&pD$h;o{Hnd#@Z;DD!3KZdqIGG_esra6A9uQjQA4Hz!r7N=XdU@6WcO-#M87M?Q=j>gxxfs=2^;ay5@+BO*|_QVm@wfYy$&1^xiq@@9!^Dd zrv()pXd4er=swS^l2?gybw<#cuSdKPs+Qlf#XmFCmx>Q8pA~IZdeZmp6{9x|0N{cA`2j+peSd%u#&2c)KVb{N7yg#r2L}L@LHrJX ziV-+}ixEIYKmZ#4Z@9S{DYK5Q9w|2q6Au>`DHjI|6AKGFXbK1*|GV=XJnT#?;4Mky zKma+#-;`(PC25)|Fi zSx`TmJY(@irsi5xQA|ua$ZWV%A4A`BrV`VxCE6eock*8KOPj)QdA<{^x=zw+{Rkar z1-a$s zk^1cnE^C~MpQ09RTs|5FP=w-QN9D#r)AR5=CZi3PEU9@dP^M7CB=pDv!-^4L^;Ui( z+rIQ??$8&CzT@(dS&Vxb{AQCS#nF|Vou~pjwn##On{%#yVxU=U&4cU+Nyw{cFDD!m zEadI&ZL-F?pA-Tj~PY6ri7dBXRtq9Ac>@ZTUD9(e>h+M zL3L5HaC7o-HM4L7KSsY~W(<`7FsuJ0g9019zrJ<}WO;8eej{W4@x1+df4De)B|!r@ zJArjYV8{!>-#_U8D|-Uj0m032Nd(+Lg&+=t?2-TsKoQt+j|%jSA&u#H8$AE2qWxqC zZ}?YnVX|TyaVrh(!*s?=*m;-@PTmG<6p9U5-(ZQpjhsUh0Yw8P#_eGl#$K1h3k>1d zGi3=YY)OQa84QQG;2TBQz!u57#~nGIfqf!H*}@av90uKutyybpEuqWQ?c`Eeef7l1 zi?e3Fz(TU_Bj3+aFe0)F0rLZk^42%J*90B-@E;0cDT%r{87p?Lk(^-}b-0)U()8f% zij1ko4{Xa^ch%hNr}w{{kBgG8KKba;*g_X^kd3k7{*tX zN$RKW{Aa?D5I8zTwjt9qQzeRK4y*mK9mq#?Z{Uv_g)a-ohhNOr-#`Q{ttN@0ztYL~ zequ3jgLqNVFcoLCMpbiVojzawQ?>ojgTKasJf($wzarIFUM+HU9E7ccpbZ zDGz0d7}+QUBy{Wr1P#J_v?JpQ#|{D%=}pW{kWF3{6nj(u&8z=A5{^aT$Ko?@6^ErE0AR(YzK)+gJN+@q`DxDhPgLr!c zfK^z$sy&Egb0jc?E;kqP%P#5`;xtdNaBc|D2T5tYdP$AQ&m@76<2CfiGFyXLc>Rjya659 zjivcu>8d}b$)-uxM5=lY|Ehr!RD9bVAzYmE6qOlSqa>iuDWkyTC}UeraZ`lb=6!mD z`m&g|ho)pytWUrGXfj?x~|-`;id>X(=n(XTHyVr8E&D9`ZH9dop* zw{`30zzf@U_(k8xeX{;cJ911(9X4G!kjxfG!_d?YV5XKVv?btNK1`wVf*bOe{8XRm zM2aI;sNq{HinNWbn|vx-)O|r|GQsUU66L-a6bl1^2!BG!6NLUlSBX6TZ$r0R+61sl&X<(fPE^U>C%-{-Da@M18YYml$(1koKc=Vf_s6ybCQDkjl&NRy;g-u^H>GsBeQR%GrDfMqfis;6P6 zZ0Zx{8G~x`%Ruj?>p71nI;6?lO>33A%jy%1;Lv-i)%~ZJY+Pjjn_Cp?C73@fvXArs zSmfVx*S}13!5LhByTiGE5B~o=Z~e_({)_GXW6sK$0N&;1;`wEVq1eF1!Mobr{}(g- z$8?!l>ObyXLvnL~m@@#^(5xRyTN>#y0jZEsW_UQi1`{y7`L{0h-*M4wzj4uEUFzSo z`(NGo+<&<7Qv(0cqSF6;WB&q&{fkpxHxAr?;JDojC}_%(M)q7l7ZlW#yuhyp0=Pk{ z8US)E?%&hXzjQ43uOvEu-@t#JVRHYGMF%WQ24~UvubXF{2*8430cR%y!=*uaMSxBy z+)~>{%VNMaq#bfi%Vsy-*xkch&d2KQFyDvM@mc?gTLYS3z{pbuv zadSBIoK|TEqhrXP+itTY15JjhE_eCFK&1Vh>u-mL^3UTOboYrC&974zhnd(eBY8Xe z%ByqfKhGUS4#)A7zV4f(a5>+Ss+rOPy6hhmJ+-atw*QDsN42xQ5cdFjxA^)vch--z z4d>`45qlV&cDFQ)?P__i7f)}#Q95R8%*|$ff5&W?a9pS=hf<@tqqT5@B%3gD!=KaH zs2eJLK(n*fz2_`yf&6hK2_%uBva?3ovKzWaU6V<|L*<132!vmzz?&{p-w|L3#%8a5 zp-fEOD1!(u5(xjcFt9vwL0wfDT9M_Myxbds6NzLrugi5VJ9?eB1SHDO2!?1d6mHUd zcF-)Q^$>Qo5AbLrBs6%Nwi*lju%r13`8BMPSdO5Vf_jgk^P7wv$HE&qC=_` zi)0){LVCKLRhC-XnETSA4t7qi*u-S(wn5Ef%*OP>DaGf$Hs@7*e$lU6<}HMpx|5`V z1_dGCY})Nq^7Ii_pOXDo#jD{GW6uvdPAcyAZc$=`#%O-6!rk0mEleB|d~aSs@^JpP zgukJOe~pd+V-LZG2JTNw2qMb>{1Ma-Mpyp^7l6-$P4s{JBK{&SfvNSZTww0OFA-8v z9RL-83TmnYFmw7G2W>W&&4y0%5uivY!HP=~I**xp^@vJBM>4oV(L$o-(q*?gEtUS* zk3hE{=R;rB;)h%X5!M4ZfCG(0qfOtLA_~XTEDj1MsVIVQC?UvDL-K~Mf`@W=w%{D% z`@67}_ZOYU`}_xxI#rS%sJxaaD&c(KB?3CHpwSS?D7T)d#kOTL%V#oXKVnN5WQprN zh-|;p_+Uf>R$eIA*p6PY|eFjXUq_*pH0sFtWNYK`~@) zNKwvTf3atAl{Q5u_o7I47nY=ch#-Ppwp$HBpgDFPWO&eWBKv8%eKu1`S;f1j45tTp zyYL+(ku$z_<`YT2@OY0I zapLF<7u8CT=-{tX^+@H>cCv?5Rv9H>@hJ$FmmQ&2GiA3J9vz8nG}R&w=1}!9u9>wo z(!g^Rn&T(|M)AHNUGrpzJcoHdbW?vw@5Jf4t(5yc{5n zuK-2heC>(_5h`YL&w{yAx;@cNL)2xU1?3_(xqKyU@4>?rQDi>lP_3DjThz5YL&TQz zPO8<1?ug0}ECV0l`S7K=H)k!T_JyEbzJk?xx~X^aPIEFF8^b8untHK7@y+f{ThKP{ z&!VinvRy%SZRUUi;BfzqnGm0`@bm$z@9i@1%O2*OR>vvY{d%n6s!_IbU)yRCi3p%I zr&FBwKIo&4KE)>R3eg}l)`__vq%h^QIrudC!y&sZwPoM>Lr&_B(mHo$7t-*Ybg9L} zH;l~g0=o}R__4WmvFpuTk1Z{5aY#)~cYQTb9OhcXui^I@&!@1Q_7?G`~Ax90Z>^PFR}vrXL2(iBPH zbY((atwpf3CQvW4Nc^uB`eD)`kf}^3Cg)V!jl0d`EqMuaa-#1c7+sWr1W^KaMvkXzo`a;m(={7{X6$s`HHDs6zTWmJXzD&STfm0#NngQ2MCLa{7}WM^?c+T!!T553JHbf z-o0DWgAAj|#k*x37uBltR@7X_zf)#1mzyq7i&yxiw8{u1oEVVeS^tM4w zlCQLbdd;w;+=~|-jbPWp#aBKLB%_QF7(xkN%cJ?Ed*!AdKDAsWPxHc#5wAmXh0v>n?2;PlH06w;u(o*QVxvRVQ%d`K8M`utb4wy?q z?GqAVTzjajWwK(zTAHelM@V{){^o|}#oIzvRm;)$%LkM)L2(yB{R@VVMaVy~PQ%Uk zY^5_i?f_Z`n0PE*V5m1kB#`wk1vXp~wC)|t_ZT4?Q#O7XLwt4V)q8EsynS9-A=PfF z-~JV6)|z3$q8n=nr(1x?)udZ(EY3maB&B8*AuE@PS-ALzhB_$S%o4#aR;SCJiSxl` zp3`D&Db1v{_6+hnVS<3%&T?062D$J_LZKV)SJM-9!1B12ivLn!B~ZJIf|ea126)R+ zcC&>qUZdSZ<{Pl3)U)cWvc+>KK!8YFyBtqPfU$u`zmdTRlydn-S^AC2C=N{6$e zvgOX~nfY+loIZe;@k6V7%`viesAy1Y3KF`nS&p__Izx*Xmp{NK6K_spK&`_I5$QGJ>tAjV@GmPy0 z>eIMag3&58nx4oqXUN(kwo_r3OQKMBobAfD7<-FC7*hF|x)KWT41d z_dZ6Rh)U^E(NtU>-Z>u29W>rcc~T{Ej*PBs(rZ&O>)OXR*`tn>icJt9$K5is(KJ*3 z?g@l$9H3;G&+c>yM&~|p)L*O(&0~zghQ`B0BO{(9Q2i5^W=Rx3UZv)1ETC7ijSC+` z?a-`)n#3SG%F{Di5y`j5iJ|6N&}JFVlOVK_-~)csfg(_VWW#%ieKB>?z`q{jK^uR{ z$SdDdwK+?*BJ+{_IOx1#N_X^sBmE~(r3&cqkkikB?ww6&AHI%?ghHFVsU@v*~8B z(WNKBQ6pgkK^>$7q&2N`Rkm4a){uv$kj2OW-{cZWY~lCE-FC->qlWhf-xbOGCdX8G zNSxZ)T#pY*tLiyEX*MN1eS5#fKng?@4mld`y`N^q1E^S@+D5{GkH!`QGWk{6Ck(0bch4A@kB7<}W zc(#Gu$;&%my6rUmT*>w_jKFvy*c{x)QPrW?xc)&2HI}iJ%Gvw6QziTvDC!R6Y`#5e zATP7vXj1EUU2ME^P3Gbf~C4Z7&|H-Mr`>$J3ynk#(+5Fl<10Vn1LIW2EPu?W{ zepl-MBLDnLh%^@mDI4$aAQEtVILq%)@6dk0IS|_2zv}ctYklBU!Oj?S>77a^)l$N4 zLrHVz7w}V2_OUL07jkY&ss$hr!ef3y=Bh_E=*f5D|C4Mn6o2Y1hK|Y{;T#lkUA^%S z-y47}nSpPC=$cQ%b@Q!jMJg>jSpK+aDQWAU)Xj7jxth9BXy zBES!t+_HGK#6ONmM_o`^2&0xR?T_Ge`3QAeIGg%)>-?IogZW>uJHoKHQn*4O60(HF zzC#ahvT^zK7j*QAzvj)&Rf=sI$WJkAb05^t<~AL7Swb7&43vyfL;kjgeOh5xVtQa% z>^OW{ua_mK!IZ3tO)sm zSl|5mA|Qt~$G_+Kb`HIO2kB8jE}@8Grf_K^$O-XmYPGLxj20wa;1%Kpvbn|$d{49J zaUdUjFQ$dLi5S%j75Mfp9}-;`*&__vsvR9oVnMR;aOcKEqJDs+zW8eGZ6sFm={F#w zlJm|kn;~tY5ejReeByF|IWCKl_OnHNXElZtcH%JKC9=W1a)0D2Au^tMOP!n?uEiQg zg1w2m7n`ENAQ&V;vGQ2iS4p*Xk`_EG+^A&^WO7zxC=%rjIZ#XPo)Mf%Pp32$&-pWH zbtmFw`yVnz@pX3ax{p7WaTg^lTy6q;FE?CWS+`I3J&`&T)GR zTyO?R?tcb_u?ydnB|6U6Co=79$}G}sX2YPW7NyXxBh$yNWwb3F|EsE(7JPhyGId_d|R8cKj5GZs=IWrorz$)%<#>CGL0s^93hZY z3Z&kfb8-&`=VUy6K|0)U?$v#=E5>=5+TD#V@e-}(kD4V6WHa5OvJy7|U$Km?K8Bp! z^**=wE;{;ii=*s9du~x8Dku0MdM$sEYjm0CnMCOh4-I9;M4Y1RXX{{=2>N#RP|yBs zJ3}2E`W0_Rl%WMwqC$KGWN1rz^%H`2!1K#su~pH_+GhwT-THD|Diet)F}jYdi~S2V z50pam(w3-CW;f+J{col6G|ER}tr?24jLXY#eYvLT?4X-iG-O|V5!>3E`4}7Nze!U@ z<%+6F$xBUdHtJR^i*ojA<;!E_hGek8qV;`qN#SbhXwq{atrs}D27X((7V{k{Giqcs z{<(wl@NR{*PV?BQQl6-N(Rew9tnmB9IxCfiY%6XThT8Ad)yYI?VV*ZSv!rG z`M&G6goL*dLk#CJRANfZarS6tkZ^nt2*u>K^yLfifH2TEr1^!kSMFC{ae@q+sSv5x z0iV!#%ny1!n;+@7N#7MPO20fOQY--hk!qzHe;EH?d<;@-c9wr%uJiu6T>m%g4^H^_ zFD`A~-^+CX*xvtC{tx?cf7tQ=(P8{gXdpclI}1l6;Wz+H=te{`Yb2cj3_(FbB_V-C zaiB0DS$_FRezou4Mkn^)AXKm);&0mbFQXItZ`3J0=)MK;J2&Qk+e8pg9{~CFpQ;d6 zcAj5Z^WFdroR+vS{coyJA9=06wQ`MT$#)49JTPHj`}VLwV+nEUuUf9p1f06meAwnG0zgMJ3RHBEyqO*p%XZ%^a+h=o)_121vcTf#uu)?mmL`=i~CX zaA@ivt1VQNNpK&=I1$3P%RgxNazLgWp>G@#)0cvoZ~5RLKSIozs3%GsaK%4mnxD&CWPCX-{>!zzn%O#u4G zj|ICgb8uTGOYd723^;weJ}nSUdeK&(J{0rrJ?7Wx?u)O>g&BPj^L{{0 zx#5xu{wL_moZ0X1>9ZmfwQ|vTzhe*O;nQ%|OLRvr*HP++)C!^ANpPV!>LNFu%mI(S z=m;MkV={RA?V2hM`gP$eB^zodeOl?_nuwIVsBN13BqQ5%3wvdmCFg$GH<2-mSIrs4 z=}jBiJ33p~=OLgORJB}|mv1Idpel~709@{T)EnV!OU_sTp?$~je#!CQZ_KDdVXZ$( zN%XvdM%c}msgq0RarSnHy_4j{CG)e zT~YyM8&OYLUpS^P(ZhbGc*_JY40Ico!D3uNxqVL4PwP<~22c+B+6}tAHHUKiI2=Ro zmIg<}!0Yr~P^K5YqN0rn5T03tvG`#&^tu^+@ftEj@PPoAk&!3sE*jUNyAWuy^mTlX zGLI@7PSrhb=jA;?uP`v-)`$*BQ;?w^FnS*I*$?>c+42>Ii`EvQ!?7G49(F?0*KeAf zERcF3K7E{e2qNL`Gz57Hd9=w*DiwO&4592~%rTm#T2-E-YJE0ixr#Er!gly$A2MY1 zuOb=cAViY{+xvD&w5G8A@il(cW|)7x$wtDTyuOXThcC%w|=@qaEe@{qCA8 zKdkq!Dlk%3Kcgy)$LHSN!9!#8ua+=*h>bVm!HkJd<@d~h{&C}+-T(yiLw zJIA&0^Gi6Wq|zOBZB4tiaz+(l(>1pkeV1A)l+>^6orJto&pH7Gu zfyRa~xxXvgwYZA+ZSY(~bm2ZnEBaKeoynsCBM4`qKA$ouD*WX6$ws>Y2$@ny()@cg z03)2iPH8gmXz*`dX?B+1Ug_8WI~ssKPD5k=ic@1}`Q?SC2j^G*&raz7I68r>*8zqg zf@kPgjpOS8X-NFvtC?To0ew~$78ZklNJ`mR*&A850IL8~oXl+;tw`Bf|GX`6YZF%$S0^(! z@K=8b8~%6c#m>qNB0L1(g1o+i{mEfppou_+hX4%fzo|0*59nGe-b{hgE8Bn zLx2e+IEe245WomVoq_0%0IF)y$Xg&40H9@<@I05rhFMi`a1OZc4OuwFNPKYo2|D4W3fT&bGiyk4Qc1*di; zZEEEgzR^AQWmjic|DkDcFnv|gHooFN5Rs&@A3A!d7>IuD2@dl_R1knrCHP#EP+F78 z-WJ{#gSXb*2Q9BuX}N6*^=L%H&Dg<8W6CWlY~HwUGFd* z_bG{V0to|GYCGhrA@Yyj26B;j(!lu^0qe{m26R&)k1~QRUo`t?#t`?Qook>WLx`dk zg#(_kB;jsxydV&ufEeAt0-cs7o>LaKmey8w+!uPF-I0{PkX5F(Wyb7gYrvT4lLo3v$?B`AWn2T3Z-qt4$*+kaoZdB{&|eZV zEJI*3Renq|GueQ+efE;1GAjetnB6BZI#@ZP7+XH?Vp>*$GnMxo8S$w<)k_xxUJPWv zt!#^HL(IHP16>bl*lPA_s@Y#UnC@TtL!V!2nqK5JyJq@!NZ8b##DzPJAR(X8PhZfj z?d>c!?>cf`2nt?3_6KUbG-7GIFjdw?oxus4@FS$Zq?Bh+l?wz~%4snbCPTQH5m>DW zAN>SI7@JwZY1Dc(+{=?f2(n`wyxe|gs8Fal3LG1Q09sNf1Mj0Vg?GH}yj7Z;UQ8es zQ=d?%T=>;}+28OZKp^nLbp21e}Vd%3eX~{7laV`h{6?(=y}aVLI(k- z4US6gPY!#sV|K2F!VP_4d%|#mz?FO^Rf5RdBk6%L#(W5F0z_}Th-N52NJR*T<8{*B z!PP+E0t=o=wIK2?NiHW1u2Jsym~PeEPfM zOYpp~U*R=Cn!Nky4J7-#wAy3* z0`K+Qg!)YB$8kS>z4_hTy~Z8#S@8vBmg)E!+{lUHE2mR&=00*bN8zm+DSn%A2su~+5{oknpjV^_ z>b$KiLM$cGltPQn9FSz$u=?7Yzci8ajcxNf_}zkbIP>c<&mD;ao=W>xnm_edGfk~1f(n!)m!Y^*SK*nfQEfOc&|!C_+c9dCoj+gl(O zR4VL%Q_%?dL2}~Q$$YO~i=@lLDba4f{c$OHE)PHE$NEQb@5b1oQ5X)-d3kr56OJ2CkJ!*e_dhX~e+^S7L5isXJD5<~Wq zv~GFZw6;8r6Hq07jM><;m_C2P!4vT+nMoP=;Zg7IQdO4G?PS3N1CtiS5w2|D%!gTG zI$|GN-D?#q^@LHXTMe9a(8x!LrMMvH(2EvWJP^%En@_ixtdu(uy>BVy30*_lwbjcp zi9Lw%@*|6lV$OO`8aTYuD%${>`?`q+vQ6qcQl1K4fTE?s=+7Dr$*rk0loS*oG~+_@ zfze+Oq5NFdwzAGG7tMGQqb9v zQbu04@5HLorvdl@n(i^|O_MDoGR%3T3+jd^JkFNC5zP}@LhF=W!;V|$>C~RB8YgO*JN_P1dppy-C%tF%8M`n zi&j)!V12*=mQ42~m|IV)NG?6VK$a9?GEi7UEA5^kn{bZ zBJCz7Q&Mt;8S61pa&RXa#EA`yeRK6$RA>OD6FP=|5H&rK*u0f=5iD*l{^!$BT(o1T6(jeZ-+h8)JxuL2425P zn#QJy$C}a^nr6uZ(;0Xt_ii@p05qqTPr((H#G!WAa{z2I{t2l8+jJx&MfKCnJL+ZN zqsFGJhdrb3N{c7OcPL1a>{Q-c?PAq16*W+_?L2(=?y3aAL({TPEZrBxT#mCA>x6VL z5@!);!3u+6zf2FuGB!k(|6s9X+<#iT7EAj!Vi3LAWvp^ZJL#~Pk>=73>+O3wSuIoY zIuPRP5aYSL9(on*twXJ;+-zn?Z$B@ZhV{TcD1kbFUnsrwXo^`-Ljs&w#l`S|n%zQ` zGT;oO3(7S1eY^|w#|t>V+jYssM9wZwc8g(Pmdp*Df?%$5=M&q`aWBCqq(t6gn|}2Y zHbnP)|4&Et+{bCKWU6HHr#Z(i{&UJ{CC^AX$Mx(p2?B9KNMuIMKPO~PxeDx zg9aZoOS=?H$SiO&>@HLeYWF2T^T`g9BfO`s7&L8Au@>braD~?W6^$ko6drJPm!2AXm$;Um&!X5vHF==UW{ZM8CLg!0ovuy(jXX{5cYs zT);Bk7sM$TA$G*32kpTQ2!YPZJRCw=c!4b1@t3WOa_iE5OCnw&>nX8?K~RhHqHh`!i? zfLA+Ewy9nV@pfs0k+}Zt!7a{%b5Tt1p|(}c3C5=z@v|-!>J6$ z!Xe}UA*Ji|-5-kboMML;6Yl%=Niam6Dh;ibz%G(gO&S(>3*fBJ``r(`i!MuiNVy!H zV&*G4X{tle`Vw8y-xGw2yCfz(KH76{Yk;6;J~cpBG(KDhpB|v)L*a-(6qLYjjoK=f z)y_uM8)6X0SP3t&n{o;a0n;d{k;{GN<4g+~Z3p8$h*!Pq&K@oVXXNx$CTKE}ei9HH zcxxk?tuMzFkh9{?lhS-4kX?GaJ(4sR_d5NoB`H4ihfk|3S74+s;t!v*q#hj=RCwvh z$Mw*)%xRl$0~njBO#3J6wZ#!JYma(7dd8Y}DY90GBn;P7-65Z+27n=9%l@k#bTL)! z@ZK?=hFss4TJJT-gs3@9MdC#-7$V~B_E?hFVqHw&=Eglv&bB^B;hlLAAeZ67+kdZu zws?}MMzIk_50Qk%qgnh)(gPn*!1jzO$AT^|$B3zq?sm=cl&a=8E6tQ4OTQxhM#{%M z5?)_Br~BPHYI)cV9uF`@ZsKXvIMvj9s+KAddIe_f!tT@)sWN8KGPqb-T-Umzvus$y z5xWeca475DG`|I3DDM(PXZrp_MRD&E5B?;Bn%M5h$c11uW2|t28pk`o?mk3G+`+qH zyz~dIs#Ld^&lB*dD1}1a&5{GMh+Mq$?bv~E^U-`y8pnz2&@(_*pr%`;wNkj&XICI+ zo-MP$@_4(RcG2#%7Q2CxSkHNxSPm1k7hl_L!WAyVBF2u1LEtyoS21R+M0z|6i@dRo z0o&7)rJjhyODNwfSz)j|h7?=cc-dhUr`K?6&+n{ohsxgv6_3#hwxt{P=xU`8U6sO6 zMH;H`XypaH^Wp#&=h#{JNi9KsP+E>=cQW>V2z)zGYJ=QTJQ{-lZ+?k%u*_B9LDa~= zPn2#Q+D7U9AVAkxy8$ibKf85#yBx$-nIC`b5HtE65GM3}Y8g+V0`KSds7_uZC~Yet z%SSTVAlnMnhd#iGIyRL}9O03Ss@;b{A(uRC@DYMVqdRQt@{ zK1DDF0u6dpq=;-4%n^RYh&xkIbnLG7DU)g5n>r~u*(u*$Dr=GF1;AZQZnD;rt%6|K z2sbuhRWQbOAuc@ku-D8vyp%HsPml~AW$eS(c`x~&JcDxPoMq(EPulO!JmG%&Hj*x- zHB8`bzM2#ThKYEYG`pm~vt96!({I!<-D@u(P3?E*p37yV4W=#ihFXG)jED5zV`JdV zPkMh9`L+?JAxA9tx%-y-YXL(~vkuzV{_HMLE?&nxm1^cY*#`gXTR-laH6@hGBh*AP z6mB^3g%ZLJF%R~4qs%W|`6bTp4mzFRISlUsXa++(fuB#KBu2hgb-ZzTX9a-;(mSv} z%vh%y;ZN#vmmQd-k1ln>|DoREvA&3;e9bQC{mY%Z%N;w6?^8cwZPT&sgn17++Y0 zJ??^(Twvk+zk^q-n5z@P4KgMsKRWhC4qpw0B#s8r57h)|LB=PtPjO@aE}fW6%M3apASatNn9Ngno7E|hm?8Wi2h+nrIZlmWKhsKtJm<%RXX>WtYT~lqR9UEaUk4i@J+{i zM-Ns0EP)?6cMt2aRh}0-z1GAma1cZ5-`>4PsOIYJ?`-f8K;J*YLWvN0!(oC=+;-^E zrpg!AL08f1x9)cAc=wJuBhD(O(!#*y8xJr@AnLJMZdYw}2~$j?r>`lpH+>6}3o zvSCe@VmF(EHSw7vjfzM|Rt&#mPNT`kF7yzcdvLDI4fj}~DML{dAdt$@=3EvmikaTq^Bm<ae9B`+DbKIq zUT~ufBCbAwOO`*D7mq&i;#Q4J6mk(-U;g$v_%4r5&v6uiomUi6FFIT12WsM)taJ1? zX0K8Y<+O>`sOWv1>L0-vsm;g6Osg&J0^tC+TdcdME54kD6s#GvA{7c4ER$5As|vUF zgtWfB;-{LF$4Hq9zwmI1`O89*KIFFQ_D_$dw#Fp!nGd7-&0j4wjJ6a^Jo?;64?gHM zMdlz+W3(A-pk9TKyDyVU+`_YhB5tr>Ka?-RojfCD5YeOw#(twmjYG2P`PPYjh=UuzC%H$15NxF0u@G`uU zQdhFh=ZZ6^YO->wbbsu_L-n;OH%$8iE?DL z$8fcZHa5)T5TuujA@~ZU`-W_(XLUm#0$k2F&$%II1kZF5Pnhq{yz%dWE{mHbWWzr` z#&wrlg*?178U}OWmFU!UtvP4p?Qcj>Q+`H%PKldWX3ZpfNT@1r>!BvpqRCblC54?5 z#gd()Fbs9Yt`DBx=$gXwocBT49R*Qzh}Uht&`h8ZTk)U9e@8!7dW4)pSwn();itfdRfc+x~wzmhh^oY?Kr zKtX2^)$fk7^i-kgNrLZKFL2r#uiU<&sX!0CM9oX>tMc~jk7m60%)`PIkMCN?Jsn1y z92b>Xem56e(@TI+glY<}z6@j(TG``|iWqo^UK;EiqK2!jLwE0IcWY(dQKE_QE0Y`oFHtk-30 z(7~*xaj29A&YvEr+UAKBTFtDYfFQ)+mEk@n>wge=No^u4{3e;j_z5m|$2Xfcx1Lv8 zp5XPjEF1(C0#9KWpfj{u_q|6S3BSWNc@~gK{n>(j#}cXDkA0Zf|k$K!ltM@g&wdi-rplWeKJ(ul2{NZZz!~T6HX( zq|11`y|!9VIE*pIJ;SQM_y4JE32}0lIMa!(5+5sAB75P*IVAR`J5TBBOiAz--2w#X z&J&-svFJ+_kemz-#y2d?-G)kSHa2VVT_D;>fDN_U5(NP~1Ejf8Z!wBI6luh;kUpJ$nwbLRBSBkb?=nKA``>+IZQ zVtW^#b72sYub*n{y1ru~9b!F*{mC0F;nFumFX8_ZvM8zRh^iT#a)4`!1>xNj76-|1 zd3lN8M$EM;(K%}7@)J-6k5Mmctoy+y(qh46iFu3_rrTka(s!yGNti z8LRd}0YuH|_Z^W;5l~xMfbf<=3SN+qHK`(L=H#A?n%+b1hSw-a6gK=4jHxVCfpv6f znPWlrlJY*zyX^ z6{*+{?LMEL*4c!nq&jB8N^#X{Icjel7I>Nldq%;#JMJxdgB2#^R3JMZp& z{dK0aqHM?7#~cL|5X@K)k`RR&=PRwn59bP@I6`l!Kz7x}vfeYgKCwu4b(#a_k^J6i z<_9*>Z^-?Q3FNgN8**%t=3~KA!UcsR)E_2PhwufPm^LO!SVHNYcd5DzTpB-h#wrM1 z9(?QBnWSTrugfMK51l8$u)(WiKNA+wZ*iEb3j7k!AB**T6e5S~oA`4#ouFX$C7&9F zbssQuN4+auq)SwdQux`{p#9O)5_D53aicnqX@OGg;aXQaplfAkC*exZ5fE3NlsWLS zb%#&OMoui77L7*!H3lH%cs(@en2^OJI^#pIdz(fxw+KRP6jC})_|(yJ+A5|vcQxWI z6bmv(u6<0I9!Sb3WT-*sR@OUFu?DXC=Sz;?KI%PKU>~G@;qrpMYLh-qS{FaPs9e$J ztC#ycZ+x>FnH=vXp5M0k)NwIFb=u?Wr-p60Ax83o9@in|_WAFnlqbq?X7prqpD15n z6^x3VOj21Gg|1?{A37Jspr2Ay@r_aj zJLGHNv-J(vSd1A-&jQ=Z<7h%=*QMCvFD^Ee^h0dQIqYJ1!1NyXjYOmm9QLAEPb23? z8?o)_=BhMYnv{DF!x!VVv=m9sRy}zRSsSwOrG*|zLxeEg{qV39l$VszcRr=1L^va^ zx^guimwB}FcGaEtxSxkLJPWdC?v#;pA59n;4u7#yd=W^MoLnM_9Hy}UC|)9=&0N?~ zZ0$p38~dP~-;%y`W3-F9#XE{c%pH7w*}$@61MvlKOMlY2lM)N`XwfsPeW!L79Z`+@ zG=mCn;UROZJF`L3`KE2<{4cy3d|xqQ?|aAQcWtiZ!{_~&5lSHjBvnq~*FSq|_~E*U zCD&esNpblFpSgbP<=F&wK|}&Wreb3nQXnT+PKutnV($4MVJF2vK?U>Gm&;^_gTy17 z4tu=EaVSK-lv{_304FuNH9g$2Cl7QYrA5RKig6)OxLDt=lKU_4mOqYYmh2@~_+H5Q zF>@x6<|~0E{j+RexTjorTMqoF?0J#OGv}8rHx4|0_laEm@-3Edx+vHEXR%giA!TA( z9eIh5gECOvpdA(uQbtloT<%=70 zf+V+8-N%eeI$!5ep60~vst2btwJl zBNDK9zKB))cxa(PLthJyI^E~oZC?@UJS=SR#pDBVP0!z%jChFX*}@z0)X(FmtON7q1SF#pxokma5+$Epg3VspEiaMF1hsfv zMIFyy(H)dFX{V_dQG748_pN_ni06BKd6fp)n+l5!SSr_L%F9fTxwP5udhHQ8@z@ZA zzZ!p!FRJmUbS+KPu293u7t*zYIMP~kt8F;0;amq(j^7?MPZR@}EMGrnj{F>CDmC!P1!YY9vWl!m(*&0v!1G3%jxqwgGQ(E`{`)I7?l+mD#kMTsy>pV{Q zJ3UV0dR)h9_{cgz0N4`c0*vr6VX0i4buCpP>dSXDa+{M1ROX~}Bc7}N$}QtOckuun z0}N=QJ9z!&XEVFFHyQ;P-02texUA1a1uXY#a}MAj`7Dj9S!jk+6!)TqZD8&DSrNoq0FE^=cf*tk{}EM+9CS@qMG=FtO`Z>RQRl%h(@o&JQ}4^te2KCTA_> z@wWs84;Ys?y@qFhDVWOyuLL3&Zgb$Q%0onF#%Li8VUa$SxZqP#y-kxe(EYIE~lQvDTD zxp`hbPv|umLE3!4i9JBdYHkz7FQ!2qJrdGOGba6o zo!y|av^6c-#7cBwBCsgKwP6|S3C`FqTVgDuEbbdli|A2Co)orx1$xpns_PliF>9L+ z=~J_<)0W1kkyTU$PcQ zXq0YVYzfoRWwYp8@4mjoJUWE*g=@YUAbv|yoiLv-=sp+6fh6T=upk#I@F;9FnYSS^ zR+4~Xc*0$TAYs>S%|*){F?bH`cy1mU)6TiK;jgIOEbCf(2rb&f&*_&t=&$0R@AFS%6} z=#SV4tBmUyd5cy|k%gIsppv(4NQ+`}x|<$7&>DMYzi{x(G)pVY?-E4sh|n-YnuWOe zIyT;`NaX^(id`;duV`Y62@(f`1&9?t#x7@El`CD~qJPl7oo4^}^s<=I8U_;}?g|b% z!%XuLVjd}uFq&pmSMIbkXJ5z;J@6=DYOEZh_>fR5S`5Qw)RpS^IOSjN(;B3(KuUA^ z<78GU4n>>w>B)3GG@*pYbI1oc=2k25_2DVcrx@3gr+DElax1@#uQgz$B7n{pQ z4U!tOXwp_2zLx&O#mb~Mct?Io7Gi-doG7!B4kjp1s2qn+$$X279no`-$dQMLwHUT} zJm?4ZmLCQh6AC8#8A7sw=W-v%8?ohiIj5)Frw{ij)By#dSJy-QH?shzo%2s zAAYE2BDK?E`ALgUCMK=RD@8E#@IWT%jFTm95nI zJ@TBjrwoz3!4Cet@{Ru9HCT!-i64moA6gt0kMt1@DPLk)S6I`ETgI7HW6VXkO72>* zfSB?XrOJ6Ok%H~c>Ok+(OSk;NG%BOgPcF?o0xH*zl!6f;80Sg|pK6y66*B-u!f;2k z$$jHc)S&iG6kVd?k0TN<0W*FBk;9@RruURMqB+#>k&=QELolm*Ssyg-DRBvfL>9_@%$X!JdZ2aS#`>9U~kyu3l z}AQvBr$H2!IkGJHOty-iDv zWR~j1M;tjQN>v%q)nD9n(z@bdRn79Q#J=zAsVnBNv_{$t26jYFP-%p7ii3tBP9ss( zo~qcj5TyEH6_>S!5a#cf1| z|9}CWyQtkg;0+42r%PLtkGkCyk1A9DP3={KbOWTihQA$5BFuqmA)s_`gIVEXHI1XI zYky&$_9qf+f6I?}t#{NehX2(~Ki<~+h#sZy4`1DCo_6@2ar+59%FD9RN~Aw(Ve zu~F)F%SM9@`NTf_k6l65h8E!Oi&%Q|`HV$j++prVd~4x2v-Yi?ywd3ElWg`ubbE<| z#u5;vm7^m%IhHn6r;${5;9`&;m9!6@sE;jjA!7OGrqrpqMRn^(aV(!Z9dP`tiPcGE z6WP79u-BDIh}Ol>g!FO4>{3|v-yPTB>uzdH_+BzF_sO{HiwYZ#!sQVVuuo$B%uAD2 zm3%C_V+|q})M=aC9^C0U)lLd zfqki1sN6vgg~&|*%}mjvX+f~k)@9694UT1@g5uD#cRy&bIl7WEmLVCyStWbXjE;Q) zsbSQKUNixBwT}o|yKLBh@t<|Y?hYaYB}oYX)?f-@2cT7tZ<$fQ|Ae!F)9 zF;&RlZ)QK+CbU1Ffb#jk5 z)vAiHa4ApPSA!D|KS~I`Qej~^|tCL8_-yNQ54)Bf-5^7lu3+cjn zKU+G-RouI$8#Z)rH0(aevV2u6Bi;5BJp|G^4pq6fV^CLX#y`+VBYW?J1T+I=;`z0D z#?OnM90=Dp2SC$R4M^FrT$B}kMLijwY2x}nDKBQ%On~o1Nar}teBF?N>!$`;TFpVWxiDoK6^bW9pFPI;x2m{tvR zi_XY%&~g-sxi$_oa>t!xJP6@K z+-KS2eogfAS?vQ5#MkNIr&bsvGFiO)>+W_8nbKgDq^Nte5B;!|oSPEyVBeYiIsh6k zPEwC={#YVH!`4|PhReG4wqo|Fo$3TD#6KPNeeBE4CS%?A?pZ8F>FdDG@(&1*NMUNi zLLA%)_|`0JZcZW<3%8n9i!vEGDhAxMs1*CkO9#UED=HRgEp#hB2?7f^4lDSB!^?h> z3sWOcD_)h4!1N-cT(<<3%%k(c@%mwx_lniA@z9_BG9=3?5*l?0g{@x(Oo(@fBEP^R z1>3MAMi~+4w_rWGYB#6V-W;hX+kP{#b40?FzWLwh|UW+%NI5& z?I^fQ%q`47rP*)9Vp3RJ9xU%BwdX8%X$yoGtpJ|G2MNv3autrsKFO#jf{KJ&n{ADR zCP(7aC?#C?+`dx>DJct%q#b9q#Dvo$1=fm6J#znwV}>WNzW1np(CI$WW@uogEu!#` z)0L^N${NbgP?ay$AEJ&=1R(cGp~3L zsf}g@nP|9YVYMwhFPQwqI^9a0s7J>n(4L*ax~Pc1o;m-$=Upk4oEFU)RS-iXNy(;m9 zG46S8`L1D!VRuar1owuW} zzMl80RG(jaEA9s^mWkyDNTol_O2P*1xTa^Yo@o|-)^au9xn8M^9c2*NH{-wN@v ze1BccwNO2US;Y7NFE^wDMLVt)$%S6DCY>s~l|R`_{>8Z}=3JRbFHLgIc*|b*hA%@f z;VVn!l1GFN?0)?!z)?Zkran%cA-n6mogcgYEd0?VM~^0r`%GpfYz|d8nupCa`nLQI z5Z2PvRk++bG?NMExFOGeOpz$7Ay3Bz?+RrbP0x8CS93khkeE@y5y@g3!hSJB4q=Ud zu58J{M;t@QY*P3(Rd(hr@DoRP%nq+erxT7-?^LT;UiAxMNqsi#jLf)mFI9x-3(b}D zZOYmiH&0_MKI^6U_%E0<{hQ188Tt;(A^IEw|)KF#B@mnCh5GAOt;&sK2uZ8dKyE1Pj&@Hux2)8c1O zh~Gz8<3BB$kvOu*U&!r|m=?8cm2lFN)AI!-7$OJ(5?nF5XtN?&#qw|}`VFVu=A~m} zZ1&~3k`jn|2Ld5qTv0mNYdP>b(}Y`!low3Gmg~mRIiJQ_IyzxxNpnYj{qW{9cE2xu z9Iws~@00dn{6_MY(oaw$@`r>oLmYl*>o0pUn(+J+v{Obuq&u1Kr7e&+9ryoueUj$C zpe7za=w*G?y<+P^vx3&N@faSH_mwT(_zMz#s>CB!z45(vh$=}SE^+jTVtfZqG5v7( zC|(kk76~(+&021NZgOg9j{axsw;Zn}8;MqZ8baSZ_fSGLk5J+NZpx@8p$O-7mf+2~ zi(E*S*z_)pC`w_o%Fk=-Gr{-wzRtNpHPIYexl*x+;&j%}(uRYm_KcNl{a2mo($N^J zLzqz{E%V+EkwUI5b}*+s#P!cFugsr|&T8Q&F1BQaD}51wY7|=!l&bLKI2NmqCSb{O z;rO}p)>W!$c5v9KWmhB^<@hqB1U3G&e6AxV7jc%LZEBiL($4T;&fGXztPPC?^OJn; zMbcX_T6KpAoqHcXQW_@WGp%BExZw=hF0S!}0iW)DoPGzVzsU< z0IyvzPG^s&1(rYY*I)O-?%zvxmMpGR_6$0AJUAf4(8sgVn0|iE`ARXo;FMn(_ciHH z9#nFJ3cf9VDuq2GPMh2$0}Qml>IUpf1wXBv!r&lhF1EI^&m6c%`@GL`a#|dv5gF#6 zXGpeS=_#v1`hx{*ABKh%#=U&NRG{(hDK&dtym9jVjj6|coK2^A#!W&{vd^{eb6U#} zBZUW;z0c^#o1L@?*l2jCLsUl&65+mSIx|TV=2mSVy{FU87C8ewFrM1y3kQn!XFtT@ zoF_2lpN7-TU+d8&%gPt)*ZDSP>vR6S6EWrj`(BZ@Eo8%PB4p35x{zeVBDtsEEorc@ zgp0xFnawvXW!1<00S~y_nQYJUHYD=Hxn?BFBy^ns+U7D8qoG+E=~20G)X8)QC5NLcynabm zqMgJO4+jAc=RLLeB!5hcO|K{RL~uiIzWanU_ffs|%DO?fP$n)5h_o_rxprQ8=9zck zF8FPv4$x{pg{gOc2g%5_&oTd?q>@jUJjjDKksD2T3KP4zAo>}SMrYfr-4ZM9FzUpw zNR<}pMtWb&G9l{F9GVNeb*!bdT@;!Nh`420dlTen>!7XDznQ>X>w{soLuWmTU0L$6 z_ot7wS^6II%MAM;;OeJ!5F^y+xHU@*Ui%_lEj8u)dMNQQ4(@JFyOvq0e`ZjxSE2vV z3~I3D-~RAWpCOO5<*3xBk4c{ZHEd0_K|=7s_wtcM^n1fB*gi~Iti!F0eOq};qTMpS z`ei>L==)EhMwEgn%^GRM88T@Svek3dJNuH};ahX>`glz}$ds~>cDF}HWU$Rb*h`+2 z^`Of3Nd}@fr`AnR99c6w)yj#(j5C?S&5sV`m&DA15ENB13KcbDNl|HgZ(Q0w+P7WG zSg#$(A6$ewS zHbMKoA!k)PnEfuEhO(s6cEn=CRWV&JDL&?X>Z+3Lz}|o-+{(&&_*!yrveu7tHcYs@ zqYzQ8dF2~d+TlCppN8Z9Yc^BVp)#1?Rt}FDh;c)yPVZN-ChfhF_l}Yq_1;@4v|p(( zfixTcfaeS8(8;7I$&h`IXc0w%Ke5EvZoi0^W~vO|p4HV(*S2Lm)jxiM2~?IfikAyn z$rIso6}s^J90|-DEMq@^JJ@cWQXRxI#+tsP{bCSlg1uu{-^aJ_xkIV`(N(~OsE~6H z1yP~>`NI%VgH6WxeXH12WESN0aGtpLdl2OvcJs!IDZTvd&H=y>x@~0Ky~|h!6$(s{ zfoRFH#R3d4e27hA98K~V%^T^S)*5&I`d98xpGnLPAtOWQtO`iwL(&^^O$I_CJRjcZ zQuDu|1>a+FWvmh0Qw!>H1BKTruFFPxOvQYvcO#k)sUm-a3io4%YClb;TzG>ka2F!A zW}$AndN1dkV6MVT+kiG_L@R3h5&TyHwdGgBb3})}1}}{oQrg%L9`Ua1pBcskZ@-|; zerRBonrwC?Guzw<5sW(~C!<+vIID1iyd;nA&TSnRHF@~nmc0AZ0k5~&coSo_V;6JI zhOJN%XEse!8A@A!DPm_{m*w887sAgVR?$xH36$HCTd0?<_SJUr1vyN<35F$M%_I+v z5SyzuIQPi$U!Q6)f8ZXUPVmXF(6#QC#qc?FsTxf{D$TSFzON#AF)6|xR9HXZY|f8> zQUf3e&Jz<9wDeQ-r*nEw-PayhnAyKVBa#q1XH8+ z<(NrJ$ZGk@XB64h!!7Lys#Z_A1KEtnA7Tg*WZR%MQDI_LPJKS-7cXa*1uO4`Q~Tin zN*=d3jG2B)*91AM(6T#EHDK;7xB_%P^S=^LcMz%_%PT@&uPatTJ>m7ld&9kLR@&v> z#}1cx{t^4xmYu{4W=uHkj8EV5NFa5&xSVq2Ht81;pEn7+-W$QikriW|DEsV;(9XnR95|GP}TLckJ9!X7` zq}h8ssp-+6gQB(h0k`_o&O*ZqXiyCMc_EACW>gMUyakuSQ>JLjskB$wqz(6@i-rRu zGQRH@$hXse9uPr3AkWH#yoR4l-PoN_W}@K^F%EMmNib_x*_2>8iLf_{LTX`q`FvwE zj?ZMsEOS%jNeE-%E6UEeWs^^kmTFH89>mYNn@{H=`kW$wY|#hYMck^n__-fSzRuBi zr6cT}j7`*+8xE9D8;$2^gY7;)&YMVomlPXGE2ig?#m4*)t3){1h%hh!^WeGi89Lih zJxh)zdwqw>wjuTtMh3=@5#t}cW&`{QQ%bLWp#q$;wC= zoZYvZ2F^~FZBBmqG4Jgj4bGuhiP;+pWH!s6zkysh=yJXtOAbMzh)=z?(SiSz)us6*42{L~TgeW-v19}R?Aw#ZA4gK{D<5%B zuWbkx7<4KsD@4z?&FgM(`a%dY-Io?uKD!KwO34MkFmhy9u4u!N>xB~q@&_QpepiTj zFZVs|hrpvyXToxH8D|KBs+Kw&B3J%O&&&rN?~%yf(ND9fA*J23_q^ZmS7&u7Hv`f)jOKQCnMFp`_TCGCi9ndkk}@ zi{%P>lwg0YF^UwpO`H71GSoX-y)O5Z?X4VBzpk8WQeHdPSF&W<9SA*3dItwbA4geD zE?C=zi2aHXQJ3in9~@$9)MzB4>$>9cT&%nQu>Q(uUPQe$N|!dZArD=}__H zx9{1+ZaJun9ZWJgP-JRjrnM{NE}*6VN^BiReF*2oI5BL@Idtr{%#G4r3x}kh1-I%1 z`x-5OIPX(9R03pukqU?->-D{uGZs0->2r>^r<|V+KOYsCrO~<~J5BEF4NBPHqjXq4 z0p@#z=Z|v``r9W`xXfr|3$-ZbRN&;vS5^nTYTmHWD`;5f*=1_jW*+r!u<6vPRiR2( zK*gT2z_a{1J*;K7LCj$lHIp*+&>)YFSDWs>)P-DC41?Ff1L7V?U$U|Zu|SDb7tf$6 zBN9sR68K(j=8~QAmNXT;ONI)w?1h+7O$I5`G-7x}UJVxS<0S!s56uE6$haCW@Yf}4 z@pl8lp5r;xA&z2g^FK5fId!@?`h3VFse>b7uyQu+6zw#g(01_LNOdk8wM6}FNW{X; z&EZV(3)8nJhe6LIAPHsXtbXmfUv!UXMJ*HgK7CRvPKsO5(cD>VWe+Qv*gY(riCm|A zvR60K%VIIx4k6N@MzyC;NZ2Mlm}OSVV^}S&G3ocM$xJzU6trc!T~m9{b|nqThhkhc z{rYPja{U&2;jot;Vy$Q&{=F)syt${~pN!M26G%qgX9VJuN|09C_F-?O)1tlcQT`Ln zBIJ%@)5(_Q5BR&TgI&vq`TO0xC-fKKH&g-ZB1d#tP*L) zWIm>uYOR|gDcT8paW`sxcvnCgT zV@uN`?#vLSb7{$aiJfPiIk(2Hbwd9g8@qbRAfR#yGL$$TdL}&?NAd)|F)Cj!dQY~j z!m{<%^N^Qeaho{}AzERH2J=%N4x6)BQp|Of5(%q1a+k9TI7A!mEP!BSQSZd7?ynom zdKhFh8!s!@i(|t-IG!T&Gl9wXjdh6I%gp2h4?nT&{7A^*iS9ZeRGiN7tl-VeU-2Ws zGJCbr0y)|rCE40)LsxY4Vf7l1%};O`K`GAJ9_KX6HXo#ZLWd11N|Ui3n@O%~A0MZI zpBtNqcqhN6(xh_nM#sPHD7Ys$ds>V=zoMZ@9`_~oC?pDnlw9*W@Nv%jUcIz8G9Mu? zW%20hk!%svNi9uytqvC1&{IPEAe))tR#&{}o{$;Yw=I6(WX$u7S&TaSTF>)Fm4us} z@5}$FC&;^3`%yGZ+g^2PgS1iM?GTfR2thWRXZ;Wj@{r!dy1WMd;Z@k;DE;zo`sFhv zd;XS{emK5yv0k`EIjd+N#1!q;C-2SEt>_6Eu;=C^y-$dHKo2Q#i!c+um3;B}$+VA& zbs!FjEayCXn(WGoQQhr~@{NddOMDu)lIy9b?+i zUN$wJ9WE>&zsHj)rIeb;HcnfIx4iHH3-^J3VbN>(H+3Ya2l`*SJ7*8G9q<~Hr|?2X z@r!yQq+|e3S8RhO3DqE7k1=ZdW3*py0$@c7vdLe2sTdZuc}SJ;EKN8l+R?Tk{gUcEu7I-$JHKRND1Bja^^IFBi6C@s-G`Ui5NA*?|tz_w^zg3o+ZXK=j=9eb4WOk zg?^hi%_M}<3#{$#T<^~L3P00>$9ugl7)qE5RRLx1ViW%`3KZKnj`1vI(i|*W^Xn5_ zhSa^_uE>Bs6$?%FU{Wf1{ z<(=zhIf^Nr6ngae$d9?)tw`)w$p0P4ux+b0VVv2& zz?C|<_G9&-rW;5lgmpW5=-8HwL_mCmV};j(^EvPdV`$`HL2Fo+u6=NZhSfn7b7fbV zRliaW4#RZ9vxSmc_H~8;6ifbR_^(7Lj~&8FMZ3w+gP3EROtQRhK2Va z{w;)t9ItDi+nii?jgrgfJg=T3y7=~e?J@bW+iOwBtO4HDH~ON)CsrJ6NSjCVY-<~) zL&D(_Os9>D9Oa|9X%7ihm}{9I(0O4ZeHLaMiy%{`OpA8eI;IIl3Tsq-!NXcVKxcHg z@^w@0UJrkqHXV>u2}oaGW2Nct6T_620r7!I@p0SjG0Nmnc6DTMNlj}?Tqu%|eHrIi zG`d=@JYcS0eT1l`mGCA5Sgdm>cIA_K&HeVJT$yD$TY!b!st5w+W z(FU-z=k3tE5RAj01ojOd19JiV++(mmKjf)&x2P%BqMjZQ5-lxR1Gc$ zembcppzO+ii7RA5^_;OVj&_&yw3xMMDo|x8jYO{&M-(B+y*}&mE8toVge&5(c=aGo zJ>Z#L_xJ?BcM?D7XZJpq*lU*fsbX|4*82Em8HH z3bs6=Q{8M4$ASVv2WH>nAWvG8AlK_zw82%El*Z>PpT5|=G1~RcB@=;=qAHWpi%4c8 zq*%wLaO#X05%DRDbaWF01cdQ+ycVzvp{JM7Dy_4n;3VH`7}X5bWO&t)v%wx74uPS2vc8$YJu3_r4T*3kV>iX^__dj?7rRJRFYZ~e3jo2 zMH;vA%@B{xDcT)Tmf*S5&rFDersSwaK|#Biym~AW!)Dh5f{3L6#b*Qp{+TEBeJBJe zs#7h;*0{NO(W?h3seJn1>PcnQ9{B~iD0)SF2*iDiBwyg%pCFDV<;8KDqJxU-APvPE zLOt#|!+oCrd_Z2XNvOnFC})Cf+_7uig*I*{#6H~74l`5-ELtVa1)_oM7EK!G+V+Ia zzcE+ARU}xN?RA3XTF}m(@SqS;1TWYj3ez}5NU4T4m7j49XP0Fz?Yw6&hHI+s5iK&Z zKz`dkeM>biN8m#=1QBP!NP3+)iS@A`!GfN&jO?&F z-D5Y8hp5uiai$)phdoZQRXPi-UmIbtkTI)M zNAAr#no0U9>}+zP8HC>Nspw>B*^`kCkc{RObhex0;AOJZHrz*$gB>XD*vw##rNrLj zS)<;0Cy4`Nvun}%7j}a6arW<~S%WX(M0QEAxLQl}=i=S14iTvj?|+;fKSi^_6f5i( zCbqEHE0@1Wx?fWUOySq+L)1fV3AEoxkvd{#UmqeD!Vt$SCa`p~8%IuXQj=+_DX#%F zm|fHlKjSuHD!6z9G0py1Y-UwkPM0r{&9T~;n~NbjM62L!`vnXxn$>-&Zm^3MuZnJ1 zuo;f~k_JaCjWJ&L$h3(XiGi6+{2l5wC~5{>HDFD%TIu^3v}hJFjv$#Qf}pTkWpZ{K zdnIVwF(pWXXA_I)q&@e?NGL3jy<_Zn0Mi}{*cv78_NG%3?Vpn1_^w5j3Ft3QFb|;91Sz;2 zWvNA_OUrx!qy+?ockdU2w|b~H+6?SG3p*>4aOh}vtrSaKokMp|vSnmF^F1=u89rok z=o1IpGkE_Pg)}DO@KuFTAHJb9JykX_wBt;6uBt`3@RSdBf9i&;U&wt0bXz3T!{jXU z7?FGTEK5uoK4~^q)CLW|@)WF~k%^4+x}KuNu=29W1<#2)U`fDqe;2E5fsnF*`>WhA zeBc!vQ>e!gL?Qp)F-EX5wf|D|+T-!j@ZqLxBgxaGEr`5ygrNm?dxUgps@rTG)Z5rm zZu6=4(HK@X!uJ?lY5a(18BGyG=#qwgKYy`{5em9W(yRH!z86^O0q!l*yulb|9! z1)NRi(}7H2Uw-6#K7`D}^;X^UlSojFA=kCa$PtgiU`I+u?Ig;JyqM@355pf1G4)~a zS_p6TvY#&aWPYDdc+cRHZl1f&Y>Yo={eyd%Zg(v*?wkhjPDIQ^r!B09j*{bgZ|O0& zA;Q^*heKn;f-;>_1~OfbFE1Ijt5lJFCMGs!!#8yy>HFL>22+pHyk>c597ek)ziZT? zP_0)mpK4%CrrMU;l-RlMsX&7j!z4om;|LTs6y6Vt)TbA@#+ZEB3?@6c$OgN(6QMl+x=?AkJN#t9^04c?=21>uY%ba&-33P3v+sxK zbSm=axGF-fW{k(XDg<*nlbBAvIkofCowWii>=}gjBp*{#3HBu)glMf@?K71pwxtjU zynyLhJ9fjXSXjY-2hgIV3hV^>!3$nWK_NhpxJ(-}$to+>G;pYC# zuJsafB7)?ex)U29JR#^O>V9#ATIhZqvp@o8SwDclXdlOwd-^7Fxwnjxn|L^U)5{)3 zKQBRr+{R)4_P}<5Ra%i_0%HdJZk;< zByEOLM$9oU%4SUsr?udU08}AkC;C;&+qiLvqj2(R@?xh=4aIOg>uM6>T0a$a=5_jL ze9S-wjaEW$hKx%W&gQA-+{&x2mMVtogtj~yG*iP6I1S9x-g~`~9w#MFpEj5;Ldh49 zN0=;^XvD^!2Q$ANr*;_8ia}miDh)w}S``@~bXC)ulJhk3C}J$t!X1r4 zu+0o(&_+1EA4mSkDmtj}o#7sZ6fK+*T$N<&lvo=Gf&v2$ZNk2GDju$fv^cv^yyK?M zFg&Y8&D06z2$h~^d}pJU9z^<6yNSI~em>_@5y2OH^`Bu_6vyb^Z%fLS!a;-}ad$Tp zIR|Q9E!03vnMrrsTq4DD;sTppe3_yYNa;I9x5u+r;K?~ITB@z(0FUg**>!(bV>(Yr zhH++0QQ}^-CI)(naRZohvIljZ#bn>Y5^zQt?F)Cf(M6pugT+Zd#YzwtY3;i5r4pEma zrCnUkXLcKa{c-dWZ#Y#W1L31cds*{96HkiBmXci)yIGf&P;ChbF0^mmLIQ~wYVdP| z+uoSRZnNykLR0c4C*vLh(@#TEf0Vf-^pA({ z;dr1^0rcB>-vhn_-?n6Z+}xu&!o(r(f{CA3>A0pcC} zVxC{Xi1^i{W$-{Uc%FZO5$gzG4IKYo%zcZZDA5ZK#esT!gh5II^AO0O$g}X(1Uxrr zj{gyahxc~*$}BuC1w0SmziL3~&*94mcy92L|4Z=;Dv_Z2>KtAZM)8N@P#PV{08rG=M0{x8n!l@2D*Cw zAL~U#0h$P4&E)^`5#Oy>p*D#C%xeE=z!4HW-=C^xB>++g?pjses z>A&`bzDNh85%B%i^dD$bzB|_nX8<^`p^Z}j;#;rAmIFoz_Uc0zqLvF+*`G0VJ@dqM$T5{A!U(Ks|g+rTi~6R2r7sRAQ5`F*SOjW@P8YA#QJD zg2p9nZ|5v&>h%1DrGvBm3z{2nP8jef6*oT+jZ4$g#MuG{j|#&%y|Kz47^>h~@wxti z1*PGJwe2)4K)7GsRRd^(fr1rU>K#)_g4rQ)swA&OZXVe7z}976o3he z(gC2pNo$r401F}b|JjTe8ut^nS#Sq{4&f$T!O(Br0IHk3zU~IFP=LX=R{Yauzrkan zO3DDDYONkX7XlpUR!a2&*mk@?sLKFsJMKGR_CIO)p{Y**_n`(ofKSztg8*a%gqs!~ zzclO_f$a-R`^^ymD+TCp2v?Y|ZhZjDhZ1{O$($aCv4HyuV1@aO`<8?L_|5J-P{=rd zl@NRzegD|V6vjain&JT4U2zmpQ5`#RL(2C{aFv@%fIkgjWdz;k(w|fUx1#)!Coq(E zSgb;oMgis3%rgKsc&MZh>}ME$FAX&C+l>|iP{Bn2H4V?d;RyQ6WiW9BK+q@Ax8i)P zuA77LxhudRDCr`M3m@=?3o8!jFFQiT5@GtgCjc;@fvbR)YR&HeAA}e=1-x4c&{knq zfRz)r)f*rDKihIcr4s@7t3y`-A^;dN@2%}FHg9(1fq~@S#MfQ!{Pr9aCj&qP$6IZ) z1u%k#=f8DW+%A9?o*xLkzYAa^1plwU1bCr@8L)i;T?XZ_==yjJ@J56(w*t7KCKor90ymk&O8=KhZmjutaRSAS!VyDLVED|?nM(kg z9Jjz-63bhfIML|b_6DE<-R2Sv=(b+afOvkfrUCK(ihS7fmq2=doZcYlkT)EDOj8x$ zU+#*3aR=R2ZyL~T&7=YG|56q9{1uioAc4DWe)Tt0{SSM=o5l--|MFJ&o44REk!Zlc zTb|(CWT64yf<)7Re}OZr!k)hr{*yPD`vxYP=wIFs{^AYhzTcjf@| z{^CgkhQVUP$}3d)H5^$CM;qF|9RHRU%y&m|X8|z(FGtaU1%6c{*z;G2!k)h@^B-vi z|CLq%mP;x|FHG&6VXpp22xc4s+$twY5P;@T1UoxV}!1&w- z0O%G48|I>00YG>3;M?mO4fwVhC9KELFFt72w-M zxm&>vBe@0a)`Q_`TiRMW!%~h}(jE%IMMOjSMZ?Xa2c>BOkp7Yj3PeRjgz(%@{i-B) zYW{&Rp2HgF4kez$@jwlnZHA8ut6xEZ)3F|#yxd2y@NZPfiK%r7BeJ2L;X3QiB& z)OsfnBqY-ca4f_uY~k%icCJ{=Mdg^KIz< zDb??7F<^q-G6%!#WZiKq7N!yC#;jo~{InAyO0y|wN}V0HulHsmeU zjp1(V{O^r!EXNImMxrAUV%=- z0}Rt1eETZ#d*oNd+}6N5svEPyj=Y=g$!~V~XZSyvCkVyGL?kr=-zd#@=l5RAMPi$NolXf!l&{H*%w(0RN2~M3^_>amz~(W(CgC-&VMB0{5Rz z;J(rMwwB*faNp?ss~MW=?-7{Jw+(Xs8G-TP{*UXpVLNgI1#hkJj}Ks@|1|6?d zLSZt{iqPpjVK%U#L7RRm@M(CrJuom4ObfNpQ^G`BW}_F^JhKtXtjgw!zInVn3ZJ6qb@v2ud`mL7Jc{Y{Jp zllb;6jRqQtg=qGR92W!|{g?hG0lXIP^73X&RP>t=yE{*ys@S)?65+xI|DfW9k=d^P zNe1P^K~yK=xjiQSU3n7%f=~`TL{gj^i~l3{P2lTq{mB67#x}4^(#=}!n-KkH?SJjV z^Xmw@X`3J-^82{q7QBs3?z<@A7QDS+aNiwY+_z^54YwdK)D{CvZB2&Sq9Bq&_h2DG|Iewd?BZ-=X=e(1Mf-hB zDjC_re&hl2Ls{?)~JXuom}FKXMpn?wgm3zb1j)e9)0!lYg6u8w`6}14Hjq+z5R02K--2SlQ%-I>9Dk zuLJ)hFqj|eNCA^+lmd~7h))m*i~hf;VMXm`0X^l7&^NcnzvlU1ES^&$3XpKaO!_~w zys$Urk2kaY+&BLP^%pGlS)~%8`+T;@^;E*HD9;h^AhrzWYpV6FC+E;BB{uz`yGUAETI=Lea;mJ7V zpI0|ue6|q0QG_P?gth;Db@SY?T^4U>*a)RTKe_0xtDNg z+a=T!Cke*0@ZSw^(El>K0af?FR2IV@j<(DaH#3W+xGNuqrD{YWsnmD064_XhJ zSt)$a9=x41Eh#=l^%tnJFksSvo!iWs`LE_eqo>pK&l-EFJ;-jTx(%E29Eb_Vs_M6s zBvs+;%`kf zRR0VqDdk+OnQ#kdJ`@?WFtbg(g>N;Oa-?lI+z2I(P}GyKaCjhJ{MzBx@qy@>nXq33 z8eXk5GJmH-7vWVyko)@jQskCa1gI}cOkW5Pr3P-j$_auEKR-KA{Ql(gEX1D!mU~rI79ZTz> zDpY`;=Cq}^O^GaAY>wql2R?ASwm;T96sREELs>@FW@`RdKjTHZTucaR3y z+5#geQJt&KVU3Rp>!xv5(1h^K&aQ>l>cu3VU&==VoQKWS&LsNpuWr8FTFhirE9=Aj zwr~nHSR4C5MfiLi*dJR5aOv|fj%7=;({-zW6xC5*vyFxA=fc-<`N&7L3VadabPRSd z_8zB+uu`R`2GG-8cM3$@47pYo9tk)pG-}nQxSVTC2WBX!#~#H7MgGJ+LNF|%z&s5+ zH*AoCsLw<8sa@dw7qwD~gD`;=HaJ$g4%r~#XH#*v>9Karr+oLZxL7m&3o$L-<}8PoRJCv^4XoCx*uKLirluyVDMN zlFSqm^vpe|dNK?_K0OQP-ChH%wnfpF?- z_l1fe2?SrL+QTi&3mOC{+mP_+N33DjvrqNs>|7?SQv>dv`cVI%3sw|~Y$z}$8=RU! z_OI?2fRu%ghc(m@d&aXEHP5{>K;^leY$S3`K}TqG4O zy>JyByV#Id0Xwv6SC3AsD?={TOx_BUAz>u4{Vaz05gku(LPn0--SWmj3P~zAkcF&) zU+(4I{Qu(pmBF+!cAlpv=|pFs^=Nk{ELwE9fqd=|pVr;uZy9{kS>w}uP}Makfl8b7 zJYqUB&vFg1rwGF@v*r|NTW~l!)8QZz8p1vBLa#!0ykFZLZ47N_55=t`^Ief;RPlrj zIR9DwxXjd+lMC#kHGl2k05KCUFpzy@kx}u(K+CR?H~sUnLfj$1LSYj(heP9?t}5U^ zW-0W3vM}zeV;pWzmd$RMjw*zRm6b+M9B8F$i3ZWo>#A&Pn#_0$qdrI775_1_LD?!i z@pYl`ih`mX8r={PKrR|Il_ied^Uyz#1Vbq!vFI3$k5~+Roq$r=8A6sy8E^nJ`X8|q z_e#TFt8pe_)~Uq=pv{yv@R4c)je$m>U9@_^e>`x66R!+S1VU%t`Uxgk>wc~1H%&N& z!%=g*wivS-gbO?5Hb>RJG7OJ=S19$|RMOw(;77cgq^%u%Wv+t%Y?^Vj=O2$hfBfa) zkt^HN>mNS;^>6|u+`j&vS7W%EWHa_M>9@ar_>JE<*Z$kv(~n=jBj?<|x3NmOuWwU* vGxL3aQ$cujpXz^eIxIADYdL>DK76") */ + if xengine = 'SASFSVAM' then do; + sFilename = ' '; + sHostOptions = "recfm=n lrecl=1" + !! " folderpath=" !! quote(strip(xpath)) + !! " filename=" !! quote(cats(package, ".zip")) + ; + end; + else do; + sFilename = cats(strip(xpath), "/", package, ".zip"); + sHostOptions = "recfm=n lrecl=1"; + end; + + sAssigned = filename(sFileref + ,sFilename + ,xengine + ,sHostOptions); + + if debug then putlog sAssigned= sFileRef= / xengine=; + leave=0; + LINK LoopTryCopyFile; /* LINK 1 */ + if leave then leave; + end; + sAssigned = filename(sFileRef); + tAssigned = filename(tFileRef); + + stopForThisPackage1: + if 0=leave then putlog "ERROR: Fail to process " package; + end; + /*=========================================================================================================*/ + + /* copy from some location to PACKAGES */ + /*=========================================================================================================*/ + when(0=sFromPackages AND 1=tFromPackages AND 0=sAssigned) + do; + select; + /* disk */ + when (sDevice in ("DISK" "BASE")) + do; + if NOT sExists then GOTO stopForThisPackage2; + sAssigned = filename(sFileRef + ,cats(source, "/", package, ".zip") + ,strip(sDevice) + ,"recfm=n lrecl=1"); + end; + /* zip */ + when (sDevice in ("ZIP")) + do; + sAssigned = filename(sFileRef + ,cats(source) + ,strip(sDevice) + ,"recfm=n lrecl=1 member=" !! quote(cats(package, ".zip")) ); + end; + /* filesrvc */ + when (sDevice in ("FILESRVC" "SASFSVAM")) + do; + sAssigned = filename(sFileRef + ,/*blank*/ ,strip(sDevice) + ,"recfm=n lrecl=1" + !! " folderpath=" !! quote(cats(source)) + !! " filename=" !! quote(cats(package, ".zip")) + ); + end; + /* other */ + otherwise + do; + putlog "ERROR: Unsupported device: " sDevice +(-1) ". Exiting!"; + GOTO stopForThisPackage2; + end; + end; + + if debug then putlog sAssigned= sFileRef= / sDevice=; + + if NOT fexist(sFileRef) then + do; + putlog "WARNING: File: " package +(-1) ".zip does NOT exist inside: " source; + end; + else + do; + _rc_ = tIter.first(); + _rc_ = tIter.prev(); + do while(tIter.next()=0); + + /* If Viya File Service, we need to use: + filename('fileref', ,'FILEFSVAM', "") */ + if xengine = 'SASFSVAM' then do; + tFilename = ' '; + tHostOptions = "recfm=n lrecl=1" + !! " folderpath=" !! quote(strip(xpath)) + !! " filename=" !! quote(cats(package, ".zip")) + ; + end; + else do; + tFilename = cats(strip(xpath), "/", package, ".zip"); + tHostOptions = "recfm=n lrecl=1"; + end; + + tAssigned = filename(tFileRef + ,tFilename + ,xengine + ,tHostOptions); + + if debug then putlog tAssigned= tFileRef= / xengine=; + leave=0; + LINK LoopTryCopyFile; /* LINK 1 */ + if leave then leave; + end; + tAssigned = filename(tFileRef); + end; + + sAssigned = filename(sFileRef); + stopForThisPackage2: + if 0=leave then putlog "ERROR: Fail to process " package; + end; + /*=========================================================================================================*/ + /** + when(0) do; put "future cases"; end; + **/ + otherwise putlog "WARNING: Unknown combination."; + end; + end; + + LINK stopProcessing; + /** the end **/ + STOP; + + /* LINK 1 */ + loopTryCopyFile: + do try = 1 to &try. while(leave=0); + + length s_HASHING t_HASHING $ 128; + + %if &checksum. AND &HASHING_FILE_exist. %then + %do; + if try = 1 AND fexist(tFileRef) then /* check SHA256 only for first try */ + do; + LINK GETSHA256DIGEST; /* LINK 2 */ + + if s_HASHING=t_HASHING then + do; + putlog "INFO: The SHA256 hash digest for source and target are identical." + / @7 "Checksum: " t_HASHING + / @7 "Package will not be copied."; + _rc_ = 0; + end; + else + do; /* message only for the first time */ + putlog "INFO: The SHA256 hash digest for source and target are different." + / @7 "Target checksum: " t_HASHING + / @7 "Source checksum: " s_HASHING + / @7 "Copying package."; + _rc_ = fcopy(sFileRef, tFileRef); + _rcTxt_ = sysmsg(); + end; + end; + else /* keep this ELSE unclosed for... */ + %end; + + do; /* ... this DO-END block */ + _rc_ = fcopy(sFileRef, tFileRef); + _rcTxt_ = sysmsg(); + end; + + if debug then putlog _rc_= / _rcTxt_=; + leave + (_rc_=0)*fexist(tFileRef); + + %if &HASHING_FILE_exist. = 1 %then + %do; + if leave then /* compare SHA256 after copy */ + do; + LINK GETSHA256DIGEST; /* LINK 2 */ + + if NOT (s_HASHING=t_HASHING) then + putlog "WARNING: The SHA256 hash digest is different for source and target!" + / "WARNING- Source is: " s_HASHING + / "WARNING- Target is: " t_HASHING + / "WARNING- There could be errors during copying. Check your files."; + end; + %end; + + if (leave AND move) then + do; + _rc_ = fdelete(sFileRef); + if _rc_ then putlog "WARNING: Target successfully copied, but cannot delete source file while moving."; + end; + if not leave then _rc_ = sleep(1,0.25); + end; + return; + + /* LINK 2 */ + GETSHA256DIGEST: + %let ST_list=t s; /* for source(s) and for target(t), repeat the same structure twice with different prefix */ + %do i=1 %to 2; + %let st=%scan(&ST_list., &i.); + select; + when (&st.Device in ("ZIP")) &st._HASHING=HASHING_FILE("SHA256", &st.FileRef, 4); + when (&st.Device in ("DISK" "BASE")) &st._HASHING=HASHING_FILE("SHA256", pathname(&st.FileRef,'F'), 0); + otherwise /* for FILESRVC and SASFSVAM*/ + do; + &st._sha256 = hashing_init("SHA256"); + &st._FID = fopen(&st.FileRef, "i", 1, "B"); /* read only in binary format */ + if &st._FID then do while(fread(&st._FID)=0); + length &st.c $ 1; + _rc_ = fget(&st._FID, &st.c, 1); + _rc_ = hashing_part(&st._sha256, &st.c); + end; + &st._FID = fclose(&st._FID); + &st._HASHING = hashing_term(&st._sha256); + end; + end; + %end; + return; + + /* LINK 3 */ + stopProcessing: + putlog 32*"*" 24*"=" 32*"*"; + stop; + return; + + run; + + /* restore optionos */ + options ls = &ls_tmp. ps = &ps_tmp. + ¬es_tmp. &source_tmp. + &stimer_tmp. &fullstimer_tmp. + msglevel=&msglevel_tmp. &mautocomploc_tmp.; + +%ENDofrelocatePackage: +%mend relocatePackage; + +/* tests on Viya: + +filename PACKAGES list; + +%let user= <...>; + +filename backup filesrvc + folderpath="/Users/&user./My Folder/SASPACKAGES"; +filename backup list; + +%put %sysfunc(pathname(backup)); + +data _null_; + x=getoption("SERVICESBASEURL"); + put x=; +run; + +options ls = 90; +%* move from PACKAGES to a FILESRVC location*; +%relocatePackage(baseplus SQLinDS macroarray +,target=/Users/&user./My Folder/SASPACKAGES +,tDevice=FILESRVC +,move=1) + +%* move back to PACKAGES from a FILESRVC location*; +%relocatePackage(baseplus SQLinDS macroarray +,source=/Users/&user./My Folder/SASPACKAGES +,sDevice=FILESRVC +,move=1) + +%* create a ZIP bundle with packages in HOME *; +%relocatePackage(baseplus SQLinDS macroarray +,target=~/SASPACKAGESbundle.zip +,tDevice=ZIP) +*/ +/* SERVICESBASEURL */ + +/* Tests on SAS: + +options mprint msglevel=N; + +filename PACKAGES ("R:\" "C:\SAS_WORK\SAS_PACKAGES"); + +%relocatePackage(myPackage) + +options nomprint msglevel=N; +%relocatePackage(baseplus SQLinDS macroarray, target=R:\abc, debug=1) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\noDir) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\bundle.zip, tDevice=zip) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\, tDevice=FILESRVC) + +filename PACKAGES ("R:\testPackages1_NOT_EXIST" "R:\testPackages2_NOT_EXIST"); +%relocatePackage(baseplus SQLinDS macroarray abc, source=R:\abc, debug=1, move=1) + +filename PACKAGES ("R:\testPackages1" "R:\testPackages2"); +%relocatePackage(baseplus SQLinDS macroarray abc, source=R:\abc, debug=1, move=1) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\noDir, debug=1) + +filename PACKAGES ("R:\testPackages2" "R:\testPackages1"); +%relocatePackage(baseplus SQLinDS macroarray, source=R:\bundle.zip, sDevice=zip, move=1) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\, sDevice=FILESRVC) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\bundle.zip, sDevice=zip, target=R:\bundle) +*/ +/*%macro _();%mend _;*/ +/**/ + diff --git a/SPF/Macros/saspackagesframeworknotes.sas b/SPF/Macros/saspackagesframeworknotes.sas new file mode 100644 index 0000000..2f9734f --- /dev/null +++ b/SPF/Macros/saspackagesframeworknotes.sas @@ -0,0 +1,165 @@ +/*+SasPackagesFrameworkNotes+*/ +%macro SasPackagesFrameworkNotes( +SPFmacroName /* space separated list of names */ +) +/ +minoperator +secure +des = 'Macro to provide help notes about SAS Packages Framework macros, version 20251221. Run %SasPackagesFrameworkNotes(HELP) for help info.' +; +%local list N i element; +%let list= +installPackage +listPackages +/**/ +verifyPackage +previewPackage +helpPackage +/**/ +loadPackage +loadPackageS +loadPackageAddCnt +/**/ +unloadPackage +/**/ +generatePackage +splitCodeForPackage +/**/ +extendPackagesFileref +relocatePackage +isPackagesFilerefOK +/**/ +SasPackagesFrameworkNotes +; +%let N = %sysfunc(countw(&list.)); + +%let SPFmacroName = %sysfunc(compress(%superq(SPFmacroName),_ *,KAD)); + +%if (%qupcase(&SPFmacroName.) = HELP) %then + %do; + %local options_tmp ; + %let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps)) + %sysfunc(getoption(notes)) %sysfunc(getoption(source)) + msglevel=%sysfunc(getoption(msglevel)) + %sysfunc(getoption(mprint)) %sysfunc(getoption(mlogic)) %sysfunc(getoption(symbolgen)) + ; + options NOnotes NOsource ls=MAX ps=MAX msglevel=N NOmprint NOmlogic NOsymbolgen; + %put ; + %put #################################################################################; + %put ### This is short help information for the `SasPackagesFrameworkNotes` macro #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Macro prints help notes for SAS Packages Framework macros, version `20251221` #; + %put # #; + %put # A SAS package is a zip file containing a group #; + %put # of SAS codes (macros, functions, data steps generating #; + %put # data, etc.) wrapped up together and included by #; + %put # a single `load.sas` file (also embedded inside the zip). #; + %put # #; + %put # The `%nrstr(%%SasPackagesFrameworkNotes())` macro provides help notes about #; + %put # components of the SAS Packages Framework. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put #### Parameters: #; + %put # #; + %put # 1. `SPFmacroName` *Required.* Names of a SPF components. #; + %put # Names should be space separated, asterisk(*) is #; + %put # allowed too. In such case ALL help notes are printed #; + %put # If equal `HELP` displays this help information. #; + %put # If empty displays list of SPF macros. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #; + %put # to learn more. #; + %put # Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` #; + %put # #; + %put ### Example 1 ###################################################################; + %put # #; + %put # Run the following code to print all SPF help notes: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes(*) %%* print ALL notes; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put ### Example 2 ###################################################################; + %put # #; + %put # Run the following code to list all SPF macros: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes() %%* list all macro names; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put ### Example 3 ###################################################################; + %put # #; + %put # Run the following code to print help notes: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes(generatePackage helpPackage) ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put #################################################################################; + %put ; + options &options_tmp.; + %GOTO ENDofSPFNotes; + %end; + +%if %sysevalf(%superq(SPFmacroName)=,boolean) %then + %do; + %put ================================================================; + %put %str( ) SAS Packages Framework provides the following macros:; + %put ================================================================; + %do i = 1 %to &N.; + %let element = %scan(&list., &i.); + %if &i. IN (3 6 9 10 12) %then %put %str( ); + %if &i. > 9 %then %put %str( )&i.. %NRSTR(%%)&element.(); + %else %put %str( )&i.. %NRSTR(%%)&element.(); + %end; + %put =================================================================; + %end; +%else %if %str(*) IN (%superq(SPFmacroName)) %then + %do; + %do i = 1 %to &N.; + %let element = %scan(&list., &i.); + %put %str( ); + %put ======; + %&element.(HELP) + %put ======; + %end; + %end; +%else + %do; + %let N = %sysfunc(countw(%superq(SPFmacroName))); + %do i = 1 %to &N.; + %let element = %qupcase(%scan(%superq(SPFmacroName), &i.)); + %if %superq(element) in (%upcase(&LIST.)) %then + %do; + %let element = %unquote(&element.); + %put %str( ); + %put ======; + %&element.(HELP); + %put ======; + %end; + %else + %do; + %put %str( ); + %put ***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***; + %put WARNING: Cannot recognise name: %superq(element).; + %put WARNING- Valid values are: %superq(list); + %put ***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***; + %end; + %end; + %end; + +%ENDofSPFNotes: +%mend SasPackagesFrameworkNotes; + +/* +%SasPackagesFrameworkNotes() +%SasPackagesFrameworkNotes(HELP) +options mlogic symbolgen; +%SasPackagesFrameworkNotes(generatePackage) +%SasPackagesFrameworkNotes(generatePackage helpPackage) +%SasPackagesFrameworkNotes(generatePackage helpPackages SasPackagesFrameworkNotes isPackagesFilerefOK) +%SasPackagesFrameworkNotes(*) +*/ + + +/* end of SPFinit.sas file */ diff --git a/SPF/Macros/splitcodeforpackage.sas b/SPF/Macros/splitcodeforpackage.sas index 18ad5fa..3b78b67 100644 --- a/SPF/Macros/splitcodeforpackage.sas +++ b/SPF/Macros/splitcodeforpackage.sas @@ -7,10 +7,9 @@ ,debug=0 /* technical parameter */ ,nobs=0 /* technical parameter */ ) -/*** HELP START ***/ -/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20251126. Run %splitCodeForPackage() for help info.' +/*** HELP END ***/ +/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20251221. Run %splitCodeForPackage() for help info.' ; -/*%macro _();%mend _;*/ %if (%superq(codeFile) = ) OR (%qupcase(&codeFile.) = HELP) %then %do; %local options_tmp ; @@ -25,7 +24,7 @@ %put #-------------------------------------------------------------------------------#; %put # #; %put # Utility macro to *split* single file with SAS package code into multiple #; - %put # files with separate snippets, version `20251126` #; + %put # files with separate snippets, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -49,7 +48,7 @@ %put # #; %put # - `packagePath=` *Required.* Location for package files after #; %put # splitting into separate files and directories. #; - %put # If missing or not exist then `WORK` is uded. #; + %put # If missing or not exist then `WORK` is used. #; %put # #; %put # - `debug=` *Optional.* Turns on code printing for debugging. #; %put # #; @@ -401,7 +400,7 @@ options nomprint nosymbolgen nomlogic notes source ls=MAX ps=MAX msglevel=N ; */ if firstLine[j] then do; - put '/* File generated with help of SAS Packages Framework, version 20251126. */'; + put '/* File generated with help of SAS Packages Framework, version 20251221. */'; firstLine[j]=0; end; put _infile_; @@ -417,4 +416,3 @@ options &options_tmp2.; %ENDofsplitCodeForPackage: %mend splitCodeForPackage; -/**/ diff --git a/SPF/Macros/unloadpackage.sas b/SPF/Macros/unloadpackage.sas index 0b6c79e..04051f5 100644 --- a/SPF/Macros/unloadpackage.sas +++ b/SPF/Macros/unloadpackage.sas @@ -20,7 +20,7 @@ */ )/secure /*** HELP END ***/ -des = 'Macro to unload SAS package, version 20251126. Run %unloadPackage() for help info.' +des = 'Macro to unload SAS package, version 20251221. Run %unloadPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -35,7 +35,7 @@ des = 'Macro to unload SAS package, version 20251126. Run %unloadPackage() for h %put ### This is short help information for the `unloadPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to unload SAS packages, version `20251126` #; + %put # Macro to unload SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; diff --git a/SPF/Macros/verifypackage.sas b/SPF/Macros/verifypackage.sas index dc385f7..36df5a6 100644 --- a/SPF/Macros/verifypackage.sas +++ b/SPF/Macros/verifypackage.sas @@ -13,7 +13,7 @@ hashing_file() function, SAS 9.4M6 */ )/secure /*** HELP END ***/ -des = 'Macro to verify SAS package with the hash digest, version 20251126. Run %verifyPackage() for help info.' +des = 'Macro to verify SAS package with the hash digest, version 20251221. Run %verifyPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -28,7 +28,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20251126. Run % %put ### This is short help information for the `verifyPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to verify SAS package with it hash digest, version `20251126` #; + %put # Macro to verify SAS package with it hash digest, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; diff --git a/SPF/SPFinit.md b/SPF/SPFinit.md index 4d45440..1f4da59 100644 --- a/SPF/SPFinit.md +++ b/SPF/SPFinit.md @@ -1,7 +1,7 @@ --- -# SAS Packages Framework, version `20251126` +# SAS Packages Framework, version `20251221` --- @@ -18,6 +18,9 @@ * [the `extendPackagesFileref` macro](#extendpackagesfileref) * [the `loadPackageAddCnt` macro](#loadpackageaddcnt) * [the `splitCodeForPackage` macro](#splitcodeforpackage) + * [the `relocatePackage` macro](#relocatepackage) + * [the `isPackagesFilerefOK` macro](#ispackagesfilerefok) + * [the `SasPackagesFrameworkNotes` macro](#saspackagesframeworknotes) * [Some more examples](#some-more-examples) -------------------------------------------------------------------------------------------- @@ -29,7 +32,7 @@ A **SAS package** is an automatically generated, single, stand alone *zip* file The *purpose of a package* is to be a simple, and easy to access, code sharing medium, which will allow: on the one hand, to separate the code complex dependencies created by the developer from the user experience with the final product and, on the other hand, reduce developer's and user's unnecessary frustration related to a remote deployment process. -In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20251126`**. +In this repository we are presenting the **SAS Packages Framework** which allows to develop and use SAS packages. The latest version of SPF is **`20251221`**. **To get started with SAS Packages** try this [**`Introduction to SAS Packages`**](https://youtube.com/playlist?list=PLeMzGEImIT5eV13IGXQIgWmTFCJt_cLZG&si=ElQm0_ifq76mvUbq "Introduction to SAS Packages video series") video series or [**`Getting Started with SAS Packages`**](https://github.com/yabwon/SAS_PACKAGES/blob/main/SPF/Documentation/Getting_Started_with_SAS_Packages.pdf "Getting Started with SAS Packages") presentation (see the `./SPF/Documentation` directory). @@ -52,7 +55,7 @@ them using the SPF can be found [**HERE**](https://github.com/yabwon/HoW-SASPack ## This is short help information for the `installPackage` macro -------------------------------------------------------------------------------------------- - Macro to install SAS packages, version `20251126` + Macro to install SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -180,7 +183,7 @@ filename packages "C:/SAS_PACKAGES"; ## This is short help information for the `helpPackage` macro ------------------------------------------------------------------------------- - Macro to get help about SAS packages, version `20251126` + Macro to get help about SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -258,7 +261,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ## This is short help information for the `loadPackage` macro ------------------------------------------------------------------------------- - Macro to *load* SAS packages, version `20251126` + Macro to *load* SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -416,7 +419,7 @@ If created, those macros are automatically deleted when the `%unloadPackage()` m ## This is short help information for the `loadPackageS` macro ------------------------------------------------------------------------------- - Macro wrapper for the loadPackage macro, version `20251126` + Macro wrapper for the loadPackage macro, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -459,7 +462,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; %include packages(SPFinit.sas); %* enable the framework; %installPackage(SQLinDS DFA) %* install packages from the Internet; -%loadPackageS(SQLinDS, DFA) %* load packags content into the SAS session; +%loadPackageS(SQLinDS, DFA) %* load packages content into the SAS session; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -467,7 +470,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ## This is short help information for the `unloadPackage` macro ------------------------------------------------------------------------------- - Macro to unload SAS packages, version `20251126` + Macro to unload SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -534,14 +537,14 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ## This is short help information for the `listPackages` macro ----------------------------------------------------------------------------------------- - Macro to list available SAS packages, version `20251126` + Macro to list available SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating data, etc.) wrapped up together and embedded inside the zip. The `%listPackages()` macro lists packages available - in the packages folder. List is printed inthe SAS Log. + in the packages folder. List is printed in the SAS Log. ### Parameters: @@ -577,7 +580,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ## This is short help information for the `verifyPackage` macro ------------------------------------------------------------------------------- - Macro to verify SAS package with it hash digest, version `20251126` + Macro to verify SAS package with it hash digest, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -631,7 +634,7 @@ filename packages "C:/SAS_PACKAGES"; %* set-up a directory for packages; ## This is short help information for the `previewPackage` macro ------------------------------------------------------------------------------- - Macro to get preview of a SAS packages, version `20251126` + Macro to get preview of a SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -700,7 +703,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ## This is short help information for the `generatePackage` macro ------------------------------------------------------------------------------- - Macro to generate SAS packages, version `20251126` + Macro to generate SAS packages, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -927,14 +930,14 @@ All files have to have `.sas` extension. Other files are ignored. ## This is short help information for the `extendPackagesFileref` macro ----------------------------------------------------------------------------------------- - Macro to list directories pointed by 'packages' fileref, version `20251126` + Macro to list directories pointed by 'packages' fileref, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating data, etc.) wrapped up together and embedded inside the zip. The `%extendPackagesFileref()` macro lists directories pointed by - the packages fileref. It allows to add new dierctories to packages folder list. + the packages fileref. It allows to add new directories to packages folder list. ### Parameters: @@ -969,7 +972,7 @@ filename packages ("D:/NEW_DIR" %extendPackagesFileref()); %* add new directory; ## This is short help information for the `loadPackageAddCnt` macro ------------------------------------------------------------------------------- - Macro to load *additional content* for a SAS package, version `20251126` + Macro to load *additional content* for a SAS package, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -1063,7 +1066,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ------------------------------------------------------------------------------- Utility macro to *split* single file with SAS package code into multiple - files with separate snippets, version `20251126` + files with separate snippets, version `20251221` A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -1087,7 +1090,7 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; - `packagePath=` *Required.* Location for package files after splitting into separate files and directories. - If missing or not exist then `WORK` is uded. + If missing or not exist then `WORK` is used. - `debug=` *Optional.* Turns on code printing for debugging. @@ -1141,6 +1144,220 @@ filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; ,packagePath=C:/split/ ) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +## This is short help information for the `relocatePackage` macro +------------------------------------------------------------------------------- + + Macro to *locally copy or move* (relocate) SAS packages, version `20251221` + + A SAS package is a zip file containing a group + of SAS codes (macros, functions, data steps generating + data, etc.) wrapped up together and included by + a single `load.sas` file (also embedded inside the zip). + + The `%relocatePackage()` is a utility macro for local copying or moving + SAS packages. The macro transfers packages located in the `PACKAGES` + fileref to a selected directory (`DISK` device), folderpath (`FILESRVC` + device), or a zip file (`ZIP` device). + + The macro allows for a bidirectional transfer of packages, i.e., from the + `PACKAGES` fileref to the selected *target*, or from the selected *source* + to the `PACKAGES` fileref. + +------------------------------------------------------------------------------- +### Parameters: + + 1. `packageName` *Required.* Name of a package, e.g. myPackage. + A space-separated(!) list of packages to transfer is + also accepted. If empty displays this help information. + + - `source=` *Required/Optional.* Source location for packages. + When used, indicates a directory (`DISK` device), + a folderpath (`FILESRVC` device), or a zip file (`ZIP` + device) *from* where packages will be copied. + In this case `PACKAGES` fileref is target location. + Cannot be used together with `target=` parameter. + + - `target=` *Required/Optional.* Target location for packages. + When used, indicates a directory (`DISK` device), + a folderpath (`FILESRVC` device), or a zip file (`ZIP` + device) *to* where packages will be copied. + In this case `PACKAGES` fileref is source location. + Cannot be used together with `source=` parameter. + + - `sDevice=` *Required/Optional.* When `source=` is used this + parameter provides which type of device to be use. + Default value is `DISK`, values `ZIP` and `FILESRVC` + are allowed. For `FILESRVC` the `folderpath=` is used. + + - `tDevice=` *Required/Optional.* When `target=` is used this + parameter provides which type of device to be use. + Default value is `DISK`, values `ZIP` and `FILESRVC` + are allowed. For `FILESRVC` the `folderpath=` is used. + + - `checksum=` *Optional.* Indicates if packages should be copied only + if the source (from file) checksum is different than + the target (to file). Default value is 0 (always copy). + + - `move=` *Optional.* Indicates if packages should be moved from + source to target, default value is `0`, + when set to `1`: after *successful* copying packages + in the source are *deleted*. Use carefully! + + - `debug=` *Optional.* Indicates if debug notes should be printed, + default value is `0`, when set to `1`: debug info + is printed. + + - `try=` *Optional.* Number of tries when copy is unsuccessful, + default value is `3`, allowed values are integers + from 1 to 9. Time between tries is quarter of a second. + +------------------------------------------------------------------------------- + + Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` + to learn more. + Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` + +### Example 1 ################################################################## + + Enabling the SAS Package Framework from the local + directory, copying SQLinDS package from Viya Files + service, and loading the package to the SAS session. + + Assume that the `SPFinit.sas` file is located in the "/home/user/PCKG" + directory and Viya Files service location is "/files/packages/" + + Run the following code in your SAS session: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + filename packages "/home/user/PCKG"; %* setup a directory for packages; + %include packages(SPFinit.sas); %* enable the framework; + + %relocatePackage(SQLinDS %* copy the package from Viya Files service; + ,source=/files/packages/ + ,sDevice=FILESRVC) + %loadPackage(SQLinDS) %* load the package content into the SAS session; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +### Example 2 ################################################################## + + Enabling the SAS Package Framework from the local directory + and creating a "bundle" file by moving 3 packages: the BasePlus, + the SQLinDS, and the MacroArray package into the target file. + + Assume that the `SPFinit.sas` file + is located in the "C:/SAS_PACKAGES/" folder. + + Run the following code in your SAS session: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + filename packages "C:/SAS_PACKAGES"; %* setup a directory for packages; + %include packages(SPFinit.sas); %* enable the framework; + + %relocatePackage(BasePlus SQLinDS MacroArray %* create a bundle of packages; + ,target=D:/archive/bundle_2025_12_15.zip + ,tDevice=ZIP, move=1) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +## This is short help information for the `isPackagesFilerefOK` macro +----------------------------------------------------------------------------------------- + + Macro to check if the `packages` fileref is "correct", version `20251221` + + A SAS package is a zip file containing a group + of SAS codes (macros, functions, data steps generating + data, etc.) wrapped up together and embedded inside the zip. + + The `%isPackagesFilerefOK()` macro checks if the `packages` fileref + is correct, i.e. all listed directories exist, are accessible (can be open), and + are assigned with the DISK device. + + The Macro works as a macro function. It returns `1` when everything is OK, and + it returns `0` if at least one issue exists. + +### Parameters: + + 1. `vERRb` - *Optional* Indicates if the macro should return value AND be verbose + (e.g., print errors and notes) or just return value. + + When used as: `%isPackagesFilerefOK(HELP)` it displays this help information. + +----------------------------------------------------------------------------------------- + + Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` + to learn more. + Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` + +### Example ############################################################################# + + Enabling the SAS Package Framework from the local + directory, expanding PACKAGES fileref, and checking + if the new one is still correct for installing new package. + + Assume that the `SPFinit.sas` file + is located in the "/sas/PACKAGES/" directory. + + Run the following code in your SAS session: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + filename packages "/sas/PACKAGES"; %* set packages filename; + %include packages(SPFinit.sas); %* enable the framework; + + filename packages ("~/myPCKGs" %extendPackagesFileref()); %* add new directory; + + %if %IsPackagesFilerefOK() %then %* check fileref; + %do; %InstallPackage(SQLinDS) %end; %* install SQLinDS; + + %listPackages() %* list packages; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +## This is short help information for the `SasPackagesFrameworkNotes` macro +------------------------------------------------------------------------------- + + Macro prints help notes for SAS Packages Framework macros, version `20251221` + + A SAS package is a zip file containing a group + of SAS codes (macros, functions, data steps generating + data, etc.) wrapped up together and included by + a single `load.sas` file (also embedded inside the zip). + + The `%SasPackagesFrameworkNotes()` macro provides help notes about + components of the SAS Packages Framework. + +------------------------------------------------------------------------------- +### Parameters: + + 1. `SPFmacroName` *Required.* Names of a SPF components. + Names should be space separated, asterisk(*) is + allowed too. In such case ALL help notes are printed + If equal `HELP` displays this help information. + If empty displays list of SPF macros. + +------------------------------------------------------------------------------- + + Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` + to learn more. + Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` + +### Example 1 ################################################################## + + Run the following code to print all SPF help notes: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %SasPackagesFrameworkNotes(*) %* print ALL notes; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +### Example 2 ################################################################## + + Run the following code to list all SPF macros: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %SasPackagesFrameworkNotes() %* list all macro names; +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +### Example 3 ################################################################## + + Run the following code to print help notes: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas + %SasPackagesFrameworkNotes(generatePackage helpPackage) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + + ------------------------------------------------------------------------------- ------------------------------------------------------------------------------- diff --git a/SPF/SPFinit.sas b/SPF/SPFinit.sas index 90b67d7..d752157 100644 --- a/SPF/SPFinit.sas +++ b/SPF/SPFinit.sas @@ -1,3 +1,4 @@ + /**############################################################################**/ /* */ /* Copyright Bartosz Jablonski, since July 2019. */ @@ -12,7 +13,7 @@ /* */ /* Here is the official version: */ /* - Copyright (c) 2019 - 2025 Bartosz Jablonski (yabwon@gmail.com) + Copyright (c) 2019 - 2026 Bartosz Jablonski (yabwon@gmail.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -38,11 +39,11 @@ /* SPF (SAS Packages Framework) is a set of macros: - to install, - to load, - - to get help, - - to unload, or + - to get help, + - to unload, or - to generate SAS packages. - Version 20251126. + Version 20251221. See examples below. A SAS package is a zip file containing a group of files @@ -91,7 +92,7 @@ */ )/secure /*** HELP END ***/ -des = 'Macro to load SAS package, version 20251126. Run %loadPackage() for help info.' +des = 'Macro to load SAS package, version 20251221. Run %loadPackage() for help info.' minoperator ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then @@ -107,7 +108,7 @@ minoperator %put ### This is short help information for the `loadPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to *load* SAS packages, version `20251126` #; + %put # Macro to *load* SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -384,7 +385,7 @@ minoperator */ )/secure /*** HELP END ***/ -des = 'Macro to unload SAS package, version 20251126. Run %unloadPackage() for help info.' +des = 'Macro to unload SAS package, version 20251221. Run %unloadPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -399,7 +400,7 @@ des = 'Macro to unload SAS package, version 20251126. Run %unloadPackage() for h %put ### This is short help information for the `unloadPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to unload SAS packages, version `20251126` #; + %put # Macro to unload SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -552,7 +553,7 @@ des = 'Macro to unload SAS package, version 20251126. Run %unloadPackage() for h */ )/secure /*** HELP END ***/ -des = 'Macro to get help about SAS package, version 20251126. Run %helpPackage() for help info.' +des = 'Macro to get help about SAS package, version 20251221. Run %helpPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -567,7 +568,7 @@ des = 'Macro to get help about SAS package, version 20251126. Run %helpPackage() %put ### This is short help information for the `helpPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to get help about SAS packages, version `20251126` #; + %put # Macro to get help about SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -710,7 +711,7 @@ TODO: */ /*+installPackage+*/ -/* Macros to install SAS packages, version 20251126 */ +/* Macros to install SAS packages, version 20251221 */ /* A SAS package is a zip file containing a group of files with SAS code (macros, functions, data steps generating data, etc.) wrapped up together and %INCLUDEed by @@ -737,7 +738,7 @@ TODO: /secure minoperator /*** HELP END ***/ -des = 'Macro to install SAS package, version 20251126. Run %%installPackage() for help info.' +des = 'Macro to install SAS package, version 20251221. Run %%installPackage() for help info.' ; %if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then %do; @@ -752,7 +753,7 @@ des = 'Macro to install SAS package, version 20251126. Run %%installPackage() fo %put ### This is short help information for the `installPackage` macro #; %put #--------------------------------------------------------------------------------------------#;; %put # #; - %put # Macro to install SAS packages, version `20251126` #; + %put # Macro to install SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -1404,7 +1405,7 @@ des = 'Macro to install SAS package, version 20251126. Run %%installPackage() fo Macro to list SAS packages in packages folder. - Version 20251126 + Version 20251221 A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -1424,7 +1425,7 @@ des = 'Macro to install SAS package, version 20251126. Run %%installPackage() fo %macro listPackages() /secure PARMBUFF -des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20251126.' +des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HELP) for help, version 20251221.' ; %if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then %do; @@ -1439,7 +1440,7 @@ des = 'Macro to list SAS packages from `packages` fileref, type %listPackages(HE %put ### This is short help information for the `listPackages` macro #; %put #-----------------------------------------------------------------------------------------#;; %put # #; - %put # Macro to list available SAS packages, version `20251126` #; + %put # Macro to list available SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -1591,7 +1592,7 @@ options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.; Macro to generate SAS packages. - Version 20251126 + Version 20251221 A SAS package is a zip file containing a group of SAS codes (macros, functions, data steps generating @@ -1637,7 +1638,7 @@ options ls = &ls_tmp. ps = &ps_tmp. ¬es_tmp. &source_tmp.; file name be created */ )/ secure minoperator /*** HELP END ***/ -des = 'Macro to generate SAS packages, version 20251126. Run %generatePackage() for help info.' +des = 'Macro to generate SAS packages, version 20251221. Run %generatePackage() for help info.' ; %if (%superq(filesLocation) = ) OR (%qupcase(&filesLocation.) = HELP) %then %do; @@ -1652,7 +1653,7 @@ des = 'Macro to generate SAS packages, version 20251126. Run %generatePackage() %put ### This is short help information for the `generatePackage` macro #; %put #------------------------------------------------------------------------------------#; %put # #; - %put # Macro to generate SAS packages, version `20251126` #; + %put # Macro to generate SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -2479,7 +2480,7 @@ title6 "MD5 hashed fileref of package lowcase name: &_PackageFileref_."; title8 "Required SAS packages: %qsysfunc(compress(%superq(packageReqPackages),%str(%'%")))" ; /* " */ %end; -footnote1 "SAS Packages Framework, version 20251126"; +footnote1 "SAS Packages Framework, version 20251221"; proc print data = &filesWithCodes.(drop=base folderRef fileRef rc folderid _abort_ fileId additionalContent) @@ -3303,7 +3304,7 @@ data _null_; %end; put +(-1) '`.;''' / ' !! '' %put The macro generated: '' !! put(dtCASLudf, E8601DT19.-L) !! ";"' / - ' !! '' %put with the SAS Packages Framework version 20251126.;''' / + ' !! '' %put with the SAS Packages Framework version 20251221.;''' / ' !! '' %put ****************************************************************************;''' / ' !! '' %GOTO theEndOfTheMacro;''' / ' !! '' %end;''' ; @@ -3468,7 +3469,7 @@ data _null_; %end; put +(-1) '`.; '' !!' / ''' %put The macro generated: ''' " !! put(dtIML, E8601DT19.-L) !! " '''; '' !!' / - ''' %put with the SAS Packages Framework version 20251126.; '' !! ' / + ''' %put with the SAS Packages Framework version 20251221.; '' !! ' / ''' %put ****************************************************************************; '' !! ' / ''' %GOTO theEndOfTheMacro; '' !! ' / ''' %end; '' !! ' / @@ -4275,7 +4276,7 @@ data _null_; %end; put 'put " " / @3 "---------------------------------------------------------------------" / " ";' - / 'put @3 "*SAS package generated by SAS Package Framework, version `20251126`*";' + / 'put @3 "*SAS package generated by SAS Package Framework, version `20251221`*";' / "put @3 '*under `&sysscp.`(`&sysscpl.`) operating system,*';" / "put @3 '*using SAS release: `&sysvlong4.`.*';" / 'put " " / @3 "---------------------------------------------------------------------";'; @@ -5391,7 +5392,7 @@ data &filesWithCodes.markdown; %end; put " " / "---------------------------------------------------------------------" / " " - / "*SAS package generated by SAS Package Framework, version `20251126`,*" + / "*SAS package generated by SAS Package Framework, version `20251221`,*" / "*under `&sysscp.`(`&sysscpl.`) operating system,*" / "*using SAS release: `&sysvlong4.`.*" / " " / "---------------------------------------------------------------------" / " "; @@ -5679,7 +5680,7 @@ TODO: (in Polish) */ )/secure /*** HELP END ***/ -des = 'Macro to load multiple SAS packages at one run, version 20251126. Run %loadPackages() for help info.' +des = 'Macro to load multiple SAS packages at one run, version 20251221. Run %loadPackages() for help info.' parmbuff ; %if (%superq(packagesNames) = ) OR (%qupcase(&packagesNames.) = HELP) %then @@ -5695,7 +5696,7 @@ parmbuff %put ### This is short help information for the `loadPackageS` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro wrapper for the loadPackage macro, version `20251126` #; + %put # Macro wrapper for the loadPackage macro, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -5793,7 +5794,7 @@ parmbuff hashing_file() function, SAS 9.4M6 */ )/secure /*** HELP END ***/ -des = 'Macro to verify SAS package with the hash digest, version 20251126. Run %verifyPackage() for help info.' +des = 'Macro to verify SAS package with the hash digest, version 20251221. Run %verifyPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -5808,7 +5809,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20251126. Run % %put ### This is short help information for the `verifyPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to verify SAS package with it hash digest, version `20251126` #; + %put # Macro to verify SAS package with it hash digest, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -5990,7 +5991,7 @@ des = 'Macro to verify SAS package with the hash digest, version 20251126. Run % */ )/secure /*** HELP END ***/ -des = 'Macro to preview content of a SAS package, version 20251126. Run %previewPackage() for help info.' +des = 'Macro to preview content of a SAS package, version 20251221. Run %previewPackage() for help info.' ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then %do; @@ -6005,7 +6006,7 @@ des = 'Macro to preview content of a SAS package, version 20251126. Run %preview %put ### This is short help information for the `previewPackage` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to get preview of a SAS packages, version `20251126` #; + %put # Macro to get preview of a SAS packages, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -6137,7 +6138,7 @@ des = 'Macro to preview content of a SAS package, version 20251126. Run %preview when empty the "packages" value is used */ )/secure /*** HELP END ***/ -des = 'Macro to list directories pointed by "packages" fileref, version 20251126. Run %extendPackagesFileref(HELP) for help info.' +des = 'Macro to list directories pointed by "packages" fileref, version 20251221. Run %extendPackagesFileref(HELP) for help info.' ; %if %QUPCASE(&packages.) = HELP %then @@ -6153,7 +6154,7 @@ des = 'Macro to list directories pointed by "packages" fileref, version 20251126 %put ### This is short help information for the `extendPackagesFileref` macro #; %put #-----------------------------------------------------------------------------------------#;; %put # #; - %put # Macro to list directories pointed by 'packages' fileref, version `20251126` #; + %put # Macro to list directories pointed by 'packages' fileref, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -6255,7 +6256,7 @@ filename packages list; is provided in required version */ )/secure /*** HELP END ***/ -des = 'Macro to load additional content for a SAS package, version 20251126. Run %loadPackageAddCnt() for help info.' +des = 'Macro to load additional content for a SAS package, version 20251221. Run %loadPackageAddCnt() for help info.' minoperator ; %if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then @@ -6271,7 +6272,7 @@ minoperator %put ### This is short help information for the `loadPackageAddCnt` macro #; %put #-------------------------------------------------------------------------------#; %put # #; - %put # Macro to *load* additional content for a SAS package, version `20251126` #; + %put # Macro to *load* additional content for a SAS package, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -6524,7 +6525,7 @@ minoperator run; data _null_; - set WORK.__&_TargetFileref_._zip___ end = EOF; + set WORK.__&_TargetFileref_._zip___ end = EOF; wc = countw(file,"/\"); put wc= file=; @@ -6639,10 +6640,9 @@ minoperator ,debug=0 /* technical parameter */ ,nobs=0 /* technical parameter */ ) -/*** HELP START ***/ -/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20251126. Run %splitCodeForPackage() for help info.' +/*** HELP END ***/ +/ des = 'Utility macro to split "one big" code into multiple files for a SAS package, version 20251221. Run %splitCodeForPackage() for help info.' ; -/*%macro _();%mend _;*/ %if (%superq(codeFile) = ) OR (%qupcase(&codeFile.) = HELP) %then %do; %local options_tmp ; @@ -6657,7 +6657,7 @@ minoperator %put #-------------------------------------------------------------------------------#; %put # #; %put # Utility macro to *split* single file with SAS package code into multiple #; - %put # files with separate snippets, version `20251126` #; + %put # files with separate snippets, version `20251221` #; %put # #; %put # A SAS package is a zip file containing a group #; %put # of SAS codes (macros, functions, data steps generating #; @@ -6681,7 +6681,7 @@ minoperator %put # #; %put # - `packagePath=` *Required.* Location for package files after #; %put # splitting into separate files and directories. #; - %put # If missing or not exist then `WORK` is uded. #; + %put # If missing or not exist then `WORK` is used. #; %put # #; %put # - `debug=` *Optional.* Turns on code printing for debugging. #; %put # #; @@ -7033,7 +7033,7 @@ options nomprint nosymbolgen nomlogic notes source ls=MAX ps=MAX msglevel=N ; */ if firstLine[j] then do; - put '/* File generated with help of SAS Packages Framework, version 20251126. */'; + put '/* File generated with help of SAS Packages Framework, version 20251221. */'; firstLine[j]=0; end; put _infile_; @@ -7049,4 +7049,1000 @@ options &options_tmp2.; %ENDofsplitCodeForPackage: %mend splitCodeForPackage; +/*+relocatePackage+*/ +/*** HELP START ***/ + +%macro relocatePackage( + packageName /* list of packages (space-separated!) */ +,source= /* place to take packages from (local location) */ +,target= /* the "packages" fileref by default */ +,sDevice=DISK /* also: ZIP, FILESRVC (SASFSVAM)*/ +,tDevice=DISK /* also: ZIP, FILESRVC */ +,checksum=0 /* if 1, copies data only if the source (from file) checksum is different than the target (to file) */ +,move=0 /* packages are copied by default */ +,try=3 /* integer between 1 and 9 */ +,debug=0 /* debugging indicator */ +,ignorePackagesFilerefCheck=0 +) +/ des = 'Utility macro that locally Copies or Moves Packages, version 20251221. Run %relocatePackage() for help info.' + secure + minoperator +; +/*** HELP END ***/ +%if (%superq(packageName) = ) OR (%qupcase(&packageName.) = HELP) %then + %do; + %local options_tmp ; + %let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps)) + %sysfunc(getoption(notes)) %sysfunc(getoption(source)) + msglevel=%sysfunc(getoption(msglevel)) + ; + options NOnotes NOsource ls=MAX ps=MAX msglevel=N; + %put ; + %put #################################################################################; + %put ### This is short help information for the `relocatePackage` macro #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Macro to *locally copy or move* (relocate) SAS packages, version `20251221` #; + %put # #; + %put # A SAS package is a zip file containing a group #; + %put # of SAS codes (macros, functions, data steps generating #; + %put # data, etc.) wrapped up together and included by #; + %put # a single `load.sas` file (also embedded inside the zip). #; + %put # #; + %put # The `%nrstr(%%relocatePackage())` is a utility macro for local copying or moving #; + %put # SAS packages. The macro transfers packages located in the `PACKAGES` #; + %put # fileref to a selected directory (`DISK` device), folderpath (`FILESRVC` #; + %put # device), or a zip file (`ZIP` device). #; + %put # #; + %put # The macro allows for a bidirectional transfer of packages, i.e., from the #; + %put # `PACKAGES` fileref to the selected *target*, or from the selected *source* #; + %put # to the `PACKAGES` fileref. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put #### Parameters: #; + %put # #; + %put # 1. `packageName` *Required.* Name of a package, e.g. myPackage. #; + %put # A space-separated(!) list of packages to transfer is #; + %put # also accepted. If empty displays this help information. #; + %put # #; + %put # - `source=` *Required/Optional.* Source location for packages. #; + %put # When used, indicates a directory (`DISK` device), #; + %put # a folderpath (`FILESRVC` device), or a zip file (`ZIP` #; + %put # device) *from* where packages will be copied. #; + %put # In this case `PACKAGES` fileref is target location. #; + %put # Cannot be used together with `target=` parameter. #; + %put # #; + %put # - `target=` *Required/Optional.* Target location for packages. #; + %put # When used, indicates a directory (`DISK` device), #; + %put # a folderpath (`FILESRVC` device), or a zip file (`ZIP` #; + %put # device) *to* where packages will be copied. #; + %put # In this case `PACKAGES` fileref is source location. #; + %put # Cannot be used together with `source=` parameter. #; + %put # #; + %put # - `sDevice=` *Required/Optional.* When `source=` is used this #; + %put # parameter provides which type of device to be use. #; + %put # Default value is `DISK`, values `ZIP` and `FILESRVC` #; + %put # are allowed. For `FILESRVC` the `folderpath=` is used. #; + %put # #; + %put # - `tDevice=` *Required/Optional.* When `target=` is used this #; + %put # parameter provides which type of device to be use. #; + %put # Default value is `DISK`, values `ZIP` and `FILESRVC` #; + %put # are allowed. For `FILESRVC` the `folderpath=` is used. #; + %put # #; + %put # - `checksum=` *Optional.* Indicates if packages should be copied only #; + %put # if the source (from file) checksum is different than #; + %put # the target (to file). Default value is 0 (always copy). #; + %put # #; + %put # - `move=` *Optional.* Indicates if packages should be moved from #; + %put # source to target, default value is `0`, #; + %put # when set to `1`: after *successful* copying packages #; + %put # in the source are *deleted*. Use carefully! #; + %put # #; + %put # - `debug=` *Optional.* Indicates if debug notes should be printed, #; + %put # default value is `0`, when set to `1`: debug info #; + %put # is printed. #; + %put # #; + %put # - `try=` *Optional.* Number of tries when copy is unsuccessful, #; + %put # default value is `3`, allowed values are integers #; + %put # from 1 to 9. Time between tries is quarter of a second. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #; + %put # to learn more. #; + %put # Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` #; + %put # #; + %put ### Example 1 ###################################################################; + %put # #; + %put # Enabling the SAS Package Framework from the local #; + %put # directory, copying SQLinDS package from Viya Files #; + %put # service, and loading the package to the SAS session. #; + %put # #; + %put # Assume that the `SPFinit.sas` file is located in the "/home/user/PCKG" #; + %put # directory and Viya Files service location is "/files/packages/" #; + %put # #; + %put # Run the following code in your SAS session: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( filename packages "/home/user/PCKG"; %%* setup a directory for packages; ); + %put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; ); + %put ; + %put %nrstr( %%relocatePackage%(SQLinDS %%* copy the package from Viya Files service; ); + %put %nrstr( ,source=/files/packages/ ); + %put %nrstr( ,sDevice=FILESRVC%) ); + %put %nrstr( %%loadPackage(SQLinDS) %%* load the package content into the SAS session; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put ### Example 2 ###################################################################; + %put # #; + %put # Enabling the SAS Package Framework from the local directory #; + %put # and creating a "bundle" file by moving 3 packages: the BasePlus, #; + %put # the SQLinDS, and the MacroArray package into the target file. #; + %put # #; + %put # Assume that the `SPFinit.sas` file #; + %put # is located in the "C:/SAS_PACKAGES/" folder. #; + %put # #; + %put # Run the following code in your SAS session: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( filename packages "C:/SAS_PACKAGES"; %%* setup a directory for packages; ); + %put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework; ); + %put ; + %put %nrstr( %%relocatePackage%(BasePlus SQLinDS MacroArray %%* create a bundle of packages;); + %put %nrstr( ,target=D:/archive/bundle_2025_12_15.zip ); + %put %nrstr( ,tDevice=ZIP, move=1%) ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put #################################################################################; + %put ; + options &options_tmp.; + %GOTO ENDofrelocatePackage; + %end; + /* local variables for options */ + %local ls_tmp ps_tmp notes_tmp source_tmp stimer_tmp fullstimer_tmp msglevel_tmp mautocomploc_tmp; + %let ls_tmp = %sysfunc(getoption(ls)); + %let ps_tmp = %sysfunc(getoption(ps)); + %let notes_tmp = %sysfunc(getoption(notes)); + %let source_tmp = %sysfunc(getoption(source)); + %let stimer_tmp = %sysfunc(getoption(stimer)); + %let fullstimer_tmp = %sysfunc(getoption(fullstimer)); + %let msglevel_tmp = %sysfunc(getoption(msglevel)); + %let mautocomploc_tmp = %sysfunc(getoption(mautocomploc)); + + options NOnotes NOsource ls=MAX ps=MAX NOfullstimer NOstimer msglevel=N NOmautocomploc; + + %if NOT(%superq(debug) in (0 1)) %then %let debug=0; + %if NOT(%superq(move) in (0 1)) %then %let move=0; + %if NOT(%superq(try) in (1 2 3 4 5 6 7 8 9)) %then %let try=3; + %if NOT(%superq(checksum) in (0 1)) %then %let checksum=0; + %if NOT(%superq(ignorePackagesFilerefCheck) in (0 1)) %then %let ignorePackagesFilerefCheck=0; + + options nonotes msglevel=N; + + %local HASHING_FILE_exist; + %let HASHING_FILE_exist = 0; + + %if %sysfunc(exist(sashelp.vfunc, VIEW)) %then + %do; + data _null_; + set sashelp.vfunc(keep=fncname); + where fncname = "HASHING_FILE"; + call symputX('HASHING_FILE_exist', 1, "L"); + stop; + run; + %end; + %if &checksum. AND NOT &HASHING_FILE_exist. %then + %do; + %put WARNING: Checksum verification impossible! Minimum SAS version required for the process is 9.4M6. ; + %end; + + data _null_; + putlog 32*"*" 24*"=" 32*"*"; + length packages source target $ 32767 sDevice tDevice $ 32; + packages = lowcase(compress(symget('packageName'),"_ ","KAD")); + + if " " = packages then + do; + putlog "INFO: No packages to move or copy. Exiting."; + LINK stopProcessing; + end; + else putlog "INFO: List of packages: " packages; + + debug = sum(symgetn('debug'),0); + + /* grab macro variables values */ + array mvar source target sDevice tDevice; + do over mvar; + mvar=symget(vname(mvar)); + end; + + if source NE ' ' AND target NE " " then + do; + putlog "WARNING: The SOURCE= and the TARGET= parameters cannot be used simultaneously. Exiting!"; + LINK stopProcessing; + end; + + if source EQ ' ' AND target EQ " " then + do; + putlog "INFO: The SOURCE= and the TARGET= parameters were not used, nothing to do. Exiting!"; + LINK stopProcessing; + end; + + /* verify that PACKAGES is valid location for source or target */ + /*=========================================================================================================*/ + %if 0 = &ignorePackagesFilerefCheck. %then + %do; + if NOT (input(resolve('%isPackagesFilerefOK(&debug.)'), best.)=1) then /* if debug=1 the isPackagesFilerefOK in verbose mode */ + do; + putlog "WARNING: The PACKAGES fileres is not OK! Exiting!"; + LINK stopProcessing; + end; + %end; + /*=========================================================================================================*/ + + /* prepare source and target */ + /*=========================================================================================================*/ + %local i ST_list st stDev stFr stH stI stEx stAsg leave; + %let ST_list=target source; /* repeat the same structure twice with different prefix */ + %do i=1 %to 2; + %let st=%scan(&ST_list., &i.); + %let stDev=%substr(&st.,1,1)Device; + %let stFr =%substr(&st.,1,1)FileRef; + %let stH =%substr(&st.,1,1)Hash; + %let stI =%substr(&st.,1,1)Iter; + %let stEx =%substr(&st.,1,1)Exists; + %let stAsg=%substr(&st.,1,1)Assigned; + %let stFp =%substr(&st.,1,1)FromPackages; + + retain &stFp. 0 move 0; + move = sum(symgetn('move'),0); + /* validate source and target */ + &stDev. = upcase(compress(&stDev.,"_","KAD")); + if NOT (&stDev. in ("DISK" "BASE" "ZIP" "FILESRVC" "SASFSVAM")) then + do; + putlog "WARNING: The &stDev. parameter value: " &stDev. "is not allowed." + / "WARNING- Only: DISK, ZIP, and FILESRVC devices are supported as &st. device. Exiting!"; + LINK stopProcessing; + end; + + if &st.=" " then + do; + if 0 then set SASHELP.VEXTFL; + DECLARE HASH &stH.(dataset:'SASHELP.VEXTFL(where=(fileref="PACKAGES"))', ordered: "A"); + &stH..DefineKey("level"); + &stH..DefineData("xpath","xengine"); + &stH..DefineDone(); + DECLARE HITER &stI.("&stH."); + + if &stH..NUM_ITEMS=0 then + do; + putlog "INFO: Packages fileref not found. Using WORK instead."; + level = 0; + xpath = pathname("WORK","L"); + xengine = 'DISK'; + &stI..REPLACE(); + end; + + &stI..FIRST(); + &st. = strip(xpath); /* get the first packages path */ + &stDev. = strip(xengine); + + /* Just to make it easier to debug since FILESRVC will show up in Google */ + if &stDev. = 'SASFSVAM' then _stDev_ = 'FILESRVC'; + else _stDev_ = strip(xengine); + putlog "INFO: The &st. location is: " / @7 _stDev_ +(-1) ": " &st.; + %if &st.=source %then + %do; + do while(&stI..next()=0); + if xengine = 'SASFSVAM' then _engine_ = 'FILESRVC'; + else _engine_ = xengine; + putlog @7 _engine_ +(-1) ": " xpath; + end; + %end; + &stFp. = 1; + end; + else + do; + length &stFr. $ 8; + + if " "=getoption("SERVICESBASEURL") AND (&stDev. in ("FILESRVC" "SASFSVAM")) then + do; + putlog "WARNING: The SERVICESBASEURL option must be specified for the FILESRVC device. Exiting!"; + LINK stopProcessing; + end; + + length &stAsg.Txt &stEx.Txt $ 256; + + + if (&stDev. in ("FILESRVC" "SASFSVAM")) then + &stAsg. = filename(&stFr., ,strip(&stDev.), "recfm=n lrecl=1 " !! "folderpath=" !! quote(strip(&st.))); /* assign FILESRVC */ + else + &stAsg. = filename(&stFr.,strip(&st.), strip(&stDev.), "recfm=n lrecl=1"); /* assign DISK or ZIP*/ + &stAsg.Txt = sysmsg(); + + &stEx. = FEXIST(&stFr.); + &stEx.Txt = sysmsg(); + + if debug then putlog (&stFr. &st. &stDev. &stAsg. &stAsg.Txt &stEx. &stEx.Txt) (=/); + _rc_ = filename(&stFr.); /*clear*/ + end; + %end; + /*=========================================================================================================*/ + + if source=target and sDevice=tDevice then + do; + putlog / "INFO: Nothing to move or copy. Exiting."; + LINK stopProcessing; + end; + + if move then + do; + putlog / "INFO: Files will be moved, i.e., after successful copying to the target location" + / " the source will be deleted."; + end; + + /* 4096 for host options for Viya FS */ + length sHostoptions tHostOptions $ 4096 tFilename sFilename $ 2048; + + do i = 1 to countw(packages, " "); + package = scan(packages, i, " "); + + putlog 32*"*" package $24.-C 32*"*"; + + select; + /* copy from PACKAGES to some location */ + /*=========================================================================================================*/ + when(1=sFromPackages AND 0=tFromPackages AND 0=tAssigned) + do; + select; + /* disk */ + when (tDevice in ("DISK" "BASE")) + do; + if NOT tExists then GOTO stopForThisPackage1; + tAssigned = filename(tFileRef + ,cats(target, "/", package, ".zip") + ,strip(tDevice) + ,"recfm=n lrecl=1"); + end; + /* zip */ + when (tDevice in ("ZIP")) + do; + if tExists then putlog "INFO: Overwriting member: " package +(-1) ".zip inside: " target; + tAssigned = filename(tFileRef + ,cats(target) + ,strip(tDevice) + ,"recfm=n lrecl=1 member=" !! quote(cats(package, ".zip")) ); + end; + /* filesrvc */ + when (tDevice in ("FILESRVC" "SASFSVAM")) + do; + tAssigned = filename(tFileRef + ,/*blank*/ ,strip(tDevice) + ,"recfm=n lrecl=1" + !! " folderpath=" !! quote(cats(target)) + !! " filename=" !! quote(cats(package, ".zip")) + ); + end; + /* other */ + otherwise + do; + putlog "ERROR: Unsupported device: " tDevice +(-1) ". Exiting!"; + GOTO stopForThisPackage1; + end; + end; + + if debug then putlog tAssigned= tFileRef= / tDevice=; + + _rc_ = sIter.first(); + _rc_ = sIter.prev(); + do while(sIter.next()=0); + + /* If Viya File Service, we need to use: + filename('fileref', ,'FILEFSVAM', "") */ + if xengine = 'SASFSVAM' then do; + sFilename = ' '; + sHostOptions = "recfm=n lrecl=1" + !! " folderpath=" !! quote(strip(xpath)) + !! " filename=" !! quote(cats(package, ".zip")) + ; + end; + else do; + sFilename = cats(strip(xpath), "/", package, ".zip"); + sHostOptions = "recfm=n lrecl=1"; + end; + + sAssigned = filename(sFileref + ,sFilename + ,xengine + ,sHostOptions); + + if debug then putlog sAssigned= sFileRef= / xengine=; + leave=0; + LINK LoopTryCopyFile; /* LINK 1 */ + if leave then leave; + end; + sAssigned = filename(sFileRef); + tAssigned = filename(tFileRef); + + stopForThisPackage1: + if 0=leave then putlog "ERROR: Fail to process " package; + end; + /*=========================================================================================================*/ + + /* copy from some location to PACKAGES */ + /*=========================================================================================================*/ + when(0=sFromPackages AND 1=tFromPackages AND 0=sAssigned) + do; + select; + /* disk */ + when (sDevice in ("DISK" "BASE")) + do; + if NOT sExists then GOTO stopForThisPackage2; + sAssigned = filename(sFileRef + ,cats(source, "/", package, ".zip") + ,strip(sDevice) + ,"recfm=n lrecl=1"); + end; + /* zip */ + when (sDevice in ("ZIP")) + do; + sAssigned = filename(sFileRef + ,cats(source) + ,strip(sDevice) + ,"recfm=n lrecl=1 member=" !! quote(cats(package, ".zip")) ); + end; + /* filesrvc */ + when (sDevice in ("FILESRVC" "SASFSVAM")) + do; + sAssigned = filename(sFileRef + ,/*blank*/ ,strip(sDevice) + ,"recfm=n lrecl=1" + !! " folderpath=" !! quote(cats(source)) + !! " filename=" !! quote(cats(package, ".zip")) + ); + end; + /* other */ + otherwise + do; + putlog "ERROR: Unsupported device: " sDevice +(-1) ". Exiting!"; + GOTO stopForThisPackage2; + end; + end; + + if debug then putlog sAssigned= sFileRef= / sDevice=; + + if NOT fexist(sFileRef) then + do; + putlog "WARNING: File: " package +(-1) ".zip does NOT exist inside: " source; + end; + else + do; + _rc_ = tIter.first(); + _rc_ = tIter.prev(); + do while(tIter.next()=0); + + /* If Viya File Service, we need to use: + filename('fileref', ,'FILEFSVAM', "") */ + if xengine = 'SASFSVAM' then do; + tFilename = ' '; + tHostOptions = "recfm=n lrecl=1" + !! " folderpath=" !! quote(strip(xpath)) + !! " filename=" !! quote(cats(package, ".zip")) + ; + end; + else do; + tFilename = cats(strip(xpath), "/", package, ".zip"); + tHostOptions = "recfm=n lrecl=1"; + end; + + tAssigned = filename(tFileRef + ,tFilename + ,xengine + ,tHostOptions); + + if debug then putlog tAssigned= tFileRef= / xengine=; + leave=0; + LINK LoopTryCopyFile; /* LINK 1 */ + if leave then leave; + end; + tAssigned = filename(tFileRef); + end; + + sAssigned = filename(sFileRef); + stopForThisPackage2: + if 0=leave then putlog "ERROR: Fail to process " package; + end; + /*=========================================================================================================*/ + /** + when(0) do; put "future cases"; end; + **/ + otherwise putlog "WARNING: Unknown combination."; + end; + end; + + LINK stopProcessing; + /** the end **/ + STOP; + + /* LINK 1 */ + loopTryCopyFile: + do try = 1 to &try. while(leave=0); + + length s_HASHING t_HASHING $ 128; + + %if &checksum. AND &HASHING_FILE_exist. %then + %do; + if try = 1 AND fexist(tFileRef) then /* check SHA256 only for first try */ + do; + LINK GETSHA256DIGEST; /* LINK 2 */ + + if s_HASHING=t_HASHING then + do; + putlog "INFO: The SHA256 hash digest for source and target are identical." + / @7 "Checksum: " t_HASHING + / @7 "Package will not be copied."; + _rc_ = 0; + end; + else + do; /* message only for the first time */ + putlog "INFO: The SHA256 hash digest for source and target are different." + / @7 "Target checksum: " t_HASHING + / @7 "Source checksum: " s_HASHING + / @7 "Copying package."; + _rc_ = fcopy(sFileRef, tFileRef); + _rcTxt_ = sysmsg(); + end; + end; + else /* keep this ELSE unclosed for... */ + %end; + + do; /* ... this DO-END block */ + _rc_ = fcopy(sFileRef, tFileRef); + _rcTxt_ = sysmsg(); + end; + + if debug then putlog _rc_= / _rcTxt_=; + leave + (_rc_=0)*fexist(tFileRef); + + %if &HASHING_FILE_exist. = 1 %then + %do; + if leave then /* compare SHA256 after copy */ + do; + LINK GETSHA256DIGEST; /* LINK 2 */ + + if NOT (s_HASHING=t_HASHING) then + putlog "WARNING: The SHA256 hash digest is different for source and target!" + / "WARNING- Source is: " s_HASHING + / "WARNING- Target is: " t_HASHING + / "WARNING- There could be errors during copying. Check your files."; + end; + %end; + + if (leave AND move) then + do; + _rc_ = fdelete(sFileRef); + if _rc_ then putlog "WARNING: Target successfully copied, but cannot delete source file while moving."; + end; + if not leave then _rc_ = sleep(1,0.25); + end; + return; + + /* LINK 2 */ + GETSHA256DIGEST: + %let ST_list=t s; /* for source(s) and for target(t), repeat the same structure twice with different prefix */ + %do i=1 %to 2; + %let st=%scan(&ST_list., &i.); + select; + when (&st.Device in ("ZIP")) &st._HASHING=HASHING_FILE("SHA256", &st.FileRef, 4); + when (&st.Device in ("DISK" "BASE")) &st._HASHING=HASHING_FILE("SHA256", pathname(&st.FileRef,'F'), 0); + otherwise /* for FILESRVC and SASFSVAM*/ + do; + &st._sha256 = hashing_init("SHA256"); + &st._FID = fopen(&st.FileRef, "i", 1, "B"); /* read only in binary format */ + if &st._FID then do while(fread(&st._FID)=0); + length &st.c $ 1; + _rc_ = fget(&st._FID, &st.c, 1); + _rc_ = hashing_part(&st._sha256, &st.c); + end; + &st._FID = fclose(&st._FID); + &st._HASHING = hashing_term(&st._sha256); + end; + end; + %end; + return; + + /* LINK 3 */ + stopProcessing: + putlog 32*"*" 24*"=" 32*"*"; + stop; + return; + + run; + + /* restore optionos */ + options ls = &ls_tmp. ps = &ps_tmp. + ¬es_tmp. &source_tmp. + &stimer_tmp. &fullstimer_tmp. + msglevel=&msglevel_tmp. &mautocomploc_tmp.; + +%ENDofrelocatePackage: +%mend relocatePackage; + +/* tests on Viya: + +filename PACKAGES list; + +%let user= <...>; + +filename backup filesrvc + folderpath="/Users/&user./My Folder/SASPACKAGES"; +filename backup list; + +%put %sysfunc(pathname(backup)); + +data _null_; + x=getoption("SERVICESBASEURL"); + put x=; +run; + +options ls = 90; +%* move from PACKAGES to a FILESRVC location*; +%relocatePackage(baseplus SQLinDS macroarray +,target=/Users/&user./My Folder/SASPACKAGES +,tDevice=FILESRVC +,move=1) + +%* move back to PACKAGES from a FILESRVC location*; +%relocatePackage(baseplus SQLinDS macroarray +,source=/Users/&user./My Folder/SASPACKAGES +,sDevice=FILESRVC +,move=1) + +%* create a ZIP bundle with packages in HOME *; +%relocatePackage(baseplus SQLinDS macroarray +,target=~/SASPACKAGESbundle.zip +,tDevice=ZIP) +*/ +/* SERVICESBASEURL */ + +/* Tests on SAS: + +options mprint msglevel=N; + +filename PACKAGES ("R:\" "C:\SAS_WORK\SAS_PACKAGES"); + +%relocatePackage(myPackage) + +options nomprint msglevel=N; +%relocatePackage(baseplus SQLinDS macroarray, target=R:\abc, debug=1) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\noDir) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\bundle.zip, tDevice=zip) +%relocatePackage(baseplus SQLinDS macroarray, target=R:\, tDevice=FILESRVC) + +filename PACKAGES ("R:\testPackages1_NOT_EXIST" "R:\testPackages2_NOT_EXIST"); +%relocatePackage(baseplus SQLinDS macroarray abc, source=R:\abc, debug=1, move=1) + +filename PACKAGES ("R:\testPackages1" "R:\testPackages2"); +%relocatePackage(baseplus SQLinDS macroarray abc, source=R:\abc, debug=1, move=1) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\noDir, debug=1) + +filename PACKAGES ("R:\testPackages2" "R:\testPackages1"); +%relocatePackage(baseplus SQLinDS macroarray, source=R:\bundle.zip, sDevice=zip, move=1) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\, sDevice=FILESRVC) +%relocatePackage(baseplus SQLinDS macroarray, source=R:\bundle.zip, sDevice=zip, target=R:\bundle) +*/ +/*%macro _();%mend _;*/ /**/ + +/*+isPackagesFilerefOK+*/ +/*** HELP START ***/ +%macro isPackagesFilerefOK( +vERRb /* indicates if macro should be verbose and report errors */ +) +/ minoperator PARMBUFF +des = 'Macro to check if the PACKAGES fileref is "correct", type %isPackagesFilerefOK(HELP) for help, version 20251221.' +; +/*** HELP END ***/ +%if %QUPCASE(&SYSPBUFF.) = %str(%(HELP%)) %then + %do; + %local options_tmp ; + %let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps)) + %sysfunc(getoption(notes)) %sysfunc(getoption(source)) + msglevel=%sysfunc(getoption(msglevel)) + ; + options NOnotes NOsource ls=MAX ps=MAX msglevel=N; + %put ; + %put ###########################################################################################; + %put ### This is short help information for the `isPackagesFilerefOK` macro #; + %put #-----------------------------------------------------------------------------------------#;; + %put # #; + %put # Macro to check if the `packages` fileref is "correct", version `20251221` #; + %put # #; + %put # A SAS package is a zip file containing a group #; + %put # of SAS codes (macros, functions, data steps generating #; + %put # data, etc.) wrapped up together and embedded inside the zip. #; + %put # #; + %put # The `%nrstr(%%isPackagesFilerefOK())` macro checks if the `packages` fileref #; + %put # is correct, i.e. all listed directories exist, are accessible (can be open), and #; + %put # are assigned with the DISK device. #; + %put # #; + %put # The Macro works as a macro function. It returns `1` wher everything is ok, and #; + %put # it returns `0` if at least one issue exists. #; + %put # #; + %put #### Parameters: #; + %put # #; + %put # 1. `vERRb` - *Optional* Indicates if the macro should return value AND be verbose #; + %put # (e.g., print errors and notes) or just return value. #; + %put # #; + %put # When used as: `%nrstr(%%isPackagesFilerefOK(HELP))` it displays this help information. #; + %put # #; + %put #-----------------------------------------------------------------------------------------#; + %put # #; + %put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #; + %put # to learn more. #; + %put # Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` #; + %put # #; + %put #### Example ##############################################################################; + %put # #; + %put # Enabling the SAS Package Framework from the local #; + %put # directory, expanding PACKAGES fileref, and checking #; + %put # if the new one is still correct for installing new package. #; + %put # #; + %put # Assume that the `SPFinit.sas` file #; + %put # is located in the "/sas/PACKAGES/" directory. #; + %put # #; + %put # Run the following code in your SAS session: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( filename packages "/sas/PACKAGES"; %%* set packages filename;); + %put %nrstr( %%include packages(SPFinit.sas); %%* enable the framework;); + %put ; + %put %nrstr( filename packages ("~/myPCKGs" %%extendPackagesFileref()); %%* add new directory; ); + %put ; + %put %nrstr( %if %%IsPackagesFilerefOK() %%then %%* check fileref; ); + %put %nrstr( %%do; %%InstallPackage(SQLinDS) %%end; %%* install SQLinDS; ); + %put ; + %put %nrstr( %%listPackages() %%* list packages; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put ###########################################################################################; + %put ; + options &options_tmp.; + %GOTO ENDofIsPackagesFilerefOK; + %end; + +%if NOT (%superq(vERRb) in (0 1)) %then %let vERRb = 0; + +%local isPackagesFilerefOK; +%let isPackagesFilerefOK=1; + +%local dsid rc nobs i XENGINE XPATH dirid _F_; +%let dsid = %sysfunc(OPEN(sashelp.vextfl(where=(fileref="PACKAGES")))); +%let nobs = %sysfunc(ATTRN(&dsid., nlobsf)); +/*%put &=dsid. &=nobs.;*/ + +%if &nobs. AND 1=&vERRb. %then %put INFO: PACKAGES fileref is: %sysfunc(pathname(PACKAGES)); + +%let isPackagesFilerefOK=%sysevalf(&nobs. AND 1, boolean); + +%do i = 1 %to &nobs.; + %let rc=%sysfunc(FETCHOBS(&dsid., &i.)); + %let XENGINE=%sysfunc(GETVARC(&dsid., %sysfunc(VARNUM(&dsid., XENGINE)))); + %let XPATH=%sysfunc(GETVARC(&dsid., %sysfunc(VARNUM(&dsid., XPATH)))); + + %put %superq(XENGINE) %superq(XPATH); + %if DISK ne %superq(XENGINE) %then + %do; + %let isPackagesFilerefOK=0; + %if 1=&vERRb. %then + %do; + %if %superq(XENGINE) = SASFSVAM %then %let XENGINE= FILESRVC (SASFSVAM); + %put ERROR: The %superq(XENGINE) is illegal! Only the DISK device is correct.; + %end; + %end; + %else %if 0=%sysfunc(fileexist(%superq(XPATH))) %then + %do; + %let isPackagesFilerefOK=0; + %if 1=&vERRb. %then + %do; + %put ERROR: Path: %superq(XPATH) does NOT exist!; + %end; + %end; + %else + %do; + %let rc = %sysfunc(FILENAME(_F_, %superq(XPATH))); + %let dirid = %sysfunc(DOPEN(&_F_.)); + %let isPackagesFilerefOK=%sysevalf(&dirid. AND 1, boolean); + %let dirid = %sysfunc(DCLOSE(&dirid.)); + %let rc = %sysfunc(FILENAME(_F_)); + %if 1=&vERRb. AND 0=&isPackagesFilerefOK. %then + %do; + %put ERROR: Path: %superq(XPATH) cannot be open!; + %put ERROR- It may not be a directory or your access rights are insuficient.; + %end; + %end; +%end; + +%let dsid = %sysfunc(CLOSE(&dsid.)); + +%if 1=&vERRb. %then + %do; + %if &isPackagesFilerefOK.=1 %then + %do; + %put %str( ); + %put INFO: The PACKAGES fileref is OK. Enjoy!; + %put %str( ); + %end; + %else + %do; + %put %str( ); + %put ERROR: The PACKAGES fileref is incorrect!; + %put %str( ); + %end; + %end; +/* result */ +%do;&isPackagesFilerefOK.%return;%end; +%ENDofIsPackagesFilerefOK: +%mend isPackagesFilerefOK; + +/*+SasPackagesFrameworkNotes+*/ +%macro SasPackagesFrameworkNotes( +SPFmacroName /* space separated list of names */ +) +/ +minoperator +secure +des = 'Macro to provide help notes about SAS Packages Framework macros, version 20251221. Run %SasPackagesFrameworkNotes(HELP) for help info.' +; +%local list N i element; +%let list= +installPackage +listPackages +/**/ +verifyPackage +previewPackage +helpPackage +/**/ +loadPackage +loadPackageS +loadPackageAddCnt +/**/ +unloadPackage +/**/ +generatePackage +splitCodeForPackage +/**/ +extendPackagesFileref +relocatePackage +isPackagesFilerefOK +/**/ +SasPackagesFrameworkNotes +; +%let N = %sysfunc(countw(&list.)); + +%let SPFmacroName = %sysfunc(compress(%superq(SPFmacroName),_ *,KAD)); + +%if (%qupcase(&SPFmacroName.) = HELP) %then + %do; + %local options_tmp ; + %let options_tmp = ls=%sysfunc(getoption(ls))ps=%sysfunc(getoption(ps)) + %sysfunc(getoption(notes)) %sysfunc(getoption(source)) + msglevel=%sysfunc(getoption(msglevel)) + %sysfunc(getoption(mprint)) %sysfunc(getoption(mlogic)) %sysfunc(getoption(symbolgen)) + ; + options NOnotes NOsource ls=MAX ps=MAX msglevel=N NOmprint NOmlogic NOsymbolgen; + %put ; + %put #################################################################################; + %put ### This is short help information for the `SasPackagesFrameworkNotes` macro #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Macro prints help notes for SAS Packages Framework macros, version `20251221` #; + %put # #; + %put # A SAS package is a zip file containing a group #; + %put # of SAS codes (macros, functions, data steps generating #; + %put # data, etc.) wrapped up together and included by #; + %put # a single `load.sas` file (also embedded inside the zip). #; + %put # #; + %put # The `%nrstr(%%SasPackagesFrameworkNotes())` macro provides help notes about #; + %put # components of the SAS Packages Framework. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put #### Parameters: #; + %put # #; + %put # 1. `SPFmacroName` *Required.* Names of a SPF components. #; + %put # Names should be space separated, asterisk(*) is #; + %put # allowed too. In such case ALL help notes are printed #; + %put # If equal `HELP` displays this help information. #; + %put # If empty displays list of SPF macros. #; + %put # #; + %put #-------------------------------------------------------------------------------#; + %put # #; + %put # Visit: `https://github.com/yabwon/SAS_PACKAGES/tree/main/SPF/Documentation` #; + %put # to learn more. #; + %put # Tutorials available at: `https://github.com/yabwon/HoW-SASPackages` #; + %put # #; + %put ### Example 1 ###################################################################; + %put # #; + %put # Run the following code to print all SPF help notes: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes(*) %%* print ALL notes; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put ### Example 2 ###################################################################; + %put # #; + %put # Run the following code to list all SPF macros: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes() %%* list all macro names; ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put ### Example 3 ###################################################################; + %put # #; + %put # Run the following code to print help notes: #; + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas; + %put %nrstr( %%SasPackagesFrameworkNotes(generatePackage helpPackage) ); + %put ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + %put # #; + %put #################################################################################; + %put ; + options &options_tmp.; + %GOTO ENDofSPFNotes; + %end; + +%if %sysevalf(%superq(SPFmacroName)=,boolean) %then + %do; + %put ================================================================; + %put %str( ) SAS Packages Framework provides the following macros:; + %put ================================================================; + %do i = 1 %to &N.; + %let element = %scan(&list., &i.); + %if &i. IN (3 6 9 10 12) %then %put %str( ); + %if &i. > 9 %then %put %str( )&i.. %NRSTR(%%)&element.(); + %else %put %str( )&i.. %NRSTR(%%)&element.(); + %end; + %put =================================================================; + %end; +%else %if %str(*) IN (%superq(SPFmacroName)) %then + %do; + %do i = 1 %to &N.; + %let element = %scan(&list., &i.); + %put %str( ); + %put ======; + %&element.(HELP) + %put ======; + %end; + %end; +%else + %do; + %let N = %sysfunc(countw(%superq(SPFmacroName))); + %do i = 1 %to &N.; + %let element = %qupcase(%scan(%superq(SPFmacroName), &i.)); + %if %superq(element) in (%upcase(&LIST.)) %then + %do; + %let element = %unquote(&element.); + %put %str( ); + %put ======; + %&element.(HELP); + %put ======; + %end; + %else + %do; + %put %str( ); + %put ***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***; + %put WARNING: Cannot recognise name: %superq(element).; + %put WARNING- Valid values are: %superq(list); + %put ***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***!***; + %end; + %end; + %end; + +%ENDofSPFNotes: +%mend SasPackagesFrameworkNotes; + +/* +%SasPackagesFrameworkNotes() +%SasPackagesFrameworkNotes(HELP) +options mlogic symbolgen; +%SasPackagesFrameworkNotes(generatePackage) +%SasPackagesFrameworkNotes(generatePackage helpPackage) +%SasPackagesFrameworkNotes(generatePackage helpPackages SasPackagesFrameworkNotes isPackagesFilerefOK) +%SasPackagesFrameworkNotes(*) +*/ + + +/* end of SPFinit.sas file */ diff --git a/SPF/license.sas b/SPF/license.sas index 2f4a195..04eab72 100644 --- a/SPF/license.sas +++ b/SPF/license.sas @@ -1,4 +1,4 @@ -Copyright (c) 2019 - 2025 Bartosz Jablonski +Copyright (c) 2019 - 2026 Bartosz Jablonski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal