From 481830cdc42566b6084b5d7fca76825d2215e1dd Mon Sep 17 00:00:00 2001 From: Chain Frost Date: Fri, 26 Dec 2025 13:36:24 +0800 Subject: [PATCH 1/2] progress --- QGIS-Styles/TUFLOW/depth_range_20251222.qml | 178 ++++++++++++++++++ ...an_functions-25.12.21.14-py3-none-any.whl} | Bin 348334 -> 351097 bytes orchestrators_structure_proposal.txt | 58 ++++++ .../thin-raster-terrain-for-12D_v5.py | 2 +- .../12D-python/tif-to-LAS-valid-only_v6.py | 2 +- .../RORB-find-closure-durations.py | 4 +- ryan-scripts/TUFLOW-python/LogSummary.py | 4 +- .../TUFLOW-python/POMM-mean-max-aep-dur.py | 4 +- .../TUFLOW-python/POMM-med-max-aep-dur.py | 4 +- ryan-scripts/TUFLOW-python/POMM_combine.py | 6 +- ryan-scripts/TUFLOW-python/PO_combine.py | 6 +- .../TUFLOW-find-closure-durations.py | 4 +- .../TUFLOW_Culvert-mean-max-aep-dur.py | 4 +- .../TUFLOW-python/TUFLOW_Culvert_Maximums.py | 4 +- .../TUFLOW_Culvert_Timeseries.py | 4 +- ...> TUFLOW_GPKG_rename_layer_to_filename.py} | 81 +++++--- .../TUFLOW-python/TUFLOW_Results_Styling.py | 6 +- .../TUFLOW_Timeseries_Peaks_Check.py | 6 +- .../TUFLOW_Timeseries_Stability.py | 4 +- ryan-scripts/gdal-python/GDAL_Flood_Extent.py | 2 +- ryan-scripts/misc-python/ss/RFFE_Only_v5.py | 2 +- ryan_library/__init__.py | 1 + .../functions/tuflow/notebook_helpers.py | 2 +- ryan_library/functions/wrapper_utils.py | 146 ++++++++++++++ ryan_library/orchestrators/__init__.py | 7 + ryan_library/orchestrators/gdal/__init__.py | 1 + .../gdal/gdal_flood_extent.py | 2 +- .../gdal/py.typed} | 0 ryan_library/orchestrators/py.typed | 0 ryan_library/orchestrators/rorb/__init__.py | 1 + .../rorb}/closure_durations.py | 2 +- ryan_library/orchestrators/tuflow/__init__.py | 1 + .../tuflow/closure_durations.py | 2 +- .../tuflow/peak_check_po_csvs.py | 2 +- .../tuflow/po_combine.py | 0 .../tuflow/pomm_combine.py | 0 .../tuflow/pomm_max_items.py | 2 +- .../tuflow/tuflow_culverts_mean.py | 0 .../tuflow/tuflow_culverts_merge.py | 2 +- .../tuflow/tuflow_culverts_timeseries.py | 2 +- .../tuflow/tuflow_logsummary.py | 2 +- .../tuflow/tuflow_results_styling.py | 6 +- .../tuflow/tuflow_timeseries_stability.py | 2 +- ryan_library/scripts/__init__.py | 48 +++-- ryan_library/scripts/_compat.py | 20 ++ ryan_library/scripts/gdal/__init__.py | 8 + ryan_library/scripts/pomm_max_items.py | 11 +- ryan_library/scripts/rorb/__init__.py | 8 + ryan_library/scripts/tuflow/__init__.py | 29 +++ ryan_library/scripts/wrapper_utils.py | 147 +-------------- setup.py | 2 +- 51 files changed, 611 insertions(+), 230 deletions(-) create mode 100644 QGIS-Styles/TUFLOW/depth_range_20251222.qml rename dist/{ryan_functions-25.12.21.13-py3-none-any.whl => ryan_functions-25.12.21.14-py3-none-any.whl} (85%) create mode 100644 orchestrators_structure_proposal.txt rename ryan-scripts/TUFLOW-python/{set_layer_to_filename_v6.py => TUFLOW_GPKG_rename_layer_to_filename.py} (69%) create mode 100644 ryan_library/functions/wrapper_utils.py create mode 100644 ryan_library/orchestrators/__init__.py create mode 100644 ryan_library/orchestrators/gdal/__init__.py rename ryan_library/{scripts => orchestrators}/gdal/gdal_flood_extent.py (98%) rename ryan_library/{scripts/RORB/__init__.py => orchestrators/gdal/py.typed} (100%) create mode 100644 ryan_library/orchestrators/py.typed create mode 100644 ryan_library/orchestrators/rorb/__init__.py rename ryan_library/{scripts/RORB => orchestrators/rorb}/closure_durations.py (98%) create mode 100644 ryan_library/orchestrators/tuflow/__init__.py rename ryan_library/{scripts => orchestrators}/tuflow/closure_durations.py (98%) rename ryan_library/{scripts => orchestrators}/tuflow/peak_check_po_csvs.py (98%) rename ryan_library/{scripts => orchestrators}/tuflow/po_combine.py (100%) rename ryan_library/{scripts => orchestrators}/tuflow/pomm_combine.py (100%) rename ryan_library/{scripts => orchestrators}/tuflow/pomm_max_items.py (99%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_culverts_mean.py (100%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_culverts_merge.py (98%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_culverts_timeseries.py (98%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_logsummary.py (99%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_results_styling.py (98%) rename ryan_library/{scripts => orchestrators}/tuflow/tuflow_timeseries_stability.py (98%) create mode 100644 ryan_library/scripts/_compat.py create mode 100644 ryan_library/scripts/rorb/__init__.py diff --git a/QGIS-Styles/TUFLOW/depth_range_20251222.qml b/QGIS-Styles/TUFLOW/depth_range_20251222.qml new file mode 100644 index 00000000..b39943a2 --- /dev/null +++ b/QGIS-Styles/TUFLOW/depth_range_20251222.qml @@ -0,0 +1,178 @@ + + + + 1 + 1 + 0 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + None + WholeRaster + Estimated + 0.02 + 0.98 + 2 + + + + + + + + + + + + + + + + + + + + + + + + + resamplingFilter + + 0 + diff --git a/dist/ryan_functions-25.12.21.13-py3-none-any.whl b/dist/ryan_functions-25.12.21.14-py3-none-any.whl similarity index 85% rename from dist/ryan_functions-25.12.21.13-py3-none-any.whl rename to dist/ryan_functions-25.12.21.14-py3-none-any.whl index b22861f5e24bc3337be451afb9d6dab6918557d6..41fab2719fe88b8e4797dd0bbbc1b11d584d10e9 100644 GIT binary patch delta 38240 zcma&NQ*@?L)90Psv28mY+qOHlZCiKjj%{~r+qP}n>`tbi_dA(6m}kC&I;+}i@4c>7 zzpMULyQTo+y#=F=*AVsIHAP2sQh=2o1O&w5pJ9Wfy1?G^8C!Tjv5Grx~Jv;PbcaTCN6+=b=`1Dr^LwM2j)RzfS_zA@O8Z#o4x8I% z^y*i0&gz&yQ12oX4;WYLUcAfEq1_(n@@w1l{J2#|%S>}^!aeJx6r1Ic1>YN{Y|IFO~})fM^LK+?A;e}r+KX1jukw(_IZ7XgL!ah z*ps*=;cPjbNSN!GUah#)S(kLq5f6J%X!c99OMY@r!xd;G%TSe9ho}FUevLGLX-h@~ z0@>LSIBG_9*ZbqoCa&gAW-n=-GnR>ERS%;$vchVjB7ybK|8WW zsa@Y%4O@jclz4MYltqPw0;W^@a>jy+1S_PpD?I7;IMs}_Ayb+E%wJXu_I_Pu02{YH z(4ZNDxtm3J6Q^DX_8ni#(DMDy6{}npC{t^;v$sqD?m7YwVosqilpls&?QJ|kCGYkM za9KjFJ4Ne4$Bl_1b6?}SqOmlp&k+$M{vg!e>7ip=d(m)FL3#)YEP+)N7ju-_3Dr0{ zs|pIol_sIgHDzY#`6z8%PR_q1F7NE{?{TL`QkE4i?Qz|+SGA!Y(36vxG? z+tVhW2r0uS@~M z#jr#Cc4%?@I_Id8fY8>x=z<&$00A`qc&lv@Ke9FDrg`01cT=noE);wXEcbv6=*p;O zprO(@qalR`x@OhIrB_a9R(5HYQfZ3Y(#XN$IApQ;Y#w27WhqGGJdSwR*yAp4O{imt zd2&v}7%pN4dii*VJ-x|2?R(mpbN;g+EqSGSBte}%h*wL2!P=w4J0Mz#|AD7(T6kVg}y+zBuUwPE=-eNOlhsD1*$8UKKVP;e+sp zL=c&yOl-4ij93H7FMb5gq$Oz$HRD|<_w)CUWz~JXGJmLkqzbuWn|vX)ww-Kw84cY9xD1#A~e^ zwJ4jRV-(-n$7cvtJ`xa<1O4Z>1m#C7p&vAzx^A~YYE?1C4SQht#Zg`>tS0QJu}T#j z3k(K4xlm#h-`-#;sIIWDP1P;@)erLi#Bv}Vp$NM_#V^?Gkh+{UOs#AdR%=w-uIMF7 zvY!b-f^aJNRk}#tD9&aiVes76qLi1A9&n(^VfF_uqM24Us@pG30~sWJbmF1XQbn}% zz*X+ug|MWK5#9sF5as8WNC1HD9cn;5Y|}}&YF8>nMEg|&u|ZDH_t%gT4eDxSaj@k& zPv$*~Tb4~B_5DkzPI|z~qqWLMGB`qzDeXR^4=P>ll=yGXV(9TcW+qA>(696~b{dw4 z_#7A+jgUl}$ba)grHwj&08Y@dqwl=w{MB{v5xrOfZ5nCwfp(PoweySJ{24PtwGCoY z4{x#e{AFZjcxP~8QsyTkKgimMnB^{~MT!d6xm<*RA%#qDVoOq^<4k0cYhX4%R%Rq*&*m8+Xq-W15UbW2m=dW<4`M0VL| zMOw+wC;}GgKze=Ntxr#R5cGqkrqw0+Q^+aHRhSE?%@2L#lzc^?oqI@*wr75MWl+1a zA6E^(%{9Ri@4X0SUpx(qCqhiMB4fyf3(I+tWW(5XSQxIaYriSS#>X9pF%!`7i?b=Grr(jeqm^nfWMF7)p8@Qo$!x+N_{a1;kXiTV;Vie8 z$_kvRs|GJ6U>p5pi0;})`Q;kMs;SKH30SOS*z7!fZ#je~@8)Bn`rM%4J~1Mz)8^ZK z5UesCl{%_6Q{S}b07U+??9qYkn2KZq+?}T$cL@>#LkMPWV8Y|(2@!JTKKNi*4xDFub?@=xfD(b z0Z$xJ^t!3|D0T<$#56_JVNsRkJPg8n^SxR4a2j2PbMs9ggul&!*<`#OE4!f-7;V?! zB0~=3?gHPKKpp3*I zxDgFZf5bI?S8NUYDX!- z^!US(vhc41pu~MO7ivtm?W8LY7+Us>=JlGPxok`#Y>BK*NVw$srua0yserouMohlG z9urBG5^{g9{2?DtoIWHq>SRRT6)SQ@c_9?Gf)H24keO7Qq4ijtBXtx-sdI5i|9zrG zhBSgj7Q)(-Dv@L2*rcn?Em*MR4M!LDhoc9;VuZH;?Y(tH@#W_#QxWzC%6kENE+%)9@vU~-0GBK>p*Al^X!Psu?uOAEiCt}n51~4d)!Z}7c?@ZR4PUV}gqf!0*zRU=&Ch4p^K$ULK|e~oTwAgDiM~;QFNjf*>ay>hJ$VBk z( zV_XAlxcssjeopIo2MOkU=}jjQeet0Ivp!&FRu%e%%j{(V%2huu2F-QxV~5JEpy`7n zF95CH2(=yrLSEiPOOEM?X$ni#qZ@INkKiGHT+e-CE5ZQfI%{ z&-7YrZmnj%L0YNILE$)nF>Wb3$`+koF8>Ox;(tc@&z!xC>IxCF7lW8!zW0j74paq6zuqTi z{RE54;3R$MYn!IX->1gUf{eRKe~>jXp9DiU5Wt@u{zF|I!GKJEm!mWDxrx%HV2uSn z>L`3)4k%1sqAS@vXPD2K<=<^jqDcrVVX*nSTv$ZO&zwKt7Q`K-m6USQ=0QfDcsPwBO=D_S>x`KEf(r zqfz*5>BD5YkOd`Rm))0EcRirsgbY5tcCsq z-&#}JKebtZRxS{zsLu~mU4gn#cjQ$^;4940 zIIH@|s9>49C>N*z(RtF_xl~gD2^ISDVwIJ$(d}D{)(f~+4jb#TU{6B+dj@tLhfXX- zMVF(=JX3o7=V>oGWzn{U4MdSsq84HxwKT#=z4mbzF$EgN^(Fp7s3-GMg}aGpG1Cj# z!AZe5KDGujEvDiF6$2-@qjU?o_v6>cD>by=I!w&Q4JV;<-6!D!Tswu}*MR}2K3x>) z_ji~mB?(YM*}40W`@W14beY^DHDMGCN9ZBasvw($GY!ij@~2YALm0!;4EUmKIEfQ5 z-BfgE07?mB929_acY%x^p%#D(8A2AiQ2oAga`i?Yc38v?!a0J8skC_GMZ0t9kwL;d zQcpR-8Zcfgjo~RdENH*8g{Fi97Yb#=a>_%I)&(@|Qy?NWXC^Sa*9!QEx4NfWySAku znet@uciOra@K7iEhzqMTWWi7?I5^v3vAb_701P@mo5?J)$@EwiMfkgE7mXP7`82t$ zuNaBO!lsYdy=0G$!(roSag)8Kt{y#yZ5YM`iPy1fkLc z^#vBZ=sqU=a^Q&bwq)e>=9x;%vhA*bHa_N?>1kEabe+Zry(bCryESVEY0VIABRak?fD32Z5=aVn zXNR0YLHx;DMzEFAA131+Uz*d}44m$lQ&O@4?F;_3bZFlIw-!!6Imy-0{r31}9sA9z zUqOXv=%9l+w;{qSi7Afd<_AOnxcHlQSVl9Fa-v$NZ(?+VvjP`az8AhEYx8ayyd3zk z|Jff4!3X9acCzxc7ca-QtZyy)ev=q|h>aHJHZ?TKuWSLRa`-2SItNZ2H za=O-{FxbenlP!;KoV6{a#c5S#bzF1GL)Vr26s)F{qVkYZ1X%Z+E>{L4=? zc?*CNGwE3Gs7x4^4f}}QZavBZpA2N&0c;;(N@8K`YlB6prW%RPO5Z$r)P}*xr4rwU zCmWF(`#y<^v*eO!`!WY1lD`UV?%_*x)K3{8C6(JcIa~6F%6dDqAD-0F{u;pE&N?)A z-drUea<|=v_ZcN)%~r2E>PZX#i>|V``WGGwRH@%}zlsL-Dg%)Vqw$Xe6d4dfwfcbX z)XRYldO-p?0+^dC_yk!GV>&jTu+{cJta1< z^lu5*@|2sjsl_ng2i5-DpR*6m^Av8ONq7+KiLYxr79Lq3aXJ$R3dRm!>=aAyaFq4V zU{o*rYrHey{tSB#qXd`zf{Q0E@rK|dy_a!ujHnom691&AzqOT6A_b{DN%c{?A*QIF zT`aNc3*vvEKtTOp^R})Wfaw1h7MvZNjsIbR^*>nPZp@w+g9HI-LivAS!G-ZZVQIH= z01RM>hMmJE2lCgAfp8f#adl1njShmPXe)=` zIZfgsfEHGgG;Y+#>*i*jl~hN&gko2kX48kH5llr}nZCFqP2}dLQMpW_fz81%C0b_K zty2?S8DCm~eeus2wBU-!#n<-DiYk$iLo3h=uGXCl&1{^dGWw=LVXxaf@kXXalWt2! zzA~Ez@O`;ONI%?@AnyU#d69E(#nEbg472to`;l(!;YW2?SiW_gC*c3_BQ@saM@J@R zmuYvDqwt9+!Q0Y#iNbUEX{{T&a$7rZt-IH@`Rp@<}!Zx!bzqju5O>M21SG z0Evy1xXqcz$iUPhzWe9n2wLH{#bSAkccMG;Lo znKHDr^#JW|fc$Tal%vpuKtbXVn=T-63P?OAGw(`A^8hL-J?#@Mnwo?gwL7o^d?+pC zmKL-Pig8WUnF}&C`ri+8GdhmSglGV)o@w;**;L|Lu;~TyL|3$k5^Mz{ zgm#16nEui(Cv)RX{^)t4loO!{7^2Gd-f2sTEUQ7&x1x203dn#qy+|fiMiom+2`-7mCOt^N7LdQa6wQH; z3zk|ECh3xRq;?KU6FO?i10-6|rIW%X!&&=oQ<`IK6N(z3*JkRs}^WmG&++7!@Im zvxk=^zi_2*c2$msW&e)ax&Ld_@$muv*J{@MCNu#;1)j~qaeONlXv!Kwzbl+9@$Tp( zC!y3Vy(>GvL>G>xXmnz>8g`i=3{kNR!0fo|M}KI zp6;dv8SLuy3KHP?08pH*tg>YSKgXhkQ2AcWFaOT^8V`gj^=e_z!svK~jz%=T0;6-s zZUA%cOWu{tF0+AX2n3FQrH6#ZhEKs;KOnsm(_Edsjb{27ElouNE~RAMjgMiw(&{j} zz8xP?tcRcQk{i?EgZ5Ssc^kGfrP08iT6K)IRKW;-4#YB}s0Wq>_=IJ0S&a2jV@Vv+ z4<{~;1+%~|Mx%gYFnHxQMp+80PP6DYk=rCg%BTkLQo}Wa?Etg+iA;*@+wcmd>O%`r z{S5PkWX`mX=#DJd!*-Mzp~8S%3wfc#Y5+`b?ju#%UvTBkSBqMe-h|Oh(=_I}IWWZD9pb>A|COs?E&w zzU}0UwPaQHK;S*D#{TK&Ibuzw0Ut*b+$=29q7XHo7LEHrt{MG$3`&~&%X^zFpB~4% zMGX?!4qSDsa-pde(pWL@!E#Ed#+Sh*Vfo`}ak#}oniXs}6E&~Ain!9~PB@UpUkmcJqt&DZ)!#gzG+Ftzb$SlsPM3OLQ_4P?=^(Q`Vflf8lG3UJ^%iy7^( zLD>#B(2aD#9wQJy4!HkhHj*aj#ywIzwjQVyxopC@mq}d{3Z37463Rj&*rqSJ@WQ(S|nD7`> zv!3uzFIe?^{#a_0!uPR*3I;1Y67_;WK$Z2OV$I(w3iqLDPZT^Ty5vzJyiN`$)h|5D zWUO$UkzbJzmn`Nx=3KoNNZLCtJ@ps$nd^%N;+qasZli<^zwb^ik~Ko1J3*tFCA-p? z@Ig<$LDTHy0JsG7|CMe=+z{xzhsOXAMOiR#^nb3s@R_E&eF zM@qz426=3@{H)>?bHd++${NT0N-I2vRBOcp8jDAuk=XpeeKJ<*cMV7)FSoFA$^c0Df9E)NF?7mzRJyF&U@=5mt8! zOstP;G4rgCm9A50@Tc_@?}Po#8|^ZfAi|M1PK<=2vmN z=0ZhYwL8G<`yzDw4Ot4E5>;(gKBv^n)WM6aU)!AI)eTndCYw6R6tV7YDT_vR794@B`2?96kjUk|{*Ati}&^`yN^ ztiY4FfOI(6nYNZ(#+1XyBHCM~OP)FOlh8PB+vf+5s%cA64@bPUT@_er8!J+B(V6$x z^^wHrPIBeLyuv?XVklge({8WzoR&h@8Q~3yO1a9w?HHIaKy|q2c|s%{c2jf!x`lj; zea!}QT*#3Ez9&%fLxT&jIyiJP2r<6F%=PShq~fxE@YUg;DKzp$=_llQ$uo#zj^xB6fOh zS3-D(Ry6ALG7DM)L19Ktgd|bjhdlPi*609sQT&y#qvuN=SudSS4 zH}(eXn|1pVp$-GPi*)HBP&q9?RcYEmM1aIIW?}V+;HYj*YX!{5+g&@BPqnkdq|08* zyyVt3fuu5+7J|HdmAbByR=wn~2TzZ2{k=zj!_n)^n6+Ebx(irNP;N;{1^MK*^n^waC{n04;w?e48eQ2p$dG zgw(3jXnfP=;YB_((LtK)9nxa|e)}AD=7K7!PE% zuUC|rVe)L1xGd;z%kvON7OEpNRL+T?&SdP48>`m5Kd_}?qJxTnm|0luc*6I$ZaqS6 zVSUlL-6yA>aB|&p9g&Mi##+?OEVebw%)V+e&gW)2KC^QVlT^zlvBKZ$uaT2&f11Hvix`?+&iaJ{BfEnBW47*+nA)CCy&o-e9P;+ep%Q^P#@OfQ*FeZLJ!g;=8W)dXI zYdBcCG+C0^qn)Q8+`|>WBe#%#>*V8%PR!M*Tg{y!evwoF!6bQo3=V8T)?O5)>l2zb zt)Y7H_1A<4HAEJFmAKkg24=rVXZ9cA8YHoohEE(;e(SPpEMHa{)O_KTy}XdZq#xuz z3L1-Jn9Td#{9qH7#W>+`@MzYlGP7R)q z9}aQ5e>guo34OCh&JU(dBz!`Im8~?-a9wV?JH~oFyi4XW%?=y7fcV7bwqU9xv!<}}S;0p#%J?&q!Xg<$3R2C^BJ0f}AC0QNS?wLX02#i|9HGe6d{|5a(5xf!# zZ%6VE!QuZ9%=zCC?82Dlr3xSca-sIT))F^`Cp6fZB@N=^&H;o`ZxQ2v{fe}3W&#AI z%Gg&^D2pollP7%(sF6Rbk1mF%cI2uqYal%fru(BNt}g$={5UUJct?p@9-y()->9it z9-PD+B9QdCBfA7k7 zZ0Zrv4&ti0vNI*YSxLos`lw?N+o>foy^|ix?64p-*DdoiRi^U;z_gguI&>Vod(otV zM%Ars(hW;(aD8FThvgBAk62z_Tf|H z866$ZckONWj?3fwRr<3#rp1tbVKc{T_BWIZ%%*d8gteMu;cv+cc{68$KUd4Uf+vc- z9-#gbyCxLk0WsyLpt${-T_$fNQ(Y7vIuw%^?za&lQ6J~Dj!5i4m)mlRlii>vRXIrw zohh$|&1+a{9HhWgGqvEzAA(^z!#dT@OeajHdzt?fz1ca2-sC&gb&CW#7=3TiB3MQBpA zgV8dh<7JXWd3{enVarISsL8WMy=5LTX^L4z(8GM>chiHup7~>+}d^8rL!QEsuI!*%C4{-O+ z--Wg1vc<|f06u?D12q4d3v@zL+5BAtJ!nE zp$7J*>>Yg)@@3+rV@!y7=wQOo&&E!Y$?jj)kgv}*e$x8b~RGmNJS8x`7 zxVXD&j@q~Sa#14VA6NAQf8zNX=DdLW@rUu$kiRYzi8=YVKQTpH$ZaDa|5(Tlgq%DlioEyZq(%9r@C&i2C|gs1Bb$Jd?}dF4z0_%6-$G zA)FxGuTnT{_~x@|aJ0Ze4svM;N}X->qQGE&)n}`%7D;-1l8vip$k_iI+ABOfj*6Z< zYl~{hmKb{4TrX&lY!OybIxo^xluwm?{DBAt z@tPj*=0s%N+fA~#t*r)ovF!JqrIpI>Pt#Vh_4uqLA+l`l5EMX}-(023s$wvs6IUpX znKDP$)*Iv-{semSDyqsZ<~c8$PmMSjGxyksC`FRU;)rs}Gcj!R>GPC$G4B;QaLuF0 z>x?v5zLr(idKWJ3spkj%IU<%v3LOW|YvGN0DSmir69pJ+gS5x?uSHtk@Mbb!#B92( z+_61riC{+0Fy8BFv?x3`q)lIChx*3yh2`PI>R~WJ47bY46Y`{>+15g!TYIVFI=k#e zr-Fld`R~V+k*rtRMX8Ng+?4YWAcs3u3EZ3_ond+>VAe12Rj~xug&gUbZD|_oWfsDo zYQsgzLHOgFT4GRV^rG?y_FMp0=qMNV#6Ue2g5e95Qg*QfF}R~xd#KqCfnJSF#q3m8 z9#pjPFom;Im#`MUIihL==l4ZDbTv0XlPXs{kAq@ld$Lw*T`C<;fuq`%##s;x)&~o+ zrvGrCScN6pzE}Nv=yJ`{JZJW=(#AJG&Q95w90F!p_g{##I-P%oG2?%OYU{oZpa6=1 z`M>&Pm;mk}|ECRzT{M!W{two#1Rx-+|1Bo1-Wq@h)cpU1-kSdiy@pUVL2kQzmO|FQ zbpng0H%x_<&{^nnY#9>E5>)X$Hi5edOO+JA5nop9*rOy!y+#kWU1kZMLn7#>gF@&b zFgDQ`2H2%2$__+wkND(+lXsxxglW2cFWYJ^b$fc+h|`1|#_`7573p*mY=%)wv8866 zfHf;}iOG`U0CKE9vEszix~2ujd`V(X4MFgZaK!eqzg(s1JY`}&=FJ8$y!6Vt6pw;- z8k?k!#~~)C2GhkjU!CWeH&1J`Va8kl}ONvG;oKi>FVHyxWu?@g*56`=O?( zm$Bb4Bc?VI6GZPMHE2O;337#OV4Bj7hUBEZ!+FU}0Y*YN#Sx|5D!7Jd7QPYm6o~G6 zNlpn1A$}o3WIT$S_(wxSlzUozKo)R@=&QQJsagGO{X7GR$HmIUy^HPR_01o`vy^v) ztnMOwv!6n~EY5C_?Pv!*+=58{Qn%anE<9N|dipujyoHv}l4DF<+PbnUU`1aFCZkTI z5s}mlEoc%f=yV#wL&$eyIGg35IPWQ42RQi(e=X#4{cQ+KM-p(aKW@24fW%vDf# z+!h(60CY2)Qh8pTBl`|)t67_p^(E_(-DdEHfKT;+jS~i@UnKxsuV#u960EjQ%PnvB z-TNR#(Bk+^RkjjxH;&H3+@&3QAHoL@sFya5va#Wymo~9|(61I+=G`E09EJ?k7)FJ5 zMuTq8>y7cmX+RFCN-M?yyG?E zBvR`hl+_knh;>GMh(%8dRe_9vYVgI|WpGfvny}Y|OIfX`OawYYe0qzbO74CDXpI2P z8v~3xaEhvcbujR<)W{g1PCIuNAFhycGrFG;pXGC|z>!pmZCb$rj+9--ljNgXMGL!Y zt9JCfj7?s}?uuBEcF3Mee~OXash{yqYmn1N7YtL>kKraEh)!9)n>RKTXWA(Y%dFtA zgS68oqvON5@|RY2fJbcyOK+!Btii@}524RmT7O-c-z?MUtnrOD7?Oe;k5im*GNVbE zVAc%fxfu-a}fwU|PmpUTk;90uzD z6C8hwN+un*I4I-2rl6uZvaYnui$!YI*ymJ_hb&UI5uBljSDv*Na*oRDLr47zfc(P! zmYon+FLLLG^RRT_Y)DV)CW$FE$7b9TqgaNC=W7@BY>`z5{#Gr>Eg0aa`1xbc;%aox zzW26Gx|^oq?*4PROiOeS*}2*>e`sB8Cq2TywK2A0c;q-`$2C)(PWhQ@xq{`}3matJ?>{U;VzOoCxakdb*RM zwHyo)Vy6T=;1OR=(j(@->`B4eB(sIX5zL>o(HZ{GnMvLqUmGb3xngU zN19ajZ|dHbx!$De)1~5=+<>Vrf@pE0(Rp=)8)5tDaYGc!#YY2O6OXZiww{2ozA1`2 zptyvx6fdk+woH@cVWY<{$gD{2PJLNOxvqn5Qhi7rXknX#D^C)6@WcICUljGr5p4@0 z8|Pv7R(T+NJXYmH;Ms%4umLP$JNq@9%WU--v(x`?6XRHpi%1abq^y{^ey9wbqRAYCeiHK*Us@?^#csCi6rMOGnQ!A)B+PK0LVI zpJ15BXFg5xHg=)t?0o)J5^GzRr!%}xajqs(E$~`xmjRn6;DOg+`_8vv`Iez}_GIUL^EM5+WOgIE?fffdz3c+Nt z(b4NT-D@AYZO#MMYKB@*LFQ$X`rDpz#&N;Gzv-n(X7#6&qlF4-IV}(S(O3Ukh4~p) zlt@zXP?IV?b+yfEd4$#~w2W^)y~qg0UvLLRk#9iMTZ1`&=naqh8okE2EkTo*ThPlc zlUKFgpcPdxhmSss(cXhBvuDuVCvAkax`cRFh#uZ6-yGau2)pqj179q{rsstp-(ly10cV0}vvER?yP?NGvP2+M8ng31 z#&iEy77O!1;I#TU1C$Z}2jVk#aLY6QW_j#TK|px^pMhxzfdFXWv4+mSo-O)+WbY;{ z7)LGFI7l|)MuPl+EYs*tBWOTsDs@&FxivY)==I00hg4LDmdzqRf@Xp?y4TEpyYFcs zQ9R#b6uK{CIbSa(3qMN<#j;4nYR5R7lQj{!T@)2%Gbu$9RM@2pa+uNGOjrK)=jHYF zt>v-Q9Ph`}WGPUU3))?>M)5~OsUbDSaju43!JWLsL@K42Oy0hu+c(}sSt+$OqexpIaWd~?5tF$>Z0^R?)Aq(Njpw;hn=LlieCuv+aa%~8LA9{nMShVS}0(wpBK#T4l;1v84Kv9L;Qby1n(n1MpY(5e>yZDRGzY zch#CEBM=z8TL9-1AK8GOlGfl56(`1$iBh+?AL}Xd{DfLhC2hlGW35MFDh>A)iGpTp zeBU5MMMFzUGf+vzHMR9JMQ_(cBL0Wnrvm%D_f@qd}?5bDl`_gZZnb;)T7)Y?cG~mS@{Sou|-Dlzp|LLtK#Y~pS&vD~wXhNg&#jl%RijK)~V85=YeyuavrTP@a z6*v_MA{akiP|;djiD%#%=h}=H;1}XME~}4daG?331e4l~*>^5X>yA%&r36l5jgiOe zVRLkz$>x{SlfDKe)LOPc8q<0l${tG-y8%t*L=Eyk0i?!pDBi)H-o0YHZEcKUIc=7- zh>ComD2hC+(6_z>zno|vC2c1f5PFli85SsMg=}D-xv>zilUx+b+=f#4Tsx+X?4~Ke zwWaL;fOC{I4G_HJ-?e}!xa72h^C;v#T8wU>7DeoXNpOrF=r6%z_rpK!MMFB5e ze)7jn`0Tp>VfOB9(FkVP2rR^69y-O%@6-8dR^4wAO#+61^_lAuvccU1$OEIh$+yBv z1Pu%-J(oQza|N`W!rCouZ`M<#`5U;Z2H?V8^S4*A@FU2psN)H!k9 z$ZVE5AMQlNQeCKz>mC`O=AwnuFaxiO=OL&QqjT1pTpl5NtTf|})^CWl0;BmT&t&Jx3CtEbvFS}!0yJl>daC{mTgVBY^G3UmeBKv z9v8QTYKE9^^(pi2zDKV%`4FF4!?eXl?5rf#ZfPX5=c3`a4y=H)&VVO}KH$=aE1}{E z8R!TWGFEK+fz=#wP95`T495O1p~G3oRaC>UwBWFi`M;9-n}Hqlf%}?OA-XBc`0@4g z(WRMvWuq#01`Ja%E6K>eg~_{c$S2d7k`CDe?z9&crJ~6m2R<Ttb$Tdql`!)q`})4)^z7-o}joF*sl ziNd$ZzRIH6N$QcEq8vYyD+K&p_!X1kPoM3kxt4Gn3%NB{`< z|9#Lk?H^Pq|6yU%{_x+R=c)$sMKpqE^I0V*hLoQ$Sg~}JXDfA3Kmo-Br8=ovqRc_l z-`AOlj;t*6PjxnE)2M82{F&^Gf*!JuA@b>AeOAAZGFRuL5o_}l4kEjh$%j`x(RZ2a|Sps{crFRUnRiaIw{B+ZM6v*^I> zBB-WR41fQ_#SN=;hMDO|k!TZf8@CdOv|_5MOwvlS7rL%?qKl^y6o{{F{yFqpf~hvf z(Y<r3ncZzJLIyu}FxV4<$!bpl)CT+hi1|iwC7mU&)uF*)N zl=};OfRmaiKX4*ICM4*HH$&p~bTGSZVJerPiZ z)Yk3AQ6l4*t_H^jWhZncj<(vw8J4t`xjSH=z$z`6-`RxfGELFQDLj4 zl?mHjm9#`PXw#rlW*o3?dgV99Og7gIq*(0L*g9~my9l zA?I9tBP0@5@mCO@GFoVURiG%2YIK@!x8!*H-h7EuL1;}>Y>k|9Z%x*b?^6K0V1tt~ zS7&E(lid+t(PNdEV?IP(c^d73=$`;ij~HLf_~1c(cHToVUk=vMutxT#?2gj28o3}U-Tm5ew9QHuZXyQXenO^Ikt%y}dQcGf;TW2{nS`)>Jyk|a zv}KPiIkzPighH;|N*eicz3N-WW^ZaQwGN6M*6#VTee`8a7rl7q;Fu`DD-a=#9Qu81 zhIYyg{T&(z4@-;mWFmxP*MR#IM#Jt-M{#&}M>C7TTvO8P#vw?1j28^Ll1WSCjHHyCzO1_bew`Q9kr zs3TXoOhV)sX8OVyulR?TUqP~gKeUc2wjNTj5++nYUnbfVy@;D35m0`ElL#Dp8H2#~ z@`;pAL+WF_wD-yT(%)%>Kw>+WtEvqiTob3PpI?~cscH4Ct|cOOSHz&{5k(!)J!!V+ z)6X?xFK9yPKWdx6{2?dqm#yuS=Og%zw<-ARut4kbGm&nFv_#eicLkLl2>p1KrAk4d zk;n$C3hsva3nknm8OC+{u0VyGe5x$JD3qYcqqh^umP0Fn7u6G`*JzbLfa{@#A3!kLvJ!+-zKIaMNgIaqd|=GaZI02M2N#ymJD$E36wQCt9eVea5g#wWsq@d zGH>^Jr^mT-4rPSg2V?G9rRwGMw|Tdoi`X?BIl%hk^VRT$iq-V8-&`=3+CG?OUK%;8 z|E7&dAF1Wk$#@A_Jo;5OWG=rHC?u9ZFyxlV!RGlbee$t6Q$ z{Gu32AubU;2L#DuKi@R%kB1G}h{R(5(LuZbg9?XJJgK3#aw~hdPYZ?so9|$@ur(pp zkbBK|4T^0OACAmd?p;iuvGHc3vR+Ivd)#GKg3>5Cpua2-7}HXsY>LC3w=r?h@BBpV z?wL#a=S*{lK34Ij5-eWsq){(=jyd^%@%2v8nM7T;aBSPQ)p0sb$F^`+J-c_^qUUM$$js$P<1-jBqcmT-ZRTH|}KFoQJSv4gb zAi>niq0y)9!ERH_Hmrrdl|Uf%-}-(bB>T=Nen)dp<Z7w7sWzrvru_St<8-?lZTS^LdszjOATs>~M%-9MvNdC8?lf>pei8J?luvu|pQ zOiCqPCXx2z@vphn7cS!277a8sP7i&O6^q)}4Zz zqstf;q$;c8dePv5s*%Vah5E6!qPn#C?=UXS5i#j?)H>9oa)8b~8$gMWu0 zMjXM7$;drr>RQ#R`#fo!gkqieEYliUO%_21Hm#-+vH%*ZI4deu_FL2|7fej>yljoR zKs46rzA$gx=Tt=1npoN-65{ca=w4RdiTUgK-@?zO=95K=S7M52ak}edjPY15Ikm9v z(0H7ys{s*X;U#)TD-`J$!vqe3_+OOu%okjTR#p3x`KxQ&4Mwd)@4x)4TbZ)s?-2loYc~{2rFq*q~R9%di3+WAyH;2#p z;W9TAT-!hDR$B^_(PflQF0Un3jn0oM#$FZQB0TGx_|8^FUC*NonF!B4lJDCh5)&RF z2NjyfFMb1_J_e6gBPT1*Wj+q)kG}Lyo_-I68d1+-NiNIBg(>h_A`p29Ws|E^@_MfJ zI09tk!r;3^_`K_h;uyvAr9!NeKiUI4LS!kO{&l4tlVgi1h1Yw4JsVKo)gG>2`8C;{ zzqPtehg-~vgw!7V^HSp9ieVKHwBgs3T{c*D8bTTxl~>&W0`oQP0n^>F|8V3@NUT3LP zB(-TaasM?qA>uXDX~==}o9%=!^Qsfz@}?c;Hn|aH6GxGDsXRQfBx2Sy)TH;Kxf}?w z@3^OR!HPvgv02#D0(HLPhtss-y2c4|Hse|<=A(2o5Y%p+rd0#+)Zd^Mho=TyoB^QX zIGG<3;ck)nG~~i-s*3&?ZUlmtjZ6^s>=pec1FtmH5T?(jJqxmM=ZjxaFB%vUxtu+I zK59~V4R%NG#nqCTPy6Frs=BA1Y~UNKUpR=&U1Dhls7Uq(5}odIjng5;0@2bYL5}J-qprE2jjLl>--vFT0lt6UY+`!i(1~a<*@hzX9T8{C(O4Fo4R^@Xj zkjX{qr}EY$*T#II;!D^yOR3Y1ePz&a`3h`9BM?rHa~0sQ!Q zF3HPfDmpA=hGl!#1xY@mf{wBSg|HL9@Z_J#$i7)n6fhPpi^7$=l6HI%lT9EnBw|*|)#)rFaz8~IyClkj09s$(zIRTbM{J<(i z6WNUt-l$AQOSMbyY2U#fz}}k*YO$S0p&)$Z<~KsK2Qspn0xR}TVUEhr!0UUT$;l*Z zY_jc}Y;&l3wR~GqIb2>K20>Jap&0gvSfLqHe}cgeBXRt#dYU7dTIOVDu(ld17~ZSY z1P%i;T{d0#nz8S}E3tKh*MFDTfUxZ0_4qcu?SBsVKj|#k)XcOsED+GekBo@te{Bu? zUlQ2V@Kg{Az&hvMW_N%*0STct_>V~UV29@*qX?eCVy>tioB;| z+^C$LixESiH62Wl>Gfm$^z{(a(Pk?F_uZA{wc{WG@K;3hIBG^S99=~kr7@_ze!@ct z9TOZG`}N`LBILlipC+KiKmqHsX{=NP+ORIOQ)1{*3xmD@ySz*p2*sq8I}B~wG!Zfd zXp<~q{EkR7Ne^>AEQ=aQ_Du2)GQ}=T+MF1goVw;=4?bU15=G%Irb#jh9nuh5G5?ti z+)G&;fKY93p1z?pst97eqa&ym1(Z690;XR^1_+;j3HVJCZ`>>Jo0@i!Wl9A7*t$1@ zO?P%US2bf>eB3EP#Sk0~UBGz|2Hm8w!a%N1t+)*Bwc{_AOij>;9DzUcj)7QN6lxuf zQ;9lv-T8qXm)eC{V0DotG`Fq2c5jtOK07%Iz$%vzJrn!2gIdFL0@Xxfbg-cM%oKWq zUj0|PbV8P-#1}M33s5?6LZXmLW^Hf|fh?5v2+G%<&_*=!&gKcWaWQcGYE(bP8cC0% z{b#%)dUs8)F&sgM0Q6m4mQ(qR^*_TMWLh#m31vi_C5R-j5HnXlGcm+wU~{6hcpx}( zKnth>2dCgos3t+QC%;aXmi`8jWqO)3+JQhXz5D3qK>rNPAgZ{Y5bKKgthcYE)2OEq zx1gJ9cPdgh%hJ#Vnzn z1N4nD(6`LpYQ-dF`jEv5j?NwKvOOL)qN zXz~vhQcRwaN6@20^w0{V@EuQn#%yt%V$~vF`dFW&v;TxY!ATL){E^+L$(Hjg04PF# z^0mpZa^wdnNS5^3l4A<(*tG6?YS#)x%EeN~SM0G#QK1VJ|?&p!bmk6wIQxy z8Dgg+47T_N@^M2#z<&)oe;pzWG-@WY?(1TKPJO#2Vq1{CG;9x*ZBr#_Tz>=tlA@&5iVWS)BIc54ClDHwfS7vf9;ph0)S965*;iP z%0eZHllZ4W6Of@QsDW7$gH!l1`>0f%!iMqwZVmhXG%6mv*JiL7>ynuyfZi%`NWdFB z22FV4Ex;4LE_5f>s9UuND(fWH*nx{u-MQh$jw4_ERqnDW^w*1pkB2Y1#@Ey7@hKGM z35zcX@1BnInvsz)Rxi&c6Ckxsz%R8TyL%?8qW~hsb2>^mtz8B&bA(!R7%k zYRk1aIwe|AmA@&T1o#UT2&39Sf*fW?ut4K=zYIi`ka3wm_ZPyMHps_p<+3Laa0^_| zJ-xpab2RN?DTV&#vz^7u%LDcRLL5ys5;4B6&)rjbc!YXOv+E=5w=d+31=@_Nk_H~F zlJH3>XS?n*f)1mNbq09oR*1x_Hg+xH<;f>i=PHVQk$_gV5#ZvZcIgMPG>R>LEj;fu2|KSf6TP3uye+;cgGE zHB68QlnO3~&;~W4ZBt0O^COR|MS??TbZ%(3lEeH=v$`ii&0BXXSb%GPx2-DxI6kdF z$jT2`#j*)X1EfZWnC!w)ad5BJo`&Ev_icf6!%7ZGR!xenG>F4mk!u4qKR8`?$P13Xi$zumfCbHZseyo+H?&0wq5 zTtV?Q>VwR9ng5NHCC>2(OCjhNO<44$kPM%K4Zj}1Y^5P1pNRdjV%-EAs(Yro<%72S zon1)gu{Ux0u?o9p8W~sI9ta9Eo9o;`#`ePCxp-QWh)`BF$Y(ECiysE-3WD1i$g?go zxgHws0l;b!_s;D>&Md>jdm|WyY#Hf*e{Vl4jbn76o9Hw6^mcOey}N3d-TSlSVfs}7 z$kx@vL4V#l857?T%hJG%$;8DF0qF8`EzJ1XBroYvY>AR)A-T zV@{^C$a#LXf*dxbeJ3<~P_M_?Xb(tIJv0xP0tApwcMy-dW(tH1dSntbUh%tl+dls} zV2ZNzI{3@17`c(1V2Mg8Z&HukqvWqd6tTlvkNk_OYf4Eml{)5&iLa>*^y;=N`xB%H zJIDz#D8KIGTsh-M7^I(4Q zWUK$Q;+~(gSyhKy=~rDhhBe0#pug=u5kqewe|~iBfAq_Wr(2b+@Kcu%m>?RsNX)@X z^Q&E$Z8z31IuzVc;bvR#h6wC?$9Q=W2@q?FdT2Q5HwZNsECL*;nd5hG)LK5Z*1m(S ziT{8Al|FrmbiW>#VN_TLMae13O`tebE%qJ%_gYQ66Ay{83cZ;D3nKTp`iBxgmi&r% zG(4FyH{J1@zZO2wyrdPcbqYuoMgYA%SB>T{Gg{8IL&y63rc_0S3$@yA`_g-u1~^jM zUWNU2fBd(pRRgmnx5&uYLHaRc%T)iF*Yju*F;Qp8*|*+2@97j>;-+J) zZ`r_J$+N9125I9!C%0A??!?VLvfI5j$QfK{c|4;i2k5}#OH&_O+4Q|$n6rz0V-*+S zG7rm5Kl;^qHx8kyGyE}5wVW~N1CVx-2b6$_1ik#yjPq!SrS#OfSeg68&exNVQ&Pn& z!NsOc*h#O($Sm~izP3y{q7p~*1A=}+9N%Oy+=IRk8#b9%R+~kn{H9H_a=KGI0 zF(TDck9+$ONVJW{6osHz7j^5e1+o`kK65aYMteis*33{sEym(oWk!8G%YcVp!`TZk9p3hvl(EMt*krh4c%JjL>Z^n+QG=X_?NH|qE`DPWI+FIso+ zW^T8f?BgQ74noEf+U7In#$jE|UDikYH~mki5Gipv?aGUnGnVLhPdTk_&{$p$ClCKn z;FNfo^johV80}*&SlI$1I=U|xwzFXhz1jh6t3U3GJ&7)W0+UGafd z?+;W8@|zda?IzG|*rU9J;>im?VihOm^wWa;x&%|Sy-PUf#D2J$Hskgw&=g`GQgMFn z!BtCD9Ho`_I=+ zdkkW*rDk)xNGb&|wAz>cvq;Oj`K8<(qEyQ}z9R7`p|>=VIEN_R{sF4eeqlR{UDmT{ zse{nU=wWc3-LdwK!2E#%LyV?H72F6j1fyQ1cPxHXztNiHd}aJ)c9(=n%ZJdd@p367 zuf))P)@Nuxr2Eq3(FC2fP=vh0Re;H;+cjcmr>HNYTLcDh201X|N)0xbVrK#4ez|dQ zh95z)NlX_Kgck{t=%)vOb#^L(4Ahh}O+><|aDIHDu8&G5WPep0+z%V|5Q`W>szqq( zcl{KuLCN)2!t61Yd=SnP>P5de+cBIjKP2J$0&&DB6Cg>oh=k{Y;IfwbEwK6$Jb2?n zPJNI3A;$(l?Z}O+)g>c_08FxNZ=fy5sCw;j4g&aCW=kKp32T0|j-Od#=Br#_nmm53 z{&CANp!g7*J_GiuB3dZFl!Y(ob+3~7#IU|%+8yYFOT52#fQGl_s@r% zkg-3A&{Tukh8+GmH0hrA!^xB;f3fEg;rxrh(xwCSDd-cbCJ~gr-F;(z{E@mTLvi8l ziRMTVv|2?b#QIfhwNUH2ld=;FuZ`015GPcook&J&dKCP&9=}RD-wBk1=-avp>WUrL zbyf`NG_Kobag!5~BU%PTSdBEQ`tUZTd3L#bwwtg;{_J(xeeg9CnOm!;?*dlKL!;0( zVPFEdpTqUHylD)eDYTcxc|rxHzyk_LlJE3GB~wM8HRo}l$md9IFr%~5cX#YJ9eTU+ z?F?hw8mg&=M;)U)aF+DA~+f* zq)+NVT%0k!h>ut*)<084WNhv-=z$|5-3te>0&T+UGVg|F?C$$w`yI3XLj3Zb3Hq04 zYV1_hB2x0~%Y%ToVHLIyCuvl4W;KU8T6?n7OF$_WBMW2=-y$$-q{b~s&7TZBwUiS4 zLIPs!)c4fNFwHR2jQP%$iK;3h3~T1p7jZI?4f}9ez~69X*uLhm`eNF?Ciipossk9* za~ZVH!K~V!u7>9#$>Bk)zbsPeD(g4pMJ;VKK7OY+M_J2a>9W@Q#^*4;ePuO*=Z;JE zx_&DJJDfnE{Ch#%<~G^}^nmj|Y>*D89ywxppIVM3)uyMCn0}&WGL}|3);F;k07CRs9 z%Za^Z&L|c#neHUP08BmnCfHf54YzVx5O&Sywf+4D5&|GFlY4&Di+Hy4ni8SWyDAvV zA#k@|tkB;kl#z@I?%CEyk4uy%hNA|9t(yIs0&#tIq&D;h$|_8Q{Y)Ixr+{r9zNO!4 zb};cjno|ywHNZ{St>0fK8tlegc8vF`%A(r+ZMm2*XV@JeBtjWsOhHW>tD^-3hvNr? zw*VCAHhiUB zHjkEXJf2-M?w_^>IO6AZgI|QR5En`~OB$+EXYDuZ)qi5DA!|MGN1x?!aPDAV-~SSe ztttISoN=ufxcjR)Ys>b90$LYbE5kvfUJ1|IbQfBTi1jrMi?TdFRv!+sV70(ZG z7dV}RKN>fLKD8&BpC@cCo6J@%^_ zzXTWvXbUVAnf+(~EL&;Z@_-4cI;5y)6rN5|daQ0c77j6( z5ub+^v{z|vpq%*n#Gg>1tKTQ2rTvSzZ&99<@j_vs*I5;Kr@ zRoTWr?oT+vD7#|l(oiV|y9l@tSsczkpY`!+#dW~+y(yz_`MNWKQ;(` zH&{%)mhzvWfq|r~m>4M3_1&4T1&GGqSU> zH*o&(jxdRzwd!L+8rptW!}Cy_;pSNh?DwB%dD+i9tu5k$6$bPL#SR9&}u zcHW3*?7rq1TA52y1$!kFEvSs|s` z2)~$VyO$sLlB$UA)jR?rSf0$oUR-o>LBCkp=kb5&Jh{rhgBm8dqK2@0I{qvi`F$F? zA^dcXQ*=P9^+%ke%sCDw<{O1~5OA2oly!;hSNf1$>#S^!aD*Tf8^}Cnm)Z2#wfU46 zQfSqFHs{4}Hhbw!WF7od05$5t9p(GKTs%&H){Y4lsRHCr(n)`kPVqlUPtD^1K>^5j z+Ww?_>l3ZC_8&S+)mk|%iV`w@88-z5S6J|+)AXPD4j*{%aAoWp`~K|iZD@Ntq0@^H z_~!=YhUf&-_zuR-SL&)fIqs(lstB%E^8wqx4RgZ76k^74OHgbl_GVzHP>1k+Z$`IG zZ$ZzCj?e=xkrFFVb*h$|YhdM#1c0Y7X5dzed3C~Ya=||x%?6PEZTx4XTEDp;u*k-h zfXuoZ=7^26Dk{!_-ZW_~xUBJAJkv@l@*3uH!l)6u((nyq!;{xoUIj(pwBs4hmGI5> zXRr}W0^{qZ_}C;rwKk|nYOsoN-e^lm_3TEH9iELs?EG|vc!8uH@AZz*F)$co<>q;F z78(CLMeBdEm72#1!i8}3bBFpnvLX5BcK`=Cm00XYuI1)vU~g~YsORErVeRxYUtMB) zVSW-Qa{U@%(pi>Na57psvkkS*HW@QoR0z^(y>#PyoUeFgwy-HiLXN;_x0e<^BJ{e&Z*Gck}U-E^!85 ztJeDES4(z58DchL7%6z9dv;LDfZcyVX>?9boJk@`t>FZRPc@PTK||pEd6W1M!F-nf z|AFBG{^Otazs*IXWB&sVT*$RgM8Z7SDX#l0B$6vSw8pZ9gN~$Td{?KDYiKy69Q0@^ z|2HBKB|?1t^~Z_RZ2U!_tt=v48(;IENyBRfll+MUI3TKDP>`3x#-oMTmTIsNSGk2s zE@_e#9cUT$L%~I9#)HFIa7t^3uQazL>9uYOS;ZHg#a$5aAIiun2v45v8*jRC*@}xf zzpXFX0UJ{a6QQ!01K|O}9aBP9dmR6bbN2_XMe4D)s-LKoewHicf0im?swEdV><((XVnHSz1+@i(wOuCS16)qPB) zv^jx$Lwzh+Z0Y8geM{rv6=f(}CCJYJZDy+k3ztSt{ekNi$}#N`3J8cE^=G8k0fXZKv!$Lt zgOS6mhvNT>Y#TL2WlP0*0iy&wC!`+dcwJ??k=$fJ=6us-rHV1Gn%wF<(L!nMEBVAFFVJ*iL`mO&HPsfJLL(>vGL=Z#|>UXjQKR3)Ye^{jn}OJ@s(7 z{fHlLM2~@VY{BNkQckzRm!RW)x`t4}}c-ltp-ID(0d}BU;V5!ZgTg>uNN%!puI?Ax^6bd*`a6{&P<>8zTUFugk5RWfqKS0gn zFa|o1_Tw^aiVGla4{-)0cHEdkf^nE3PXLyci`BPd=!RmoRPe!pI-&ThmXInmdC@q9 zdGAC;pHdu0-1SZ3olmmp*b@g$o2cH}jM1BccLyRTo|U{PIUgbo@lJ$_bu%T3FmI1Qls{rt;PByJR>2$17Ih*7!^QI8mfxtV(+Z$OB+daI zKv@orQLX-9WSllDYFlmh6@cGf7gIIodZ0v|XiiqAGu0%lzXsMv9#n>lnaa3}W{g_( z8I!M?@4yKjNj>!W%PD|Vyn1R+?DrVla6@$)89g$81=-qLX{wstDw#&)srbsmW!lF! zQLf^4-RAQJ0j1|wSm$~QIfZlj_6kW2w_AqB54I0z1xRCAef0{ zf0c&onT&dEU?vPYt}fTkNU(NW&ILI#{my?+B!4mxL>gGJR~6;r@V*7vNx(lJk!Wgg zPb|(BN+%GY=lkwP7o(jHW3eWIiG&1$BPXT=OphUfPGv1}DF#w7SPjUD$fI+urPrW! zE4!!WE_iXB^5w=}1)BAbE7Hc2s_?;tWS`TLss{s_2Mz~fDq@EgCfa3^QlK#c^)vPm zUOSj=rP~x%Lt%`sE5ydLN?zT=D1yhc_|x_}HIi{T7dL82nc34svH`nbPs6|FIkfoB zCS)3wY+?bwXhWIQ*ABqfke$aJ_YzYxLk9Au`aM`G*IZ8P(C+IWNrFO_1{r3EkO0c~$v||<)fZcG)1bgq zLJ{FiET#XX>(Qm05PMzHm9kpR-UtSBK=z|!Db}BAUT6gc9v?W}k1xJYzP-I&UYb6R zzdb&_-=*a%t0X`@N3qBt3=b5ZlUdNOcv^yEm4D#h$>|gW>zi|ty%;E7dhpL-{*@t4 zRkl1lv;1r`jsxVSzhV)3VgtONzY8MSNNk&AbS`fy)i)S5@JXuTHy9}Z=GjBATWw!{#7M9I5L9FZ2Mjy> zyz!r^e!|%Ai6}5yq|zd2(`gJs%W}$`TD#?!^VL+qSLCK2-~mH#%xM2kLz;b#VGbw^ zwOp7CVbF(QJOh($7OMODvrbP3>WJ^eB`q*JgVqPXPyeb2DavK z=(aV0K4gYKTN-;5UQD44TTCs(mM2O1Ty@Y1I_glza5t-;Aq6CgFngNI3DZWMr4}sZl4OE5% z*u&bq4wx*f`{OCM#&Vp{BIlFX(rkl&%A;so7|-{KsP7xOj!H>3j$wZ(z^mN+>zxtq zzkKS4c6@=;{?H5>U~pHEB$w0z;Qx7?0tS~sPW#~`%G;JzpEy83`9FQaX#amEB%@HdQ)(9#^7r^a89Fj*aU*~o8mXs?LM zMp#OjpwH&HTo@Z?3+_@#f3IbGzd*7&tu0o=Pn9;CqTwTmi9TS`q0hgb>?pzu0QaTy z;T{yV)cDM$^8`-h*m0)4(}@L_q^cMt&daogNC5e~XE^sX^h_R!XUF2dN27vUxRc4$+y5{_xL zk-F|B-1ULrfSUc%aI}XI0o*3iIh8FDa4W6E@Gr=9YwEH-uEIiCZz%3Q8)nkT%rxgE zLL4e;2&}SkaWk_SMFeDvjN%y$?g*Lx=;|wMK~bPy<|vI?LUiXS4W6&3YC@j2U9=wa zw<%R#uM4s_%!Ga#BS@h@J+gDevqJ7M;|3q?BnVue_m33xB3ZcA016QnAi$aK^e*>O zWZ9DRc6EEm#ZKn+{BOw~8>gzw((to^?UJE1zw88={zME)aC#=B|Sio0eS zSqD0F3(OI-6HgTQvoIzx`f7C$b%OGEZ}`FsZK5X|eH{qvX3rZwbij^cS5B>T5i3Qr zkx*2(gPq9@xb8Dg6n2Bf?R_k@OFeq2-;{rn4)R$a01{ttvXu|e{I0ev6iwKs1PBd& zr1*`xGc7q`Zj>6G!W@!^*7`CiK`#pd9TEG(cfQ`fLd#Yv=ZEunFzggXc#gXuqi9}k zC$>Goypo^sn?mGx*BoGiecc9FYrEjRiY=%Yfr|M1t-)b4{#T6J?bBeg#l@%GM1qb& zF{R}Svdbtyf>d|d!tu^ua>c%eOa`d5LsAh<7Q!3yOZucE>SQCcRP1%Jq&pa9aTl5$~E5g@@a0r2x{Im}B@4j8>ke34~B^ z46*+p5lJ7?GCc|N0mW=kjpSIUO8;vn2^BMK%Bh5JX#&a>JKa|I@eO#|wKP}kn%WJ? z5rCZr?{<^J0i=m5Yg%qrWi}&m@0|HZqZo*91fhI>LXg`(C?(KQs}&$pnKZ>dQIt*ZJ#xTEDZ6uaBnFmYL1TiTYN{YQZ1NTIF z^v88^-&oEa3btX$#bF2Y424!k3hd0g%*d`?5h|V5?AV+@$Z9p_+{d+>;gYnVU?QQ# zk7G#O-c?__U>PAd4z-RZ&7#~pAL#2(ErPIff&en09CnVr)8O@b3AeLq@e-S8B5N;l z#XnBaAViMB%~lRly`aGHp{oFQf8&+AQs-0ip}>g&6<9CVHm`r?UYn3=RP&_a0|KyL zG!2W%YgIt}S%r02+y1na*x-JHI| ziAm)E$xUpaI{48%?PT*H*H;)EsCgF3$3W;sIBCQ4*3m<2jYPTQXUjuZgblkq9l2_o zGa<4}|McD$uS~*I&^@qLCKA(Vjyg>3{*AA}`;D$vTC1`V;cjoQeuV*lIRxepl%l+3 z|I2E>$M7%bO%2YacDR`zPyE2umW8Bw73JwU^SkuB6EwF4mfxjCNI!)F#kDb9o$TQm2?{`|DSk!|s1HW(Vs7(B<&~^8a1axb5z{ zP>IQx-_AjR-`e=J)j|_5XKMmbOiw|*%|Q{Iq6P$1!s(A(&wPsodn0}zqE%pm z=|zsTVX5o{Iem9&G7okBqf)H(ymt0`j93~fA&8)g(u|?E+EwK#;#)yLsmBE)0<=Q` z+?$anUGz+u!&HXq_AEP)`5WpSta{5;m=; z@~ypRQNc73k2sA)KXdZA_UHrdY|8VHLD+<|+5&D*8otA7Jk8Tmlcwo=WLnX6`i|9O zbeZNR!kDD%vZF|}wX`wF@yKLmQCszyECcsAzy9!6QUQ#GAeZ@UdwcIE_H{Wj6!~)l zX7rY*(M#+geOz6W3L4F+Nh%?~sVKTw(627YeAIcp>^RGdyr?l9llK7QBjTpC46=KX zXI%P&EJ&rK9&%Og%~NN%c>Ui4Ui=k3&la=PLeH&O0^xyIb9~}qkFD2+o64Fq7*}~} z#9+MIZzAGVu)J66e}61OcLu)0>wT8HHgD%DWRGIFk%*U?ER46~`Dm1o$PsP(Nxx*m zanpW}EUdlmbjy|lL|y?6Y5dpzP|~hq`YfYa3iX#SM=65>%6^HH^#ScFgp@rp0pZ-5 z$w(xl{Ku1(Ew~YepUsrq>bIDSi`B66O9zifVif{T19-0y*{khnt>hZR*|wYZf7rny zJ|%WO>U~xorM`Tlx;BceWXSKzIeU=XP(PacSV3Ej1B(u(Ff9v?eZVZx2bs#ybjdnqT z2Q_H~V-FqcZ!z!^kG;4^1Co~wvgeR@bA;hau^RbyjrDti>*u`7V&puP`a9iE&V-{| zTN=e2)7|*bymAts`rx%O?Y?vF>z8Mo;#?azU3TrJ@&y2^Ni%2}R&E1RTr7XUVkxHg zw=o*;;Yg${r)@wHk8^wD(GWP685vaV)-9(sq~!5NB5vzSSso>%2s_hT<;O?L#iEc* zB4x>rEjK7fitd7mjIdNJ_aI;f<@-o;E8p-e-m$ zRV90{O5sfhGB3~o!m*`4Qx)A+^K0|(51LSV%&Zw2?g*6|`!=%srTDqQzJm_mDgz(c;=VFqW>J2Q(W`J}YEsz+n z=wDd?KJItWGfe8FGR(dsx~7`mO9PQC91(-ckm18kJ zr5}AVHRAAv_Z;ON!*9C*u}4z0W9hid1W;j~eowH7`k#ebU)2V9s83I+ zU3m9w0;^|_`(o!l#pg_+RVPaOzC@b_*gPFi6*tE<`>x+cYG~~H%-4Q@EW1NKowfh9 zS30ipVES!nFgsCrZUI&avbcK(VjjUie=7phPi&dge!{<Zm#>O{;_GB9zd^Dk6qfBU*^H!kLx1b z^=3|LsIFVMJqA4SC6njarnr`i3qm1vU^eX&7vQx(0~UV6NlS4IYQDFp?yGAGpRtURnjau&6k9T)^Z54renp}D%v`qR zctX0+h|5UvHx2@7>CHB;ct<0tmKNIl`6{fK`musThAi``-q@g2`ZFtyD84y&YAt|8ojg* zV>&R8&>vE{*g_wtR0r1jNDRz|2(;j0Qm2Pp%r`k^mGGG+o!W&0j)`4)23)47Zh*+A6wsW**nXh2s4U6*aZB__NtFz!-%K zUqTNip<&r39f}7ZSeba3KotAu3%yl$$ugyS|2(zp%|k{(C`<|~YF!wr52U>ip9gcG5{YDyFPaz`3e+ z&_ZI;r+!)Mx~qcir|m0GGob9gh6i15^VU0Y@;7@3tPv4Z=@Qq5V}$iysS#Grd#{C6 z=p!Ur2R?L?uM4S-VTRndAF8&uWW& zH|*4*zn!fn#}MTosa53(lVWA_NfTP~+6I*NrT`Vt2iIZhmQDA-GobmaSKzI3(L%7V zXGQnKf`7@4Yhvfz`rvYBLC&W!ab;aY%SX)c1ac9Iru%&wC*iOSga2Nfj16e&6)on; zhNGdG??h7b7)U^Ju^o)RxbTI0#H{3Xp-(_oR3tA@-iR<6I`A%mW^ttLWvI-2d z_=r}=>Y*?zbycocYk+aGhbs?r(pMM<5G12UBs(aeHEdjZQquu|WuEjCYJi1zyd zlVGQl#&n`As=C&&<24SlP|k(}`}FK1Rl~dqLwve}Q4*x^aDw1dcsxChoYH zhyEt)zFg4_?gv7x43qncRgY15Y;o6I#R-Z+u5H3HbOOX{)zwhQ2<@c{dfTN~Y0i4R zQqP{od_k-A2Z#Yh3-_3R# zt{c7FoLvP+CeE^$N!+L*5gX?+=%V+@fr8AdvH(3(#X64B;sIoU_NHw)y_{yv`=YXu zN@R}$6w!6y33OIJL)XaLHv7v1^+WX%nQ1(J8*!u;qWS3)rFL15>FMe#4Lo!xua2DJ zPj@%bNRxG((&Uu*1602ql|sBE*zL0soK&zk;@mEb7c~|pT}%g&4GF^Mhf7P>`LrDc z6+l|Po=pD$O+5(9tH6T zUnIzrul?&zQ&UL~?k9}L)0*HTG5)`WCn|wO%|^>V zz^HX0yc)w*ztqEG_eb1fYLd^^!}IU=UjVjK?XOj3kWGi%3rM*iq?hZBhw=CpeD0 z&@jFg>Lp`io*Kmv?~Ax@1O6_a>t86QpT#0}ga2P)S02^WvBt^V3~SgFMYbgD5I|NJ z)_`mxi?mO`s-R-so~_^p1wBGscv?lVw0xC{K#fsw0hHD%7NPn?&;qrUqG&~{f(2AS zaYNI&xq$#yI{9PH?>FBv%e`~woXpHO?=lu=?461N5-FQy=Soy#JtnMA)BUkszxB-c zHDlgd%&xq%F=~3-3dgq_8X+#_JJHWq$Go1#70)>N`?smz@9^~I8-{WvuV&{>{N=>Y z(S?4(_U5tYH4Hp!_r#tGwvP;OE@|SPd!X?=&S2SgqhiPFs*Adg*e2cV{6S>encR^7 zzp@U;2&0Q#f1c^CSY%mO=Q1y}wj%9@(XnG!+Kw(Tyk=!R+cEd9RZwn)k#c+dnTt2N zvU!5qu|KPn?e$x;#2)c8Bvl#5d=DS~!)figmb~YmOKgL4Yt9A~1h+Zo>hgYTReK$L z%;Vzx`G2bbsC1yz_m|I$tze-zcqol~neuCjCX< z#sBoyrmoqtM00~MUB`9h`V@VB+`)Ab7ur^Jt}u-5TzF$mDsBPYAMj_F-y5{++3o z;;inJ)V+T zwByRX{MrkW_(xawvd*5Hnlk=wux8BnZM&ZHUK{gT+8aLlL)>?|^x?0Sg~xlN!-H2^ z*)3_ln7M0ln(A`yY-Jx3YBv5*58Hot_V(SqeUF38}ezW@q00heb(&Wb<`@PspXNMdGcMz8$l6Y)A>KXc6x$mKuMQ7jKi7 zdh$|r^LIB`J>J#=$?=_EnCPtjP3vt=!LC!Ee-UcQQtl~lTDyh4@y*%$*7lOB6IZ_x z-+HK&Q*CTsloYpichs`SpB&6e?YbV_wCrYzNlfFfPLO))<*Lx`64h75ahIzmJZPA^ z^h1x3m}<9fe~scciy2;@Cw(K*HmO~)rT1aMqrQ2`>HJr#-n2JtbIb8req~8-iBuc5 zn_%Np3C38L((EQXi2N`6xRU>~l$Js!567^?aG!^#q3a9a7e3YpUp}6M3>MNr0EK)! z5wTX#AR7IeD3>tBzO1bvGQ}%d8t}vv&q4KHW}ALx0LyvU2-3~4A=3GZ5O!c>g*n+z zbM-jHoh(U3&vHqL3Fw$(4|K4QR?BWE)P%J>tOJ|Oi7Kx&`_5_O?66X8xNMI(aLpWZ zQR8Vs3V>&U1!#GV%-P2l*poF03M_CWs~@^8@CV4|B@|jVe2f}PXGl$E$pj1`O^u~T*HnN$(4|!jVS_G98xm>epgzMi>a)hcCDIzOn}T(8 ztOwdda;fOH8RIE_3buz`5m*ZeZ5bxgoP|NloOF|kHL;eVp!FezW-477!9*L3A=7~f z*3&e08>H32#0F1AYdi)SAEfRx2r$&!U>6i2XN+vIJ4zHX#R;}p$a(_{=qBmRV5vZ( zEg9RONT!r8z(N!oO@k;Tk>z}77GMGYDS1fVu+X*_q_cD_l$7YZ?FW)nG;=L)vDKwTvPTyjL3H9I!DsnPH9{9jkjFNkx0!uamGE&RS!x=RZa5Rv5TB zssR$i+Xxz`Vq-g-0Tq%74u%)rPS`xFMQJQ>XZxxddOI5L!l^e9DW$&vS^D2(lYJ(@9cdx{y@c+1-~ z^5mw%$|4o?{z(SNIZju|vX##<)O>9Odt8wL#O-5da}F~B8St?d_3c1myaRTj?lOo^ z@5|MPdI!v<5_M(Te9)eVJ*nl6a+GkEH4ggS$X8|8L?R_|k@F1`u^*)$DMu!^$Op{R z5euj|hO&c%TP$_Rqp9zsWm0zV%n?tf7B7+OL^$CvZ_73;!lXY4^WZW>B0cfsyd*|wq7rEy4y z@!R7<8o57fXkmaWo=Rncf(oa&-^h`+8xEpO_sP&i$Z#WH!2|oD$_+1}&L5DoF_Z8V zbVLGKlL$NKu$)~v3CX^=9RBcwK}t&effkcoDsn1?afX^vRgRf9C|sFnPTr zGWp4h11UqF*>?_74Ab3vl<`H*Rp`=hJcmyoC7?yfnG0DW5n%?CRCMncBd+y%5 zHBeHr92BIRVS1bqCF>7k{_rjRBSl}zMZJQ^ppc~oha!9D!O;vGp?f8amAEjZ34Aj7 z^M`MuA8E>}R3^`sg(auIKKysKrw^;8P8k%sV=nVn?DHm%0y=@)M<9y_knW2^kZ(Jf`r&cV>PyxRiTpRL$ zK0o5fHjJW?ErdF^HFo2Gb09W>e9UGZP53c@teWO(G4!hdvRcyAra?G5IG)bAus@Kj z>^?SSBpwG6iR)Gj@DCzDY|8*`bG9akgNPHcP|mos)u4}NEMplaE1EFVg9&51l414) zV>h%qnE|&FNpTlld|(Td%^mAOhfqDd~)T|f7X;rB2W~;#J2x8m4f3Qp)&P9+R zOdrZTenvXWekSIq4IX*`znOR(C3?$-#^-E9zo9z}!vkme1^CVK8#>R>dTSrlb}qV7iH+%9ja?+C7OM{OWP9TT5JqB-={tKIhnOlCwaQg&hSrGL Y^B5V5m1)@m^7AG^C#@{Vo##q_19*Fo-T(jq delta 35544 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 Vl|Wgo1>r6FmePvlu~Do>;eXBJok;)y diff --git a/orchestrators_structure_proposal.txt b/orchestrators_structure_proposal.txt new file mode 100644 index 00000000..3224005b --- /dev/null +++ b/orchestrators_structure_proposal.txt @@ -0,0 +1,58 @@ +Proposed tree (orchestrators grouped by domain) + +ryan_library/ +├── orchestrators/ +│ ├── __init__.py +│ ├── py.typed +│ ├── gdal/ +│ │ ├── __init__.py +│ │ ├── py.typed +│ │ └── gdal_flood_extent.py +│ ├── tuflow/ +│ │ ├── __init__.py +│ │ ├── closure_durations.py +│ │ ├── peak_check_po_csvs.py +│ │ ├── po_combine.py +│ │ ├── pomm_combine.py +│ │ ├── pomm_max_items.py +│ │ ├── tuflow_culverts_merge.py +│ │ ├── tuflow_culverts_mean.py +│ │ ├── tuflow_culverts_timeseries.py +│ │ ├── tuflow_logsummary.py +│ │ ├── tuflow_results_styling.py +│ │ └── tuflow_timeseries_stability.py +│ └── rorb/ +│ ├── __init__.py +│ └── closure_durations.py +├── functions/ +│ └── wrapper_utils.py +└── scripts/ + ├── __init__.py (compat shim -> orchestrators) + ├── py.typed (compat shim package marker) + ├── wrapper_utils.py (compat shim -> functions) + ├── gdal/ + │ ├── __init__.py (compat shim -> orchestrators.gdal) + │ ├── py.typed + │ └── gdal_flood_extent.py (compat shim) + ├── tuflow/ + │ ├── __init__.py (compat shim -> orchestrators.tuflow) + │ ├── closure_durations.py (compat shim) + │ ├── peak_check_po_csvs.py (compat shim) + │ ├── po_combine.py (compat shim) + │ ├── pomm_combine.py (compat shim) + │ ├── pomm_max_items.py (compat shim) + │ ├── tuflow_culverts_merge.py (compat shim) + │ ├── tuflow_culverts_mean.py (compat shim) + │ ├── tuflow_culverts_timeseries.py (compat shim) + │ ├── tuflow_logsummary.py (compat shim) + │ ├── tuflow_results_styling.py (compat shim) + │ └── tuflow_timeseries_stability.py (compat shim) + └── rorb/ + ├── __init__.py (compat shim -> orchestrators.rorb) + └── closure_durations.py (compat shim) + +Notes +- All functional modules live in ryan_library/orchestrators. +- ryan_library/functions/wrapper_utils.py holds shared wrapper utilities. +- ryan_library/scripts becomes compatibility-only until 31/12/2026 with DeprecationWarning notices. +- Orchestrators are grouped by domain (gdal, tuflow, rorb). diff --git a/ryan-scripts/12D-python/thin-raster-terrain-for-12D_v5.py b/ryan-scripts/12D-python/thin-raster-terrain-for-12D_v5.py index 92167dc3..b51e8ea1 100644 --- a/ryan-scripts/12D-python/thin-raster-terrain-for-12D_v5.py +++ b/ryan-scripts/12D-python/thin-raster-terrain-for-12D_v5.py @@ -13,7 +13,7 @@ from loguru import logger from ryan_library.functions.loguru_helpers import setup_logger, worker_initializer from ryan_library.functions.file_utils import ensure_output_directory -from ryan_library.scripts.wrapper_utils import print_library_version +from ryan_library.functions.wrapper_utils import print_library_version def thin_data_by_global_selection(df: pd.DataFrame, thinning_factor: int) -> pd.DataFrame: diff --git a/ryan-scripts/12D-python/tif-to-LAS-valid-only_v6.py b/ryan-scripts/12D-python/tif-to-LAS-valid-only_v6.py index f33c318c..ec97bdfc 100644 --- a/ryan-scripts/12D-python/tif-to-LAS-valid-only_v6.py +++ b/ryan-scripts/12D-python/tif-to-LAS-valid-only_v6.py @@ -6,7 +6,7 @@ import numpy as np from ryan_library.functions.loguru_helpers import setup_logger from ryan_library.functions.terrain_processing import parallel_process_multiple_terrain -from ryan_library.scripts.wrapper_utils import print_library_version +from ryan_library.functions.wrapper_utils import print_library_version def save_tile_las(tile_df, output_dir, base_filename, i, j) -> None: diff --git a/ryan-scripts/RORB-python/RORB-find-closure-durations.py b/ryan-scripts/RORB-python/RORB-find-closure-durations.py index 6d89c3b4..34305e1e 100644 --- a/ryan-scripts/RORB-python/RORB-find-closure-durations.py +++ b/ryan-scripts/RORB-python/RORB-find-closure-durations.py @@ -6,8 +6,8 @@ import os from pathlib import Path -from ryan_library.scripts.RORB.closure_durations import run_closure_durations -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.rorb.closure_durations import run_closure_durations +from ryan_library.functions.wrapper_utils import ( change_working_directory, print_library_version, ) diff --git a/ryan-scripts/TUFLOW-python/LogSummary.py b/ryan-scripts/TUFLOW-python/LogSummary.py index d19acd90..00bd5494 100644 --- a/ryan-scripts/TUFLOW-python/LogSummary.py +++ b/ryan-scripts/TUFLOW-python/LogSummary.py @@ -12,8 +12,8 @@ from pathlib import Path import os -from ryan_library.scripts.tuflow.tuflow_logsummary import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.tuflow_logsummary import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/POMM-mean-max-aep-dur.py b/ryan-scripts/TUFLOW-python/POMM-mean-max-aep-dur.py index d8f15701..559ba37e 100644 --- a/ryan-scripts/TUFLOW-python/POMM-mean-max-aep-dur.py +++ b/ryan-scripts/TUFLOW-python/POMM-mean-max-aep-dur.py @@ -29,8 +29,8 @@ import gc import os -from ryan_library.scripts.tuflow.pomm_max_items import export_mean_peak_report -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.pomm_max_items import export_mean_peak_report +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, PommPeakWrapperDefaults, add_common_cli_arguments, diff --git a/ryan-scripts/TUFLOW-python/POMM-med-max-aep-dur.py b/ryan-scripts/TUFLOW-python/POMM-med-max-aep-dur.py index 59b64787..242db38c 100644 --- a/ryan-scripts/TUFLOW-python/POMM-med-max-aep-dur.py +++ b/ryan-scripts/TUFLOW-python/POMM-med-max-aep-dur.py @@ -30,8 +30,8 @@ import gc import os -from ryan_library.scripts.tuflow.pomm_max_items import export_median_peak_report -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.pomm_max_items import export_median_peak_report +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, PommPeakWrapperDefaults, add_common_cli_arguments, diff --git a/ryan-scripts/TUFLOW-python/POMM_combine.py b/ryan-scripts/TUFLOW-python/POMM_combine.py index c0f7c447..0406ef23 100644 --- a/ryan-scripts/TUFLOW-python/POMM_combine.py +++ b/ryan-scripts/TUFLOW-python/POMM_combine.py @@ -2,7 +2,7 @@ """ Wrapper Script: Combine TUFLOW POMM Results. -This script acts as a mutable wrapper for `ryan_library.scripts.tuflow.pomm_combine`. +This script acts as a mutable wrapper for `ryan_library.orchestrators.tuflow.pomm_combine`. It manages the combination of "POMM" (Plot Output Maximums/Minimums) data, primarily used for culvert peak analysis. Users can edit hard-coded defaults in this file or use CLI arguments to control the execution. @@ -31,8 +31,8 @@ import gc import os -from ryan_library.scripts.tuflow.pomm_combine import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.pomm_combine import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/PO_combine.py b/ryan-scripts/TUFLOW-python/PO_combine.py index 320aea22..cdb4b5fd 100644 --- a/ryan-scripts/TUFLOW-python/PO_combine.py +++ b/ryan-scripts/TUFLOW-python/PO_combine.py @@ -2,7 +2,7 @@ """ Wrapper Script: Combine TUFLOW PO Results. -This script acts as a mutable wrapper for `ryan_library.scripts.tuflow.po_combine`. +This script acts as a mutable wrapper for `ryan_library.orchestrators.tuflow.po_combine`. It allows users to hard-code default configurations for merging TUFLOW "PO" (Plot Output) CSV files, while still providing command-line overrides for automation/batch processing. @@ -31,8 +31,8 @@ import gc import os -from ryan_library.scripts.tuflow.po_combine import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.po_combine import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/TUFLOW-find-closure-durations.py b/ryan-scripts/TUFLOW-python/TUFLOW-find-closure-durations.py index f3732608..44cc1162 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW-find-closure-durations.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW-find-closure-durations.py @@ -22,8 +22,8 @@ import os -from ryan_library.scripts.tuflow.closure_durations import run_closure_durations -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.closure_durations import run_closure_durations +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert-mean-max-aep-dur.py b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert-mean-max-aep-dur.py index 4017346d..d22d4da1 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert-mean-max-aep-dur.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert-mean-max-aep-dur.py @@ -23,8 +23,8 @@ import gc import os -from ryan_library.scripts.tuflow.tuflow_culverts_mean import run_culvert_mean_report -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.tuflow_culverts_mean import run_culvert_mean_report +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Maximums.py b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Maximums.py index cb0143cf..eff9c63a 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Maximums.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Maximums.py @@ -21,8 +21,8 @@ import gc import os -from ryan_library.scripts.tuflow.tuflow_culverts_merge import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.tuflow_culverts_merge import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Timeseries.py b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Timeseries.py index 16267dca..295944f9 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Timeseries.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Culvert_Timeseries.py @@ -21,8 +21,8 @@ import gc import os -from ryan_library.scripts.tuflow.tuflow_culverts_timeseries import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.tuflow_culverts_timeseries import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/set_layer_to_filename_v6.py b/ryan-scripts/TUFLOW-python/TUFLOW_GPKG_rename_layer_to_filename.py similarity index 69% rename from ryan-scripts/TUFLOW-python/set_layer_to_filename_v6.py rename to ryan-scripts/TUFLOW-python/TUFLOW_GPKG_rename_layer_to_filename.py index e83bb175..36f554fc 100644 --- a/ryan-scripts/TUFLOW-python/set_layer_to_filename_v6.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_GPKG_rename_layer_to_filename.py @@ -1,7 +1,8 @@ -# ryan-scripts\TUFLOW-python\set_layer_to_filename_v5.py -# 250913 +# TUFLOW_GPKG_rename_layer_to_filename.py +# 20241011 from collections.abc import Iterator from pathlib import Path +import argparse import geopandas as gpd import pyogrio import shutil @@ -9,6 +10,9 @@ from colorama import init, Fore, Style import sys +SCRIPT_NAME: str = "TUFLOW_GPKG_rename_layer_to_filename" +LAST_UPDATED: str = "2024-10-11" + # === Configuration === # Toggle to search subfolders recursively underneath the Python file. SEARCH_RECURSIVELY: bool = False # Set True to scan all nested folders under the script directory. @@ -42,18 +46,16 @@ def press_any_key(prompt: str = "Press any key to exit...") -> None: pass -# Initialization function to set up environment and return colors -def initialize(target_dir: str | None = None) -> tuple[Path, str, str]: +# Initialization function to set up environment and return colours +def initialize(target_dir: str | None = None) -> tuple[Path, str, str, str]: """ - Returns the base directory to process, plus colours. - - If target_dir is provided, use it (must be a drive-letter path if you plan to chdir). + Returns the base directory plus colours. + - If target_dir is provided, use it (supports drive-letter paths). - Else use the script's folder, keeping the Q: form by using .absolute(), not .resolve(). """ - # Initialize colorama for Windows support init() base: Path = Path(target_dir).expanduser() if target_dir else Path(__file__).absolute().parent - # Return success and failure colors - return base, Fore.GREEN, Fore.RED + return base, Fore.GREEN, Fore.RED, Fore.CYAN # Helper function to check if we should skip the file @@ -67,9 +69,11 @@ def should_skip_file(layers: list[list[str]], gpkg: str, fail_colour: str) -> bo # Helper function to check if renaming is needed -def is_layer_name_correct(old_layer_name: str, new_layer_name: str, gpkg: str, success_colour: str) -> bool: +def is_layer_name_correct( + old_layer_name: str, new_layer_name: str, gpkg: str, skip_colour: str +) -> bool: if old_layer_name == new_layer_name: - print_colored(message=f"Skipping {gpkg} as the layer name is already correct.", color=success_colour) + print_colored(message=f"Skipping {gpkg} as the layer name is already correct.", color=skip_colour) return True return False @@ -105,7 +109,9 @@ def rename_layer_in_geopackage( # Function to process all GeoPackage files in the directory -def process_geopackage_files(base_dir: Path, success_colour: str, fail_colour: str) -> None: +def process_geopackage_files( + base_dir: Path, success_colour: str, fail_colour: str, skip_colour: str +) -> None: # No chdir needed; operate with absolute paths to avoid UNC/cwd issues entirely # Loop over all .gpkg files in the current directory # (If SEARCH_RECURSIVELY is True, this will search all subfolders as well.) @@ -123,7 +129,10 @@ def process_geopackage_files(base_dir: Path, success_colour: str, fail_colour: s new_layer_name: str = gpkg_path.stem old_layer_name: str = layers[0][0] if is_layer_name_correct( - old_layer_name=old_layer_name, new_layer_name=new_layer_name, gpkg=gpkg, success_colour=success_colour + old_layer_name=old_layer_name, + new_layer_name=new_layer_name, + gpkg=gpkg, + skip_colour=skip_colour, ): continue @@ -137,23 +146,43 @@ def process_geopackage_files(base_dir: Path, success_colour: str, fail_colour: s ) -# Main function to execute the script -def main() -> None: - # OPTION A: Use the script's folder (keeps Q: if you launched it that way) - base_dir, success_colour, fail_colour = initialize() +# CLI helpers +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser( + description="Rename single layers in GeoPackages so the layer matches the file name." + ) + parser.add_argument( + "-t", + "--target", + help="Optional target folder; defaults to the script location when omitted.", + type=str, + ) + return parser.parse_args() - # OPTION B: Explicitly target a folder (drive-letter path); uncomment and set if desired - # base_dir, success_colour, fail_colour = initialize( - # r"Q:\BGER\PER\RP20180.387 WYLOO NANUTARRA ACCESS ROAD - FMG\TUFLOW_Metawandy\model" - # ) - # If you really want to change cwd (not required), only chdir to a drive-letter path: - # if base_dir.drive: # e.g., 'Q:' - # os.chdir(base_dir) +def announce_start(base_dir: Path, target_dir: str | None, info_colour: str) -> None: + target_label = "script folder" if target_dir is None else f"target {target_dir}" + print_colored( + message=( + f"{SCRIPT_NAME} · Last updated {LAST_UPDATED} · working directory {base_dir} ({target_label})" + ), + color=info_colour, + ) + - process_geopackage_files(base_dir=base_dir, success_colour=success_colour, fail_colour=fail_colour) +# Main function to execute the script +def main() -> None: + args = parse_args() + base_dir, success_colour, fail_colour, skip_colour = initialize(args.target) + announce_start(base_dir=base_dir, target_dir=args.target, info_colour=skip_colour) + + process_geopackage_files( + base_dir=base_dir, + success_colour=success_colour, + fail_colour=fail_colour, + skip_colour=skip_colour, + ) - # Wait for user input before exiting (Windows only) if sys.platform == "win32": press_any_key() diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Results_Styling.py b/ryan-scripts/TUFLOW-python/TUFLOW_Results_Styling.py index 9625c8b0..f31be617 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Results_Styling.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Results_Styling.py @@ -2,7 +2,7 @@ """ Wrapper Script: TUFLOW Results Styling. -This script acts as a mutable wrapper for `ryan_library.scripts.tuflow.tuflow_results_styling`. +This script acts as a mutable wrapper for `ryan_library.orchestrators.tuflow.tuflow_results_styling`. It applies QGIS styles (.qml) to TUFLOW results (rasters/vectors) found in the target directory. Users can define custom QML overrides in the `user_qml_overrides` dictionary within this file. """ @@ -14,13 +14,13 @@ from loguru import logger from ryan_library.functions.loguru_helpers import setup_logger -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.functions.wrapper_utils import ( change_working_directory, print_library_version, ) # Now import the TUFLOWResultsStyler class -from ryan_library.scripts.tuflow.tuflow_results_styling import TUFLOWResultsStyler +from ryan_library.orchestrators.tuflow.tuflow_results_styling import TUFLOWResultsStyler # User Overrides: Define your custom QML paths here user_qml_overrides: dict[str, str] = { diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Peaks_Check.py b/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Peaks_Check.py index ee6f1005..c95a8ef1 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Peaks_Check.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Peaks_Check.py @@ -3,7 +3,7 @@ Wrapper Script: Peak checks for TUFLOW PO CSV files. This wrapper exposes hard-coded defaults for quick edits while delegating the heavy -lifting to ``ryan_library.scripts.tuflow.peak_check_po_csvs``. +lifting to ``ryan_library.orchestrators.tuflow.peak_check_po_csvs``. """ from pathlib import Path @@ -12,8 +12,8 @@ import gc import os -from ryan_library.scripts.tuflow.peak_check_po_csvs import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.peak_check_po_csvs import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Stability.py b/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Stability.py index 73efe1d7..e30abd95 100644 --- a/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Stability.py +++ b/ryan-scripts/TUFLOW-python/TUFLOW_Timeseries_Stability.py @@ -11,8 +11,8 @@ import gc import os -from ryan_library.scripts.tuflow.tuflow_timeseries_stability import main_processing -from ryan_library.scripts.wrapper_utils import ( +from ryan_library.orchestrators.tuflow.tuflow_timeseries_stability import main_processing +from ryan_library.functions.wrapper_utils import ( CommonWrapperOptions, add_common_cli_arguments, change_working_directory, diff --git a/ryan-scripts/gdal-python/GDAL_Flood_Extent.py b/ryan-scripts/gdal-python/GDAL_Flood_Extent.py index 40b4f673..035a1e43 100644 --- a/ryan-scripts/gdal-python/GDAL_Flood_Extent.py +++ b/ryan-scripts/gdal-python/GDAL_Flood_Extent.py @@ -3,7 +3,7 @@ from pathlib import Path import os import sys -from ryan_library.scripts.gdal.gdal_flood_extent import main_processing +from ryan_library.orchestrators.gdal.gdal_flood_extent import main_processing def main(): diff --git a/ryan-scripts/misc-python/ss/RFFE_Only_v5.py b/ryan-scripts/misc-python/ss/RFFE_Only_v5.py index 85cd1d94..f8b0633e 100644 --- a/ryan-scripts/misc-python/ss/RFFE_Only_v5.py +++ b/ryan-scripts/misc-python/ss/RFFE_Only_v5.py @@ -23,7 +23,7 @@ from pandas import DataFrame from ryan_library.functions.loguru_helpers import setup_logger from loguru import logger -from ryan_library.scripts.wrapper_utils import print_library_version +from ryan_library.functions.wrapper_utils import print_library_version # ─── Constants ──────────────────────────────────────────────────────────────── DEFAULT_INPUT_DIR: Final[Path] = Path(r"C:\Temp\tester") diff --git a/ryan_library/__init__.py b/ryan_library/__init__.py index 8e7a251a..f325e64e 100644 --- a/ryan_library/__init__.py +++ b/ryan_library/__init__.py @@ -1,3 +1,4 @@ from .functions import * +from .orchestrators import * from .scripts import * from .processors import * diff --git a/ryan_library/functions/tuflow/notebook_helpers.py b/ryan_library/functions/tuflow/notebook_helpers.py index 81d9730d..affce972 100644 --- a/ryan_library/functions/tuflow/notebook_helpers.py +++ b/ryan_library/functions/tuflow/notebook_helpers.py @@ -11,7 +11,7 @@ from ryan_library.functions.tuflow.tuflow_common import collect_files, process_files_in_parallel, process_file from ryan_library.processors.tuflow.base_processor import BaseProcessor from ryan_library.processors.tuflow.processor_collection import ProcessorCollection -from ryan_library.scripts.tuflow.tuflow_culverts_mean import find_culvert_aep_dur_mean, find_culvert_aep_mean_max +from ryan_library.orchestrators.tuflow.tuflow_culverts_mean import find_culvert_aep_dur_mean, find_culvert_aep_mean_max import pandas as pd import matplotlib.pyplot as plt diff --git a/ryan_library/functions/wrapper_utils.py b/ryan_library/functions/wrapper_utils.py new file mode 100644 index 00000000..b88bb9cb --- /dev/null +++ b/ryan_library/functions/wrapper_utils.py @@ -0,0 +1,146 @@ +"""Utility functions shared by wrapper scripts.""" + +from argparse import ArgumentParser, Namespace +from collections.abc import Collection +from dataclasses import dataclass +import os +from pathlib import Path +from typing import Protocol, Sequence +from importlib.metadata import PackageNotFoundError, version + + +@dataclass(slots=True) +class CommonWrapperOptions: + """Container for CLI-provided overrides that most wrappers share.""" + + console_log_level: str | None = None + data_types: tuple[str, ...] | None = None + locations_to_include: tuple[str, ...] | None = None + working_directory: Path | None = None + + +class PeakReportExporter(Protocol): + """Callable signature for POMM peak report exporters.""" + + def __call__( + self, + *, + script_directory: Path, + log_level: str, + include_pomm: bool, + locations_to_include: Collection[str] | None, + include_data_types: Collection[str] | None, + ) -> None: ... + + +@dataclass(slots=True, frozen=True) +class PommPeakWrapperDefaults: + """Default configuration values for POMM peak report wrappers.""" + + console_log_level: str + include_pomm: bool + include_data_types: tuple[str, ...] + locations_to_include: tuple[str, ...] + working_directory: Path + + +def change_working_directory(target_dir: Path) -> bool: + """Change the working directory and handle failures.""" + try: + os.chdir(target_dir) + print(f"Current Working Directory: {Path.cwd()}") + except OSError as exc: + print(f"Failed to change working directory to {target_dir}: {exc}") + if os.name == "nt": + os.system("PAUSE") + return False + return True + + +def print_library_version(package_name: str = "ryan_functions") -> None: + """Display the installed version of *package_name* if available.""" + try: + print(f"{package_name} version: {version(distribution_name=package_name)}") + except PackageNotFoundError: + print(f"{package_name} version: unknown") + + +def add_common_cli_arguments(parser: ArgumentParser) -> None: + """Inject shared CLI arguments that most wrappers support.""" + parser.add_argument( + "--console-log-level", + dest="console_log_level", + help="Set log verbosity (e.g., INFO or DEBUG). Defaults to the script value.", + ) + parser.add_argument( + "--data-types", + nargs="+", + metavar="TYPE", + help="Override the data types to load (e.g., POMM RLL_Qmx). Defaults to the script value.", + ) + parser.add_argument( + "--locations", + nargs="+", + metavar="LOCATION", + help="Limit processing to one or more PO/Location/Channel identifiers.", + ) + parser.add_argument( + "--working-directory", + type=Path, + help="Directory to process instead of the script's location.", + ) + + +def parse_common_cli_arguments(args: Namespace) -> CommonWrapperOptions: + """Map argparse results to :class:`CommonWrapperOptions`.""" + locations_argument = getattr(args, "locations", None) + data_types_argument = getattr(args, "data_types", None) + return CommonWrapperOptions( + console_log_level=getattr(args, "console_log_level", None), + data_types=_coerce_sequence_argument(raw_values=data_types_argument), + locations_to_include=_coerce_locations_argument(raw_locations=locations_argument), + working_directory=getattr(args, "working_directory", None), + ) + + +def run_pomm_peak_report_wrapper( + *, + exporter: PeakReportExporter, + defaults: PommPeakWrapperDefaults, + overrides: CommonWrapperOptions, +) -> None: + """Run a POMM peak report wrapper using common defaults and CLI overrides.""" + print_library_version() + + script_directory: Path = overrides.working_directory or defaults.working_directory + if not change_working_directory(target_dir=script_directory): + return + + effective_console_log_level: str = overrides.console_log_level or defaults.console_log_level + effective_data_types: tuple[str, ...] | None = overrides.data_types or defaults.include_data_types or None + effective_locations: tuple[str, ...] | None = ( + overrides.locations_to_include if overrides.locations_to_include else (defaults.locations_to_include or None) + ) + + exporter( + script_directory=script_directory, + log_level=effective_console_log_level, + include_pomm=defaults.include_pomm, + locations_to_include=effective_locations, + include_data_types=list(effective_data_types) if effective_data_types else None, + ) + print() + print_library_version() + + +def _coerce_locations_argument( + raw_locations: Sequence[str] | None, +) -> tuple[str, ...] | None: + return _coerce_sequence_argument(raw_values=raw_locations) + + +def _coerce_sequence_argument(raw_values: Sequence[str] | None) -> tuple[str, ...] | None: + if not raw_values: + return None + normalized: tuple[str, ...] = tuple(value.strip() for value in raw_values if value.strip()) + return normalized or None diff --git a/ryan_library/orchestrators/__init__.py b/ryan_library/orchestrators/__init__.py new file mode 100644 index 00000000..367b555d --- /dev/null +++ b/ryan_library/orchestrators/__init__.py @@ -0,0 +1,7 @@ +"""Orchestrators that coordinate library workflows.""" + +from . import gdal +from . import rorb +from . import tuflow + +__all__: list[str] = ["gdal", "rorb", "tuflow"] diff --git a/ryan_library/orchestrators/gdal/__init__.py b/ryan_library/orchestrators/gdal/__init__.py new file mode 100644 index 00000000..a7e4957a --- /dev/null +++ b/ryan_library/orchestrators/gdal/__init__.py @@ -0,0 +1 @@ +"""GDAL orchestrators.""" diff --git a/ryan_library/scripts/gdal/gdal_flood_extent.py b/ryan_library/orchestrators/gdal/gdal_flood_extent.py similarity index 98% rename from ryan_library/scripts/gdal/gdal_flood_extent.py rename to ryan_library/orchestrators/gdal/gdal_flood_extent.py index 300cb54c..67fb3089 100644 --- a/ryan_library/scripts/gdal/gdal_flood_extent.py +++ b/ryan_library/orchestrators/gdal/gdal_flood_extent.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/gdal/gdal_flood_extent.py +# ryan_library/orchestrators/gdal/gdal_flood_extent.py import os from pathlib import Path diff --git a/ryan_library/scripts/RORB/__init__.py b/ryan_library/orchestrators/gdal/py.typed similarity index 100% rename from ryan_library/scripts/RORB/__init__.py rename to ryan_library/orchestrators/gdal/py.typed diff --git a/ryan_library/orchestrators/py.typed b/ryan_library/orchestrators/py.typed new file mode 100644 index 00000000..e69de29b diff --git a/ryan_library/orchestrators/rorb/__init__.py b/ryan_library/orchestrators/rorb/__init__.py new file mode 100644 index 00000000..5d78e240 --- /dev/null +++ b/ryan_library/orchestrators/rorb/__init__.py @@ -0,0 +1 @@ +"""RORB orchestrators.""" diff --git a/ryan_library/scripts/RORB/closure_durations.py b/ryan_library/orchestrators/rorb/closure_durations.py similarity index 98% rename from ryan_library/scripts/RORB/closure_durations.py rename to ryan_library/orchestrators/rorb/closure_durations.py index 68a9310c..c161131a 100644 --- a/ryan_library/scripts/RORB/closure_durations.py +++ b/ryan_library/orchestrators/rorb/closure_durations.py @@ -1,4 +1,4 @@ -# ryan_library\scripts\RORB\closure_durations.py +# ryan_library\orchestrators\rorb\closure_durations.py from datetime import datetime from pathlib import Path diff --git a/ryan_library/orchestrators/tuflow/__init__.py b/ryan_library/orchestrators/tuflow/__init__.py new file mode 100644 index 00000000..bd006804 --- /dev/null +++ b/ryan_library/orchestrators/tuflow/__init__.py @@ -0,0 +1 @@ +"""TUFLOW orchestrators.""" diff --git a/ryan_library/scripts/tuflow/closure_durations.py b/ryan_library/orchestrators/tuflow/closure_durations.py similarity index 98% rename from ryan_library/scripts/tuflow/closure_durations.py rename to ryan_library/orchestrators/tuflow/closure_durations.py index 9c604503..f6376e41 100644 --- a/ryan_library/scripts/tuflow/closure_durations.py +++ b/ryan_library/orchestrators/tuflow/closure_durations.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/closure_durations.py +# ryan_library/orchestrators/tuflow/closure_durations.py """Orchestrator for computing closure durations from TUFLOW PO processors. This script: diff --git a/ryan_library/scripts/tuflow/peak_check_po_csvs.py b/ryan_library/orchestrators/tuflow/peak_check_po_csvs.py similarity index 98% rename from ryan_library/scripts/tuflow/peak_check_po_csvs.py rename to ryan_library/orchestrators/tuflow/peak_check_po_csvs.py index 3d9272bd..ab079ada 100644 --- a/ryan_library/scripts/tuflow/peak_check_po_csvs.py +++ b/ryan_library/orchestrators/tuflow/peak_check_po_csvs.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/peak_check_po_csvs.py +# ryan_library/orchestrators/tuflow/peak_check_po_csvs.py """ Peak checks for TUFLOW PO timeseries CSVs. diff --git a/ryan_library/scripts/tuflow/po_combine.py b/ryan_library/orchestrators/tuflow/po_combine.py similarity index 100% rename from ryan_library/scripts/tuflow/po_combine.py rename to ryan_library/orchestrators/tuflow/po_combine.py diff --git a/ryan_library/scripts/tuflow/pomm_combine.py b/ryan_library/orchestrators/tuflow/pomm_combine.py similarity index 100% rename from ryan_library/scripts/tuflow/pomm_combine.py rename to ryan_library/orchestrators/tuflow/pomm_combine.py diff --git a/ryan_library/scripts/tuflow/pomm_max_items.py b/ryan_library/orchestrators/tuflow/pomm_max_items.py similarity index 99% rename from ryan_library/scripts/tuflow/pomm_max_items.py rename to ryan_library/orchestrators/tuflow/pomm_max_items.py index b6aad58b..fc9bcabe 100644 --- a/ryan_library/scripts/tuflow/pomm_max_items.py +++ b/ryan_library/orchestrators/tuflow/pomm_max_items.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/pomm_max_items.py +# ryan_library/orchestrators/pomm_max_items.py """ POMM Peak Reporting Utilities. diff --git a/ryan_library/scripts/tuflow/tuflow_culverts_mean.py b/ryan_library/orchestrators/tuflow/tuflow_culverts_mean.py similarity index 100% rename from ryan_library/scripts/tuflow/tuflow_culverts_mean.py rename to ryan_library/orchestrators/tuflow/tuflow_culverts_mean.py diff --git a/ryan_library/scripts/tuflow/tuflow_culverts_merge.py b/ryan_library/orchestrators/tuflow/tuflow_culverts_merge.py similarity index 98% rename from ryan_library/scripts/tuflow/tuflow_culverts_merge.py rename to ryan_library/orchestrators/tuflow/tuflow_culverts_merge.py index 49a0cd28..e6342c47 100644 --- a/ryan_library/scripts/tuflow/tuflow_culverts_merge.py +++ b/ryan_library/orchestrators/tuflow/tuflow_culverts_merge.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/tuflow_culverts_merge.py +# ryan_library/orchestrators/tuflow/tuflow_culverts_merge.py """ Merge TUFLOW Culvert Maximums. diff --git a/ryan_library/scripts/tuflow/tuflow_culverts_timeseries.py b/ryan_library/orchestrators/tuflow/tuflow_culverts_timeseries.py similarity index 98% rename from ryan_library/scripts/tuflow/tuflow_culverts_timeseries.py rename to ryan_library/orchestrators/tuflow/tuflow_culverts_timeseries.py index 2b1583dc..8c8a58cc 100644 --- a/ryan_library/scripts/tuflow/tuflow_culverts_timeseries.py +++ b/ryan_library/orchestrators/tuflow/tuflow_culverts_timeseries.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/tuflow_culverts_timeseries.py +# ryan_library/orchestrators/tuflow/tuflow_culverts_timeseries.py """ Merge TUFLOW Culvert Timeseries. diff --git a/ryan_library/scripts/tuflow/tuflow_logsummary.py b/ryan_library/orchestrators/tuflow/tuflow_logsummary.py similarity index 99% rename from ryan_library/scripts/tuflow/tuflow_logsummary.py rename to ryan_library/orchestrators/tuflow/tuflow_logsummary.py index d3c2e9bf..498b6a47 100644 --- a/ryan_library/scripts/tuflow/tuflow_logsummary.py +++ b/ryan_library/orchestrators/tuflow/tuflow_logsummary.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/tuflow_logsummary.py +# ryan_library/orchestrators/tuflow/tuflow_logsummary.py """ TUFLOW Log Summary. diff --git a/ryan_library/scripts/tuflow/tuflow_results_styling.py b/ryan_library/orchestrators/tuflow/tuflow_results_styling.py similarity index 98% rename from ryan_library/scripts/tuflow/tuflow_results_styling.py rename to ryan_library/orchestrators/tuflow/tuflow_results_styling.py index 2233e196..2ea9a25b 100644 --- a/ryan_library/scripts/tuflow/tuflow_results_styling.py +++ b/ryan_library/orchestrators/tuflow/tuflow_results_styling.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/tuflow_results_styling.py +# ryan_library/orchestrators/tuflow/tuflow_results_styling.py """ TUFLOW Results Styling. @@ -43,7 +43,7 @@ class TUFLOWResultsStyler: def __init__(self, user_qml_overrides: dict[str, str] | None = None) -> None: """Initializes the TUFLOWResultsStyler with default styles path and user overrides.""" - # __file__ resolves to ryan_library/scripts/tuflow/tuflow_results_styling.py + # __file__ resolves to ryan_library/orchestrators/tuflow/tuflow_results_styling.py # We need the repository root to locate QML files under QGIS-Styles/TUFLOW self.default_styles_path: Path = Path(__file__).absolute().parents[3] / "QGIS-Styles" / "TUFLOW" logger.debug("Default styles path: {}", self.default_styles_path) @@ -158,7 +158,7 @@ def process_gpkg(self, filename: str, layer_name: str, current_path: Path, qml_p ) styles: list[tuple[str, str]] = cursor.fetchall() - for style_name, style_qml in styles: + for style_name, _style_qml in styles: logger.info( f"Applying style '{style_name}' to layer '{layer_name}'", ) diff --git a/ryan_library/scripts/tuflow/tuflow_timeseries_stability.py b/ryan_library/orchestrators/tuflow/tuflow_timeseries_stability.py similarity index 98% rename from ryan_library/scripts/tuflow/tuflow_timeseries_stability.py rename to ryan_library/orchestrators/tuflow/tuflow_timeseries_stability.py index cb222076..00d5f4cb 100644 --- a/ryan_library/scripts/tuflow/tuflow_timeseries_stability.py +++ b/ryan_library/orchestrators/tuflow/tuflow_timeseries_stability.py @@ -1,4 +1,4 @@ -# ryan_library/scripts/tuflow/tuflow_timeseries_stability.py +# ryan_library/orchestrators/tuflow/tuflow_timeseries_stability.py """ Timeseries stability checks for TUFLOW outputs. diff --git a/ryan_library/scripts/__init__.py b/ryan_library/scripts/__init__.py index 69131995..3679ba0e 100644 --- a/ryan_library/scripts/__init__.py +++ b/ryan_library/scripts/__init__.py @@ -1,10 +1,43 @@ -"""Convenience imports for script entry points.""" +"""Compatibility imports for legacy script entry points.""" + +from __future__ import annotations -from importlib import import_module import sys -# Expose relocated TUFLOW scripts at this package level for backward compatibility -_tuflow_modules = [ +from ryan_library.orchestrators import gdal as gdal +from ryan_library.orchestrators import rorb as rorb +from ryan_library.orchestrators.rorb import closure_durations as rorb_closure_durations +from ryan_library.orchestrators import tuflow as tuflow +from ryan_library.orchestrators.tuflow import closure_durations as closure_durations +from ryan_library.orchestrators.tuflow import pomm_combine as pomm_combine +from ryan_library.orchestrators.tuflow import tuflow_culverts_merge as tuflow_culverts_merge +from ryan_library.orchestrators.tuflow import tuflow_culverts_timeseries as tuflow_culverts_timeseries +from ryan_library.orchestrators.tuflow import tuflow_logsummary as tuflow_logsummary +from ryan_library.orchestrators.tuflow import tuflow_results_styling as tuflow_results_styling +from ryan_library.scripts._compat import warn_deprecated + +warn_deprecated("ryan_library.scripts", "ryan_library.orchestrators") + +RORB = rorb + +sys.modules[f"{__name__}.gdal"] = gdal +sys.modules[f"{__name__}.tuflow"] = tuflow +sys.modules[f"{__name__}.rorb"] = rorb +sys.modules[f"{__name__}.RORB"] = rorb +sys.modules[f"{__name__}.RORB.closure_durations"] = rorb_closure_durations + +sys.modules[f"{__name__}.tuflow_culverts_merge"] = tuflow_culverts_merge +sys.modules[f"{__name__}.tuflow_culverts_timeseries"] = tuflow_culverts_timeseries +sys.modules[f"{__name__}.tuflow_logsummary"] = tuflow_logsummary +sys.modules[f"{__name__}.tuflow_results_styling"] = tuflow_results_styling +sys.modules[f"{__name__}.pomm_combine"] = pomm_combine +sys.modules[f"{__name__}.closure_durations"] = closure_durations + +__all__ = [ + "gdal", + "tuflow", + "rorb", + "RORB", "tuflow_culverts_merge", "tuflow_culverts_timeseries", "tuflow_logsummary", @@ -12,10 +45,3 @@ "pomm_combine", "closure_durations", ] - -for _mod in _tuflow_modules: - module = import_module(f"{__name__}.tuflow.{_mod}") - sys.modules[f"{__name__}.{_mod}"] = module - globals()[_mod] = module - -__all__ = list(_tuflow_modules) diff --git a/ryan_library/scripts/_compat.py b/ryan_library/scripts/_compat.py new file mode 100644 index 00000000..cf0950e6 --- /dev/null +++ b/ryan_library/scripts/_compat.py @@ -0,0 +1,20 @@ +"""Compatibility helpers for deprecated script imports.""" + +from __future__ import annotations + +import warnings + +_DEPRECATION_DATE = "31/12/2026" + + +def warn_deprecated(module_name: str, replacement: str) -> None: + """Emit a deprecation warning for the legacy scripts namespace.""" + warnings.warn( + ( + f"{module_name} is deprecated; use {replacement}. " + f"Backwards compatibility is supported until {_DEPRECATION_DATE}." + f"Get the latest wrapper from ryan-tools\ryan-scripts\\ " + ), + DeprecationWarning, + stacklevel=2, + ) diff --git a/ryan_library/scripts/gdal/__init__.py b/ryan_library/scripts/gdal/__init__.py index e69de29b..066cc3d6 100644 --- a/ryan_library/scripts/gdal/__init__.py +++ b/ryan_library/scripts/gdal/__init__.py @@ -0,0 +1,8 @@ +"""Compatibility package for GDAL orchestrators.""" + +from ryan_library.orchestrators.gdal import gdal_flood_extent as gdal_flood_extent +from ryan_library.scripts._compat import warn_deprecated + +warn_deprecated("ryan_library.scripts.gdal", "ryan_library.orchestrators.gdal") + +__all__ = ["gdal_flood_extent"] diff --git a/ryan_library/scripts/pomm_max_items.py b/ryan_library/scripts/pomm_max_items.py index 13f21169..e296709e 100644 --- a/ryan_library/scripts/pomm_max_items.py +++ b/ryan_library/scripts/pomm_max_items.py @@ -2,7 +2,14 @@ """Compatibility wrapper that delegates to the TUFLOW POMM orchestrator. This shim keeps older imports working now that the implementation lives under -``ryan_library.scripts.tuflow.pomm_max_items`` with the other TUFLOW orchestrators. +``ryan_library.orchestrators.tuflow.pomm_max_items`` with the other TUFLOW orchestrators. """ -from ryan_library.scripts.tuflow.pomm_max_items import * # noqa: F401,F403 +from ryan_library.scripts._compat import warn_deprecated + +warn_deprecated( + "ryan_library.scripts.pomm_max_items", + "ryan_library.orchestrators.tuflow.pomm_max_items", +) + +from ryan_library.orchestrators.tuflow.pomm_max_items import * # noqa: F401,F403 diff --git a/ryan_library/scripts/rorb/__init__.py b/ryan_library/scripts/rorb/__init__.py new file mode 100644 index 00000000..246c0bc0 --- /dev/null +++ b/ryan_library/scripts/rorb/__init__.py @@ -0,0 +1,8 @@ +"""Compatibility package for RORB orchestrators.""" + +from ryan_library.orchestrators.rorb import closure_durations as closure_durations +from ryan_library.scripts._compat import warn_deprecated + +warn_deprecated("ryan_library.scripts.rorb", "ryan_library.orchestrators.rorb") + +__all__ = ["closure_durations"] diff --git a/ryan_library/scripts/tuflow/__init__.py b/ryan_library/scripts/tuflow/__init__.py index 8b137891..454712da 100644 --- a/ryan_library/scripts/tuflow/__init__.py +++ b/ryan_library/scripts/tuflow/__init__.py @@ -1 +1,30 @@ +"""Compatibility package for TUFLOW orchestrators.""" +from ryan_library.orchestrators.tuflow import closure_durations as closure_durations +from ryan_library.orchestrators.tuflow import peak_check_po_csvs as peak_check_po_csvs +from ryan_library.orchestrators.tuflow import po_combine as po_combine +from ryan_library.orchestrators.tuflow import pomm_combine as pomm_combine +from ryan_library.orchestrators.tuflow import pomm_max_items as pomm_max_items +from ryan_library.orchestrators.tuflow import tuflow_culverts_mean as tuflow_culverts_mean +from ryan_library.orchestrators.tuflow import tuflow_culverts_merge as tuflow_culverts_merge +from ryan_library.orchestrators.tuflow import tuflow_culverts_timeseries as tuflow_culverts_timeseries +from ryan_library.orchestrators.tuflow import tuflow_logsummary as tuflow_logsummary +from ryan_library.orchestrators.tuflow import tuflow_results_styling as tuflow_results_styling +from ryan_library.orchestrators.tuflow import tuflow_timeseries_stability as tuflow_timeseries_stability +from ryan_library.scripts._compat import warn_deprecated + +warn_deprecated("ryan_library.scripts.tuflow", "ryan_library.orchestrators.tuflow") + +__all__ = [ + "closure_durations", + "peak_check_po_csvs", + "po_combine", + "pomm_combine", + "pomm_max_items", + "tuflow_culverts_mean", + "tuflow_culverts_merge", + "tuflow_culverts_timeseries", + "tuflow_logsummary", + "tuflow_results_styling", + "tuflow_timeseries_stability", +] diff --git a/ryan_library/scripts/wrapper_utils.py b/ryan_library/scripts/wrapper_utils.py index b88bb9cb..be8314fc 100644 --- a/ryan_library/scripts/wrapper_utils.py +++ b/ryan_library/scripts/wrapper_utils.py @@ -1,146 +1,7 @@ -"""Utility functions shared by wrapper scripts.""" +"""Compatibility wrapper for shared wrapper utilities.""" -from argparse import ArgumentParser, Namespace -from collections.abc import Collection -from dataclasses import dataclass -import os -from pathlib import Path -from typing import Protocol, Sequence -from importlib.metadata import PackageNotFoundError, version +from ryan_library.scripts._compat import warn_deprecated +warn_deprecated("ryan_library.scripts.wrapper_utils", "ryan_library.functions.wrapper_utils") -@dataclass(slots=True) -class CommonWrapperOptions: - """Container for CLI-provided overrides that most wrappers share.""" - - console_log_level: str | None = None - data_types: tuple[str, ...] | None = None - locations_to_include: tuple[str, ...] | None = None - working_directory: Path | None = None - - -class PeakReportExporter(Protocol): - """Callable signature for POMM peak report exporters.""" - - def __call__( - self, - *, - script_directory: Path, - log_level: str, - include_pomm: bool, - locations_to_include: Collection[str] | None, - include_data_types: Collection[str] | None, - ) -> None: ... - - -@dataclass(slots=True, frozen=True) -class PommPeakWrapperDefaults: - """Default configuration values for POMM peak report wrappers.""" - - console_log_level: str - include_pomm: bool - include_data_types: tuple[str, ...] - locations_to_include: tuple[str, ...] - working_directory: Path - - -def change_working_directory(target_dir: Path) -> bool: - """Change the working directory and handle failures.""" - try: - os.chdir(target_dir) - print(f"Current Working Directory: {Path.cwd()}") - except OSError as exc: - print(f"Failed to change working directory to {target_dir}: {exc}") - if os.name == "nt": - os.system("PAUSE") - return False - return True - - -def print_library_version(package_name: str = "ryan_functions") -> None: - """Display the installed version of *package_name* if available.""" - try: - print(f"{package_name} version: {version(distribution_name=package_name)}") - except PackageNotFoundError: - print(f"{package_name} version: unknown") - - -def add_common_cli_arguments(parser: ArgumentParser) -> None: - """Inject shared CLI arguments that most wrappers support.""" - parser.add_argument( - "--console-log-level", - dest="console_log_level", - help="Set log verbosity (e.g., INFO or DEBUG). Defaults to the script value.", - ) - parser.add_argument( - "--data-types", - nargs="+", - metavar="TYPE", - help="Override the data types to load (e.g., POMM RLL_Qmx). Defaults to the script value.", - ) - parser.add_argument( - "--locations", - nargs="+", - metavar="LOCATION", - help="Limit processing to one or more PO/Location/Channel identifiers.", - ) - parser.add_argument( - "--working-directory", - type=Path, - help="Directory to process instead of the script's location.", - ) - - -def parse_common_cli_arguments(args: Namespace) -> CommonWrapperOptions: - """Map argparse results to :class:`CommonWrapperOptions`.""" - locations_argument = getattr(args, "locations", None) - data_types_argument = getattr(args, "data_types", None) - return CommonWrapperOptions( - console_log_level=getattr(args, "console_log_level", None), - data_types=_coerce_sequence_argument(raw_values=data_types_argument), - locations_to_include=_coerce_locations_argument(raw_locations=locations_argument), - working_directory=getattr(args, "working_directory", None), - ) - - -def run_pomm_peak_report_wrapper( - *, - exporter: PeakReportExporter, - defaults: PommPeakWrapperDefaults, - overrides: CommonWrapperOptions, -) -> None: - """Run a POMM peak report wrapper using common defaults and CLI overrides.""" - print_library_version() - - script_directory: Path = overrides.working_directory or defaults.working_directory - if not change_working_directory(target_dir=script_directory): - return - - effective_console_log_level: str = overrides.console_log_level or defaults.console_log_level - effective_data_types: tuple[str, ...] | None = overrides.data_types or defaults.include_data_types or None - effective_locations: tuple[str, ...] | None = ( - overrides.locations_to_include if overrides.locations_to_include else (defaults.locations_to_include or None) - ) - - exporter( - script_directory=script_directory, - log_level=effective_console_log_level, - include_pomm=defaults.include_pomm, - locations_to_include=effective_locations, - include_data_types=list(effective_data_types) if effective_data_types else None, - ) - print() - print_library_version() - - -def _coerce_locations_argument( - raw_locations: Sequence[str] | None, -) -> tuple[str, ...] | None: - return _coerce_sequence_argument(raw_values=raw_locations) - - -def _coerce_sequence_argument(raw_values: Sequence[str] | None) -> tuple[str, ...] | None: - if not raw_values: - return None - normalized: tuple[str, ...] = tuple(value.strip() for value in raw_values if value.strip()) - return normalized or None +from ryan_library.functions.wrapper_utils import * # noqa: F401,F403 diff --git a/setup.py b/setup.py index c7a6e65f..fc21c56e 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ name="ryan_functions", # Version scheme: yy.mm.dd.release_number # Increment when publishing new wheels - version="25.12.21.13", + version="25.12.21.14", packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), include_package_data=True, # Include package data as specified in MANIFEST.in # package_data={"ryan_library": ["py.typed"]}, From 3781bcae947f3a2da0c76af51752c19b8c4264bf Mon Sep 17 00:00:00 2001 From: Chain Frost Date: Mon, 26 Jan 2026 23:24:28 +0800 Subject: [PATCH 2/2] pdf cleaning --- ...ryan_functions-26.1.26.1-py3-none-any.whl} | Bin 351097 -> 354226 bytes requirements.txt | 1 + ryan-scripts/misc-python/ocg_clean_file.py | 543 ++++++++++++++++++ ryan-scripts/misc-python/pypdf_decrypt.py | 65 +++ setup.py | 3 +- 5 files changed, 611 insertions(+), 1 deletion(-) rename dist/{ryan_functions-25.12.21.14-py3-none-any.whl => ryan_functions-26.1.26.1-py3-none-any.whl} (83%) create mode 100644 ryan-scripts/misc-python/ocg_clean_file.py create mode 100644 ryan-scripts/misc-python/pypdf_decrypt.py diff --git a/dist/ryan_functions-25.12.21.14-py3-none-any.whl b/dist/ryan_functions-26.1.26.1-py3-none-any.whl similarity index 83% rename from dist/ryan_functions-25.12.21.14-py3-none-any.whl rename to dist/ryan_functions-26.1.26.1-py3-none-any.whl index 41fab2719fe88b8e4797dd0bbbc1b11d584d10e9..359c6adbcc18eaae29c80d878526b4a8333bdaab 100644 GIT binary patch delta 46761 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 b1ob}+-8~O5QzjB65}~1$(-9tMeM$6xgaKE` diff --git a/requirements.txt b/requirements.txt index 1ebe31ee..fb599343 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,3 +19,4 @@ requests openpyxl loguru ezdxf +pypdf diff --git a/ryan-scripts/misc-python/ocg_clean_file.py b/ryan-scripts/misc-python/ocg_clean_file.py new file mode 100644 index 00000000..38ba51ed --- /dev/null +++ b/ryan-scripts/misc-python/ocg_clean_file.py @@ -0,0 +1,543 @@ +# ryan-scripts\misc-python\ocg_clean_file.py + +""" +Remove the smaller-numbered OCG marked-content block per page, drop XForm /OC +objects, strip JavaScript actions, and remove /Widget annotations. + +Usage: + python3 ocg_clean_file.py input.pdf -o output.pdf + or set the DEFAULT_INPUT_PDF + python3 ocg_clean_file.py +""" + +from __future__ import annotations + +import os +import re +import sys +from typing import Any + +from pypdf import PdfReader, PdfWriter +from pypdf.generic import ArrayObject, ContentStream, NameObject + +DEFAULT_INPUT_PDF = r"folder/file.pdf" +DEFAULT_OUTPUT_PDF = None +DEFAULT_DECRYPT_PASSWORD = "" + + +def _name_to_key(value: Any) -> str | None: + if value is None: + return None + if isinstance(value, bytes): + try: + return value.decode("latin1") + except Exception: + return repr(value) + try: + text = str(value) + except Exception: + return None + return text if text else None + + +def _resolve_dict(value: Any) -> dict[Any, Any]: + if value is None: + return {} + if hasattr(value, "get_object"): + try: + value = value.get_object() + except Exception: + return {} + return value if isinstance(value, dict) else {} + + +def _normalize_ocg_label(label: str | None) -> str | None: + if label is None: + return None + text = label.strip() + if text.startswith("/"): + text = text[1:] + return text if text else None + + +def _ocg_numeric_suffix(label: str | None) -> int | None: + normalized = _normalize_ocg_label(label) + if not normalized: + return None + if "-" in normalized: + return None + match = re.search(r"(\d+)$", normalized) + if not match: + return None + try: + return int(match.group(1)) + except ValueError: + return None + + +def _resolve_ocg_name(ocg_obj: Any) -> str | None: + if ocg_obj is None: + return None + if hasattr(ocg_obj, "get_object"): + try: + ocg_obj = ocg_obj.get_object() + except Exception: + return None + if isinstance(ocg_obj, dict): + if "/Name" in ocg_obj: + return _name_to_key(ocg_obj.get("/Name")) + if "/OCGs" in ocg_obj: + names: list[str] = [] + for item in ocg_obj.get("/OCGs", []): + entry = item + if hasattr(entry, "get_object"): + try: + entry = entry.get_object() + except Exception: + continue + if isinstance(entry, dict) and "/Name" in entry: + name = _name_to_key(entry.get("/Name")) + if name: + names.append(name) + if names: + return ", ".join(names) + return None + + +def _resolve_props(props: Any, props_dict: dict[Any, Any]) -> tuple[str | None, str | None]: + props_obj = props + if hasattr(props_obj, "get_object"): + try: + props_obj = props_obj.get_object() + except Exception: + return None, None + if isinstance(props_obj, dict): + return None, _resolve_ocg_name(props_obj) + props_key = _name_to_key(props_obj) + if not props_key or not props_dict: + return props_key, None + ocg_obj = None + if props_obj in props_dict: + ocg_obj = props_dict.get(props_obj) + else: + try: + ocg_obj = props_dict.get(NameObject(props_key)) + except Exception: + ocg_obj = None + return props_key, _resolve_ocg_name(ocg_obj) + + +def _remove_ocg_xobjects(resources: dict[Any, Any]) -> tuple[set[str], int]: + ocg_names: set[str] = set() + xobjects = resources.get("/XObject") + if not xobjects: + return ocg_names, 0 + xobjects_obj = _resolve_dict(xobjects) + if not xobjects_obj: + return ocg_names, 0 + + for name, ref in list(xobjects_obj.items()): + xobj = ref + if hasattr(xobj, "get_object"): + try: + xobj = xobj.get_object() + except Exception: + continue + if not isinstance(xobj, dict): + continue + subtype = _name_to_key(xobj.get("/Subtype")) + if subtype == "/Form" and "/OC" in xobj: + key = _name_to_key(name) + if key: + ocg_names.add(key) + try: + del xobjects_obj[name] + except Exception: + pass + + if not xobjects_obj: + try: + resources.pop("/XObject") + except Exception: + pass + + return ocg_names, len(ocg_names) + + +def _is_oc_tag(operands: list[Any]) -> bool: + if not operands: + return False + tag = _name_to_key(operands[0]) + return tag == "/OC" + + +def _strip_content( + content_obj: Any, + reader: PdfReader, + ocg_xobject_names: set[str], + props_dict: dict[Any, Any], +) -> tuple[ContentStream, int, int, set[str]]: + content_stream = ContentStream(content_obj, reader) + new_ops: list[tuple[list[Any], bytes]] = [] + + ocg_entries: list[dict[str, Any]] = [] + for operands, operator in content_stream.operations: + if operator == b"BDC" and _is_oc_tag(operands): + props = operands[1] if len(operands) > 1 else None + props_key, ocg_name = _resolve_props(props, props_dict) + num = _ocg_numeric_suffix(props_key) + if num is None: + num = _ocg_numeric_suffix(ocg_name) + if num is not None: + ocg_entries.append( + { + "num": num, + "props_key": props_key, + "ocg_name": ocg_name, + "primary": ocg_name or props_key, + } + ) + + remove_props: set[str] = set() + if ocg_entries: + min_num = min(entry["num"] for entry in ocg_entries) + for entry in ocg_entries: + if entry["num"] == min_num: + if entry["props_key"]: + remove_props.add(entry["props_key"]) + + remove_props_norm = {_normalize_ocg_label(name) for name in remove_props if name} + + removed_blocks = 0 + remove_depth = 0 + do_removed = 0 + + for operands, operator in content_stream.operations: + if remove_depth > 0: + if operator in {b"BDC", b"BMC"}: + remove_depth += 1 + elif operator == b"EMC": + remove_depth -= 1 + continue + + if operator == b"BDC" and _is_oc_tag(operands) and remove_props: + props = operands[1] if len(operands) > 1 else None + props_key, ocg_name = _resolve_props(props, props_dict) + norm = _normalize_ocg_label(props_key) if props_key else None + if props_key in remove_props or (norm and norm in remove_props_norm): + removed_blocks += 1 + remove_depth = 1 + if remove_depth > 0: + continue + + if operator == b"Do" and operands: + name = _name_to_key(operands[0]) + if name and name in ocg_xobject_names: + do_removed += 1 + continue + + new_ops.append((operands, operator)) + + content_stream.operations = new_ops + content_stream.get_data() + return content_stream, removed_blocks, do_removed, remove_props + + +def _default_output_path(input_path: str) -> str: + root, ext = os.path.splitext(input_path) + return f"{root}_cleaned{ext or '.pdf'}" + + +def _strip_js_from_action(action: Any) -> bool: + action_dict = _resolve_dict(action) + if not action_dict: + return False + if _name_to_key(action_dict.get("/S")) == "/JavaScript": + return True + if "/Next" in action_dict: + next_obj = action_dict.get("/Next") + if isinstance(next_obj, list): + next_list = list(next_obj) + elif next_obj is not None: + next_list = [next_obj] + else: + next_list = [] + for item in list(next_list): + if _strip_js_from_action(item): + try: + next_list.remove(item) + except Exception: + pass + if not next_list: + try: + del action_dict["/Next"] + except Exception: + pass + else: + action_dict[NameObject("/Next")] = next_list + return False + + +def _remove_js_from_annotations(page) -> int: + removed = 0 + annotations = page.get("/Annots") + if not annotations: + return 0 + annots_obj = annotations + if hasattr(annots_obj, "get_object"): + try: + annots_obj = annots_obj.get_object() + except Exception: + return 0 + if not isinstance(annots_obj, list): + return 0 + for annot_ref in annots_obj: + annot = annot_ref + if hasattr(annot, "get_object"): + try: + annot = annot.get_object() + except Exception: + continue + if not isinstance(annot, dict): + continue + action = annot.get("/A") + if action and _strip_js_from_action(action): + try: + del annot["/A"] + except Exception: + pass + removed += 1 + aa = annot.get("/AA") + if aa: + aa_dict = _resolve_dict(aa) + if aa_dict: + for key in list(aa_dict.keys()): + if _strip_js_from_action(aa_dict.get(key)): + try: + del aa_dict[key] + except Exception: + pass + removed += 1 + if not aa_dict: + try: + del annot["/AA"] + except Exception: + pass + return removed + + +def _remove_widget_annotations(page) -> int: + annotations = page.get("/Annots") + if not annotations: + return 0 + annots_obj = annotations + if hasattr(annots_obj, "get_object"): + try: + annots_obj = annots_obj.get_object() + except Exception: + return 0 + if not isinstance(annots_obj, list): + return 0 + kept = [] + removed = 0 + for annot_ref in annots_obj: + annot = annot_ref + if hasattr(annot, "get_object"): + try: + annot = annot.get_object() + except Exception: + kept.append(annot_ref) + continue + subtype = annot.get("/Subtype") if isinstance(annot, dict) else None + if str(subtype) == "/Widget": + removed += 1 + continue + kept.append(annot_ref) + if kept: + page[NameObject("/Annots")] = ArrayObject(kept) + else: + try: + del page["/Annots"] + except Exception: + pass + return removed + + +def _remove_doc_level_js(writer: PdfWriter) -> bool: + # Run after cloning so we can safely mutate writer's root object. + root = writer._root_object + if not root: + return False + removed = False + names = root.get("/Names") + if names: + names_dict = _resolve_dict(names) + if names_dict and "/JavaScript" in names_dict: + try: + del names_dict["/JavaScript"] + removed = True + except Exception: + pass + if not names_dict: + try: + del root["/Names"] + except Exception: + pass + open_action = root.get("/OpenAction") + if open_action and _strip_js_from_action(open_action): + try: + del root["/OpenAction"] + except Exception: + pass + removed = True + aa = root.get("/AA") + if aa: + aa_dict = _resolve_dict(aa) + if aa_dict: + for key in list(aa_dict.keys()): + if _strip_js_from_action(aa_dict.get(key)): + try: + del aa_dict[key] + except Exception: + pass + removed = True + if not aa_dict: + try: + del root["/AA"] + except Exception: + pass + return removed + + +def main() -> int: + if len(sys.argv) > 1: + pdf_path = sys.argv[1] + output_path = sys.argv[2] if len(sys.argv) > 2 else _default_output_path(pdf_path) + else: + pdf_path = DEFAULT_INPUT_PDF + output_path = DEFAULT_OUTPUT_PDF or _default_output_path(pdf_path) + + if not pdf_path: + raise ValueError("Set DEFAULT_INPUT_PDF or pass a PDF path on the command line.") + + reader = PdfReader(pdf_path) + writer = PdfWriter() + + total_ocg_blocks = 0 + total_xforms = 0 + total_do_removed = 0 + total_js_annots = 0 + total_widgets_removed = 0 + warnings: list[str] = [] + errors: list[str] = [] + page_notes: list[str] = [] + + decrypt_status = "not_encrypted" + if reader.is_encrypted: + try: + result = reader.decrypt(DEFAULT_DECRYPT_PASSWORD) + except Exception as exc: + raise RuntimeError(f"Decrypt failed: {type(exc).__name__}: {exc}") from exc + if result == 0: + raise RuntimeError("Decrypt failed: invalid or missing password.") + decrypt_status = f"decrypted (result={result})" + warnings.append("Input was encrypted; permissions removed by decrypt before processing.") + + def process_page(page, page_num: int) -> None: + nonlocal total_ocg_blocks, total_xforms, total_do_removed, total_js_annots, total_widgets_removed + + def record_error(stage: str, exc: Exception) -> None: + errors.append(f"Page {page_num} [{stage}]: {type(exc).__name__}: {exc}") + + resources = {} + props_dict = {} + ocg_xobject_names: set[str] = set() + + try: + resources = _resolve_dict(page.get("/Resources")) + props_dict = _resolve_dict(resources.get("/Properties")) + except Exception as exc: + record_error("resources", exc) + + try: + ocg_xobject_names, xforms_removed = _remove_ocg_xobjects(resources) + total_xforms += xforms_removed + except Exception as exc: + record_error("xobject", exc) + + try: + total_js_annots += _remove_js_from_annotations(page) + except Exception as exc: + record_error("js_annots", exc) + + try: + total_widgets_removed += _remove_widget_annotations(page) + except Exception as exc: + record_error("widgets", exc) + + try: + content_obj = page.get("/Contents") + if content_obj: + content_stream, removed_blocks, do_removed, removed_props = _strip_content( + content_obj, reader, ocg_xobject_names, props_dict + ) + total_ocg_blocks += removed_blocks + total_do_removed += do_removed + page[NameObject("/Contents")] = writer._add_object(content_stream) + if removed_props: + removed_list = ", ".join(sorted(removed_props)) + page_notes.append(f"Page {page_num}: removed OCG blocks {removed_list}") + else: + warnings.append(f"Page {page_num}: missing /Contents") + except Exception as exc: + record_error("content", exc) + + total_pages = len(reader.pages) + processed_pages = {"value": 0} + + def process_page_with_progress(page) -> None: + processed_pages["value"] += 1 + page_num = processed_pages["value"] + print(f"Processing page {page_num}/{total_pages}") + process_page(page, page_num) + + writer.clone_document_from_reader(reader, after_page_append=process_page_with_progress) + doc_js_removed = _remove_doc_level_js(writer) + + with open(output_path, "wb") as handle: + writer.write(handle) + + if page_notes: + print("\nPer-page notes") + print("-" * 40) + for note in page_notes: + print(f"- {note}") + if warnings: + print("\nWarnings") + print("-" * 40) + for warning in warnings: + print(f"- {warning}") + if errors: + print("\nErrors") + print("-" * 40) + for error in errors: + print(f"- {error}") + print("\nSummary") + print("-" * 40) + print(f"Pages processed: {processed_pages['value']}") + print(f"OCG blocks removed: {total_ocg_blocks}") + print(f"XForm /OC objects removed: {total_xforms}") + print(f"Do ops stripped: {total_do_removed}") + print(f"JS annotations removed: {total_js_annots}") + print(f"Widget annotations removed: {total_widgets_removed}") + print(f"Doc-level JS removed: {doc_js_removed}") + print(f"Decrypt status: {decrypt_status}") + print(f"Warnings: {len(warnings)}") + print(f"Errors: {len(errors)}") + + print(f"Wrote {output_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/ryan-scripts/misc-python/pypdf_decrypt.py b/ryan-scripts/misc-python/pypdf_decrypt.py new file mode 100644 index 00000000..29d224f9 --- /dev/null +++ b/ryan-scripts/misc-python/pypdf_decrypt.py @@ -0,0 +1,65 @@ +# ryan-scripts\misc-python\pypdf_decrypt.py + +""" +Decrypt a PDF (remove permission flags) using pypdf. + +Usage: + python3 pypdf_decrypt.py input.pdf [output.pdf] + or set the DEFAULT_INPUT_PDF + python3 pypdf_decrypt.py +""" + +from __future__ import annotations + +import os +import sys + +from pypdf import PdfReader, PdfWriter + +DEFAULT_INPUT_PDF = r"folder/file.pdf" +DEFAULT_OUTPUT_PDF = None +DEFAULT_DECRYPT_PASSWORD = "" + + +def _default_output_path(input_path: str) -> str: + root, ext = os.path.splitext(input_path) + return f"{root}_decrypted{ext or '.pdf'}" + + +def main() -> int: + if len(sys.argv) > 1: + pdf_path = sys.argv[1] + else: + pdf_path = DEFAULT_INPUT_PDF + if len(sys.argv) > 2: + output_path = sys.argv[2] + else: + output_path = DEFAULT_OUTPUT_PDF or _default_output_path(pdf_path) + + if not pdf_path: + raise ValueError("Set DEFAULT_INPUT_PDF or pass a PDF path on the command line.") + + reader = PdfReader(pdf_path) + writer = PdfWriter() + + decrypt_status = "not_encrypted" + if reader.is_encrypted: + try: + result = reader.decrypt(DEFAULT_DECRYPT_PASSWORD) + except Exception as exc: + raise RuntimeError(f"Decrypt failed: {type(exc).__name__}: {exc}") from exc + if result == 0: + raise RuntimeError("Decrypt failed: invalid or missing password.") + decrypt_status = f"decrypted (result={result})" + + writer.clone_document_from_reader(reader) + with open(output_path, "wb") as handle: + writer.write(handle) + + print(f"Decrypt status: {decrypt_status}") + print(f"Wrote {output_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/setup.py b/setup.py index fc21c56e..f0d61911 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ name="ryan_functions", # Version scheme: yy.mm.dd.release_number # Increment when publishing new wheels - version="25.12.21.14", + version="26.01.26.01", packages=find_packages(exclude=["*.tests", "*.tests.*", "tests.*", "tests"]), include_package_data=True, # Include package data as specified in MANIFEST.in # package_data={"ryan_library": ["py.typed"]}, @@ -30,6 +30,7 @@ "openpyxl", "loguru", "tabulate", + "pypdf", # "beautifulsoup4", # Add any dependencies here, e.g., 'numpy', 'pandas' ],