From 2955cda84a042ea8abf50e3d359fb72dada570f9 Mon Sep 17 00:00:00 2001 From: John Andrews Date: Mon, 26 Feb 2024 20:19:08 +1300 Subject: [PATCH] FF-1393 - new duration start flow element --- DiscordNodes/i18n/de.json | 30 + FileFlows.Plugin.dll | Bin 133120 -> 134144 bytes FileFlows.Plugin.pdb | Bin 31040 -> 31592 bytes Gotify/Gotify.csproj | 10 +- .../FFmpegBuilderDurationStart.cs | 64 ++ .../FFmpegBuilderWatermark.cs | 302 +++++++ .../FfmpegBuilderExecutor.cs | 23 + .../FfmpegBuilderNodes/Models/FfmpegModel.cs | 16 + .../Models/FfmpegVideoStream.cs | 15 + .../FfmpegBuilder_AudioConverterTests.cs | 2 +- .../FfmpegBuilder_VideoEncodeTests.cs | 49 +- VideoNodes/Tests/_TestBase.cs | 8 + VideoNodes/i18n/de.json | 840 ++++++++++++++++++ VideoNodes/i18n/en.json | 46 + 14 files changed, 1399 insertions(+), 6 deletions(-) create mode 100644 DiscordNodes/i18n/de.json create mode 100644 VideoNodes/FfmpegBuilderNodes/FFmpegBuilderDurationStart.cs create mode 100644 VideoNodes/FfmpegBuilderNodes/FFmpegBuilderWatermark.cs create mode 100644 VideoNodes/i18n/de.json diff --git a/DiscordNodes/i18n/de.json b/DiscordNodes/i18n/de.json new file mode 100644 index 00000000..7a660403 --- /dev/null +++ b/DiscordNodes/i18n/de.json @@ -0,0 +1,30 @@ +{ + "Plugins": { + "DiscordNodes": { + "Description": "Mit diesem Plugin können Sie Nachrichten an Discord senden.\n\nDie Webhook Id und der Token kann aus der URL entnommen werden.\n https://discord.com/api/webhooks/[webhookid]/[webhooktoken]", + "Fields": { + "WebhookId": "Webhook-ID", + "WebhookToken": "Webhook-Token" + } + } + }, + "Flow": { + "Parts": { + "Discord": { + "Outputs": { + "1": "Discord-Nachricht gesendet!", + "2": "Die Discord-Nachricht konnte nicht gesendet werden!" + }, + "Description": "Sendet eine Nachricht an einen Discord-Server.", + "Fields": { + "Message": "Nachricht", + "Message-Help": "Die Nachricht, die an den Discord-Server gesendet werden soll.", + "Title": "Titel", + "Title-Help": "Hier kann ein optionaler Titel festgelegt werden.", + "MessageType": "Typ", + "MessageType-Help": "Die Art der zu sendenden Nachricht. Der Grundtyp ist nur die Nachricht ohne Titel und ohne Farbgebung." + } + } + } + } +} \ No newline at end of file diff --git a/FileFlows.Plugin.dll b/FileFlows.Plugin.dll index 2a8db20e4d0d8e45484b7ac53e71945f0be7fa0b..869d34560de3a27f19817b9eb9fa1eaf937d1b73 100644 GIT binary patch literal 134144 zcmcG%3w%`7_4dDKCYecQNXP{;gcy#sM<=3U43{Dz zRkUdFMiG^wr4%WpXep%>5h=A4t))~EthLr!N-3q3*YZRD&$HJ)vkp|-{(Rp*A3gKz zwfA?ewfEWk+~y=1an;vM$QYA_|4*GV<_GxXzYFa4-*4uiI=|wF`R4n%yQ+Q=xMWw= z8A7~7;J9H(RMU^dczBleYf=Fn^I_Kb4AXEO``wOZXm3u{X2nv z@gH*wnrw64Z;g57f`AFo_&NS{2qxPiaLt$GGZrro)G<4i*`v&R%3x7?Onb*f0x(IOIHkntLMd^EP)eLK$Bb0w8fB&_gB{{A zXE|oRGV7K3K$+TLhADSUPnsmR!IYAlwMuSdmFeJ^3Cc7nW39q0@R&sUAxhb66}gUI zqWp5@S5peVol?f5BI=-B3hhnSDZ07@6Mm4k*U zG+v?U3eEMPM0z2m>uH|jAEHfyE~S*9t0^Vu7D^X1-$6SRI-*cnRt6eH>7dpQ8b_N% zx`R?8EmmlS4=QlbYK1l_v|FL~Jt&brNa?y)==dYFNzg9YnV{n-rF%`3F4H0hHPa^0 zLWLevXq^u#cF;zJ_9=8yp^C6ZYU7|Tv`M61lrkm*C?&no9+XIrr*z$G>-dSZ3BR0D z`2Cc^AE9*J^A2erE0h<>Kvk3i^`j(|NDrcPLA_(zFxn*OcuEO6ol^L@l)^8hbi8*^ zdx$pSS5gYUiBkA|lrCxSsP?`>M->X?WS~xz4)P9bwX{j3F_aQ%oBhu6$PJ-QG95=LnNFh=em14+o_Ca6pwK#n z_A68#Rj9&EnFMVTX(XjYYN3=!t9($UgVrguMWLMv?em~S`h7~*y(-6lM4JTtm{Nk~ z#WF#wC}nuMQaZk);~Qub{(MT|tyPj9?(xqiDmpo6v_caVN>K{5$b%B;C6q2`XU8w4 zO@gkcl%QKEg@2z?l0Hc3_=Mw+&?bCgD@d0#rSP{>x_w&hpqaD@v|OQW3VrBE0uh5_CDG1l>gGf;Kv6n?i3YWUT_d??E`nQo5i$9DhXl;(|=j-ju>mp>#oe zIw(b(WI9(NYZd4bA9S{ZmMXMaq5YHso%EnYI=c{7muWA@$7qwFaY`AUPL#s;r*xT~ zN&`2>PGfkvh zQ#$@U$G4?T_zFtlyHW~2fYSB!d9dNM0y^j3;G4eFQiR^uA-EnJ18aS z`;;zde+L~@=wpRqZ8A_5rGqYTP*>U{Qa?(GG+3btK4^f0rYO{`(ESQM<3Wk^DoWSA zfsS8Gn*`lLDM5Epy6#cRJ~>F~_(6_8LYwd>D22~%3n_dRrR(X1UQcNgs28O`0~DIz zg9dv&RcN(Bxh0uM*HF4h7ddD$Z4zlVr9`@4q4hp!h=VpM^qNBZ6guibiS!9dHzq?J zABbmycBPb{V<=@z7E`)RhdJm8g;ptKtpaWIK^Hq{t3vN9l-n*7X#k~*G~7YMXp=D+ zLn-M^R;a~;66yJru6vg_{(jnoUq&hXT1v_E4N3-0q~D@+{0PUtOPlbADTO~p>84C6 zq)Ylz2X&=QpuUs>jieMPl1hS7QfZ`=REAKx zRKDn-kqV7dXp%zne9&kI-LKFpg?1|Rp%1#;L5CGOrBLg#OnMEJF1;}h>P?&UX*i|y zX@WxYe9#qMdI~L5XstqT_@J>4dP|{W3bj2elU^@Mrk6;cPw6JYm5v`on`AngQZk)N zDWkuDQuv1`9Y4kyuFyIUN~AYZy6#=$_${=|0Tztq)qri z9Uz5YOey?MO4ri~4tj$&f!bDNped9Bt)z6&wGLWCn?N5cG@>#CJw)lCi4J;0Okrd)GPsP1=M%OeuU`6{KX^mC^;BzIi&j8f8DKIR5jVPrmH< z*XUE?zeOp-^C6`qo!tr2B|X(ad9(>sMk!ENN`d-%P$E5m(j|SPtyXBKLi>HtO%D1%q2mhWcFshqrF4;|JE$jZlHNEzxQc}rHK*~sUp>+A*;-CiF z1nNgA&=7?t`Jh`JG)AH8DgQn9akrq-)q~!{2_CYfov|XV$6na;olRoHn2W5B3MCwl|k>*iK zdTS_MdUrTzgF;&sdP||>9+XI*qI3g!rx!E{n{=;`Qi4`cO3;3kF6c}L4N_=~Le?tK z6c0+IQ#=6g^gy@=9vZy@)s;dXdjBE6f^h5m}V*rP5! zR2Lspii=pS3!O+8Q#u#()Wzp~h*x=!x+tY*8GtHE8Gx>olEnZ@4nQJ3jM8O+?^wMt z97(gdxQ0?(SgW|0=DBz_QF*U&P0F<>w}4W(l|F8Pa%+^^tlTc;-u1Xd`a?>W@_p*! z5Y3YENlHmMR+kA~PAR=kP&yY2)kQ7M;-WXDxEMq!*-xN!Gv}+yO;K)!a`Tm2>2WxW zQ@YUj2HP9(^)yT9?UWLFFQtV3h|-0AK)EBz1?n?gA*FDgD5cl6lrHolb4?j(f=CaMI51<^qP(#gq&fPA4cCFq}T0l3+MJn36f` zNqaaY%uVdWOkEb&$; z_oi}(ecU6;9ak>iJrl1trNkRW>EeA|xp6d0yqU@^Q*NEd;ZBFr?dv7#VhhdU;x$Sc zqCJ!ndOsyYC(<8KIv01<7qYb+>^@fQ0|a&@gAA}jiz+{<6Bhjv@@P&>ECop>ECSS z9`U$DdMTwF+Ha_f%++i{uVxc^HJi|@*@Rxr;sA`-U%V`yp=ZfrHKkyVoK*?g}NxE zSzJs|7po}6#V$%WhTl|fk8;Jm&_Y6wrxb1`rQ=pAHOjYeFoF{O016Qy)@5T(q9;goJRd`Df3qFF|38l|{+h*DgvqjY<9jdB~6 zdri4_l?(K7Tq2!I=|aDtE?Uzpp{pn*bWchNJ(|*mUaQ=A<)$dtq})S3?z_r8rrh(& zy`vz1$<+*0M%dR!v?5~U0MeRZ*!W(oZorG$QqQbHf6l|a!Ff^rL#Tcg}oANP`SJC)m`oV7~4_dG6<{)p10%vYA(8Sk*VIHfLH z_sgW5pmZs3RIZ+8>1tm}>FQwRCi=J^DmPWR7UdQzx6{XC_F-b(30Z&B`ZzLZw^6LqmuL%*q^_iO0mzR-B_)|(@zl*>IolX5Yo zq+ClW1KyL;_4;LX(U)fF^$1Go^+ZZ>aR;Tim`&+iY*QEWX%-iYD8+@fiVJHM7fXCD zUQriI)x|n>v5Qh%d`KxS4pX`;wyTR{G)oqRUx1V>YAMCVAWFKxHQlSq4X0VS3CdZk za7`YUNHSzNSGii?LR#l;FrnP#ggor_c~jp}KgUQe14JbfMo>Zkuv@l>1P*6CQ^jmKdU;f2%G&@6!nUD2z9)bLm+IAWkX! zx(lUbKbVr)C(9{{A*NbL}H%_@`<<|PR50!gK zxi^(NtX%71E?y!Xr*vKYqq-=kSwc5bN>>L{O3Gs>UCJLRca3t>l$)vCV;+}CFQ;^& z|D-Nf(k!7jQ%dO9C?)hqlrl$-P&yX})x~j|#YN;|NO2LTbOTN)E_zWq7k^e4{b&{! zBPhki1WIu+m(mTuA>|e-_k?oRD%>g`_ZQ{XDYr?vZIr@UtE9Z2R+sW&b@9HsIIJ#C zsEhb;mvSOqLFrulRb3=#mR|RylwJ>@lq|+lN){6+or@#tVlvI*;too2F`rUgET?n> z_c!I9S8juH+mw6H#~oGfBjs{0$;7Lrlz0;;UA(_5H-%=&bEb0lE4SRo9aHXk<+dsJ zu5z&v8t)&<71J#7swib#8Ym^t;XdxTa-)@-tlS;SJ>hYQ^fQ!hm;4`f@jT5EdOf9t z-byK<_fWba`dGRB${kYfW94F(Iu2hwQo7LpR2QW*OX#kY61p#?gdRufLZ47>qH-za z7Ad#N$Ni6T>y+D~oV7~4T|Vxla(k3}Pq{;s!gU#`d48f?1I^OE-jve6{*=O5EBlv7 zkD}EL(J6H?R$WX|7b$hoLMblhQ#uzWkU6d1PqSpPlv1)-MJZWqq7)a~D4mOdy4Xpx zxY$Q2E)G$Oi&KCWUGrkG)ormQMv)36c@RpAl(3jl`EuKxH3xN5|qLX z@NxLLU++?Am~xYqo2T4zk4vPVr*tXjsEai;OXzKs68bGl34M&xrJSqWN#){S%y5mA z!i}et(V9f*LPyobRGKC93`z+-mr`6TqZAh_DV>X$x>!xKxY$G~E?%P)7Y8X__N|mV zs@y5%Vxu!$7fQ$FDc3-=#G6Pd@fIt$%E#p^w@$e&%I#9_ppR><+)?FnFVDoQpp^dg zrj#M-Pw9rJKwS)`SyCQLDJf5*6c_U-T~`a0yI;8{lzU#e4L+_&xy{P$QSL+KB4b=U z{A>xOOSxEGw53^6?m{UkTdSnp*K>i(^ES#2P;QiRlPHC2@o{aHo3Gpx%2}&$Ydj8L zfKs}YOVq_Cb+JobyhkZ60#`t~QO1w!dn-7XX6b5MO6h79rEuqa9DX*A(uHoPE{4-A zE@o1Si`A6k;t-_^U8>wM<+8_SIBONIEv+)Q$|+sw_UfV&%@VpnU7SxTF2+;3&}GU^ zQZA)ji*k!SE|GqM(uF=tT`Z?rLa(8eUT>t7&~H(?(B;a#r`%!XPAV6_Qn?PwRnRQ) zYAGdNZ%TtB^}wKPkfgD54>@ygBf zaUGSrU%9o)?NKgrmB#C&+~++)bygRx=~+_lO(`i~Ln%YM#1}fD+%o0XDz{a+4?HfB zK1AteQMI}_O0$Fxjn9NGrj*cKDP;{bQaTs-EgRkn?oG3}7)&YIkEIkBO_Xj&C6#Md zZjo}!mD}Rux+=FrxsQ~~y*d-GE2WE9qg*4+l4pNP$#aBq(|la5a!txDP;QBGt357} zUQg+Us7_sMq*+35r<9aGLR=Fw4 zS*vh&__(u``pdx(-rYbft7IzMw7|XciaeQ;G{~6&J(R#b}?4{_0|!x=5*u zg_PoAB_*@K_2dQ0tx;~1a@H!`E{{v3_fWd*2dImE>f)%nh)v3bE~Rv#2P#)Zv-G-_ zQhMD>xsg6@kaA;{dq}xm%EhnOco!;HL9@iGr<8cTDW$8UeB5B=KIacOR9>Vm#%bsl z4gHLUUgw3z>!Xxzl=17WymRmtnkD=9DJA>t$(ihnDP@|KQ92hx)kPJ}ZU897MPEu8 zfZ>#GM-5YMv~p9GTcF$uA9t~GtCicL+?&dMxD1{r~<3=bqOu1>wEmm%WkGoX4&C0#2TwqEjUYye9iQiD>?bQmJ zCC^4m>E9sbCVE^VJ(bc8(Pio)MYFh=ODQfMp_Hy}pmd=}DYsd<-O9bE+({qzMdh-; zoQYRRDe=lFC0<`j7jLw31C$$~+&JZC__)iJYf)~ca=VrL(Bl&6!<24_#;A*9G|Lc$ zrb0@}g_M$V10_>Vq}$0>JGxz;ykxN=J28Yv}oUrHDHDs|DH zW(hr$QbMn$6c<}4UFh-3?NIKZa=FtoTmz-!u2!x$%@S`MrNnDiZk3P2FZ%OV)H>yM zD7Rm^&`lceOUlJ)mUv~960eq0`ZvtSO;B!>a+8$1L%C%>?pozmDz`zo9m*Z@xJ3FG zrQ0PF)x`;#CFR2DnUt+nQtm>l8`|rXYoJ-U{>lxf6mE)-o1|Pyxi!iiSFZKV8t;1L zKJSkQO;#6idX|(2P|Dt!Mky(8@P)oXxy{PGsoaOko%C^2l*>+K;De*+tfvZW*MTMl#=owN=bP#rAv8+a?_QYt=vP(t?;-+dNrjBef$5t zi#ycCI(nAuH&aUXJ1Hgm4=81h9HMkt+^H^((kw0_w?T@FQc7{rKb z&RT^VTMzida z21*&1v6PbMVjs6axhIs{s@y5%if3xP`;;rAS>pAjlz0;;CEjcww@|qS$}LuIsd6v* zxUVX=MY&zd?Njb!A9ufUfx9w!7E(%{T_`2bL6n>?iS%$vH{~8s7o%vFt~ODMi^Y`U zVk@Paa*LGPsoZhpx;AIHX_St8P`M_WCEgNBiMK(yLq6^y<&G&Ax;w+QrIb8tDW$7D zDP32;_J8kUvAXC>&yxKJO3D5jO39*$QnF~KbXh#CF6PoKE|yWc0iYBYyC~hjJ)+zm z<&G#9Ysqj4N(o(0=|X>9UG$_`LXV=9&?!m@J(tpjUZUJW<(4V;l5%hOxJQ+HOS!|! z<<82)OHjIak11DAv*g*2Qt}+8+yswHq^D52u0F0Vrqe7g=241^Cn%+>8z^1qCzRW) z+)m~8D0kH3aNSGkLO-c40<&S3(5)#YbUCGj?nfy*Y7nJ!u~c0Qqgh;xqZAiYDaFM? zN|*gNlv}LaGs>+~Zkvx=rrc}Fy``MBO1uv}4i88uUCK|Xi(~4dbWSGaew5;3Jf%x{ zxpI?eb~{SBWy)>!xI}snN9jVZR2T2jETIokO6U`m5<31BNEaHo7rKIG;YLsjHp$lo2&=r&tx}H)(52th~uTpNba#NIRQSLF1!;90DF7&t6#Y&nb z^jb;@ZLJb|i{}D2d8?J%q1;=_9i$ZQl#lz4a*=y7@#2&c&sv4+LMywPNH zUg~17x)?(#E~Zh6izZ6v;stdvlV<7lQcB5UE2X%2gVGK7TIJqS?nC81R<3lua^F?1 zie`z|lTzXhrj&T&JT8%*Na<2ur!J<@EH36zii>5G;$kPIOZj`sy`kKG<*Ze>gC2*U ziKcX+*Q<+<)kXHbnb3ul;vzvQ171(*Tzp?$^rTs`A3!PDkERqCw^E9WnUv1O26Zu; zW^r*prMP&EQe3R3bOZ3Ba+{RfsoY-Wj`_HklslQC&3C?7B)RUA0yTy;NPS@VWS*x>%(y)~k!nl;UD9r40DHlrD=+ z>f&?$(&@?{sf!QjSvqorQaW;yQnDz$57Ld{X634A7Op3yaDyp@o8oc!jb@ZC`yZ=| z88nNF7D{n3pHf^{s|&qFxn;_&QEszxZ&5n#C(6C2+!5sh3p4RbDIK>}xhk3^&qhkg zbAWOaeca2+O;xU0xkbt?^KsjhTdCYu<@PHV|ElKsigFb+OP<3iCC?^G8P5eChriZC z>2}F>b+LqIaj}Y0Tx_Nk7yBsP5WTA0`^p_xE_Q#0YoK)84&{2&Eb#_YO1#m^-Rg0P z^h`>Z@=w*pY?{TzB1&Ig&ElehQd~4pii?qyZUA0WZme=Mlv}LaY9IG=<<={=O}Smlz3XxKEohW3qU@~axY3rc{-&_`4`H~pjo(i$}LuIwU67a+f(KxCFSFkl5*^!Ov+W1GFn|Jor^u{qJd^{(VtRWjHGlsn9}XwUn@65 zxrdZnrQDl7Zm)9tl>0zAYn6CMJr1|ClrH7psEfeYV3w5gC?(}`N^#LhDZTDX>0G>} zF8b3fE{0ILUQ>#TDU`0)Z!4Elu35PS%B}D?Jn*M%p9h4G!Kc$5Jm{PJ2 zEQWM0-cc73n#Dz&Qe0T8xadNwxM=XX*sm^nsfz*XVmPI^7*FX2;DBgR!y50m%5|byy4pY~UA0!pv!9Q9Pq{(LjZ|(trEqunxZf%FIe(RN z<@@SlwuWAzp|@-3k9?tjuiO#k0*_?6+L}^QPEg8Tt*3Mo;{$cklV%yM{**FW!zsnZ z6iRWCqI53)pe|<6EH36zii<}m#l>n$H!(g`ZoP6_lzUCN4?PYKY$#pmKdOskG)w4{ zloC4o>yQ%KT3zUml{4F<(ib6r`#jTt@Jqj{vS%0@mOzS&zLer(45iEdkaE}1EZlVE<|_AukNb;q z&nUN1xxLCA@o|Th`&hZiqnSLdRq||0tIPAR%9YbBd5%%;eoEnX`?w>@?N#mr<*Ze> zqaKG71*IF>zp0DNAD_T)IxIyC8QRPrpGfE*pTM6mYOgMis*Av5FiZATl;Wa4rDSmp zrR(+Im7A?nUWUh6bQ}I8jE6+wruO{XvB<8r=HXy64}VHHQJ+=a zrnWG-oU6&|>}1&5gVn(^8{t9Xe{O`Qf1lC_{VD4nG|l)7po>5A-<@s>bi|2qs(GN^Z5XOe#b1rgC@*raE97J&;{p z5+WKD-)^ZDE}9fP43D`5D7 zXRyN8vOg=LB{k7D+@j?LG~japKYIj|m2jD=qF>avw|~sHrhQXK8eBtbpNC&tL@%BRzu^FkI#ttbk#ZXRrc>FM0+m zU>NNgtbpNi&tL@%V?2WuFkImotbk#xXRrc>D?Ni1FpTpIR=|Kmj&#ln7{+@BD`2?V zGgtw`HJ-r=7{25gtbhS~S)5t{!?m8l3K%AO1}k8=&NEm6!z9mO1q|1F1}p6G63Y&M zsoNB$S7Wj#>o9ww;bc8N>LS5pic=t*-j1qZ@-`G=MS)LBI%0{Zx}iz3fg4OayVNIp z&aFVS8$5#*Fii0bR=_aTGgtw`jh?{@7^Zm!E3OMB??M*!IhdX}Ackx3*}_k>yvb{6 z1&)~^vmSlpzhJzDGc#xp7A>4{PI9iv(uE^-8ZSb_lAXL3PGPF$M}Afk1Il8fEoLXb z!p~+lt?v?a3o5>{HcKBGb@9BZOAr?tRJb1kS`i!TL}*k`cwL`M}$;eZsaDZ}4vzYh~OqJ0VQ zT*sqg-*y3UXy$nu7b_e(bIE( zpJitcbud{2yLBG(oX4Lqw?tBX;o^Y=7lk-($XHty1vv$x4`9xDwWCg}?RQ4)jMHkd zH&0`i*jnUqM#}ijt+wVfI@70|-AK;0qxg4h^NK>r^Wmi~dw+jap@g$>wAd|+MEX5= zE6hseVZXaReI%CF_7dgvaXhJw<-kz{R2nu`+mldjS7#~C_PpY-6DG0V z>~ zdi9xe<)~EWo)NS4Qkx3RpBA&%>D6b(yyo=kGh@z`YH#1zo$vPODyi}&kiTm8XIC9k zhu+-E`IosRmj8Ngb^V4N0VetX%;z=Y)0?mU-p!M$GbbgNGN#07lhTiIL8Jb&CS`IW z=ABKyevoq$w6@d*T-OcW%zH)?bM;(p?t0el8av4k^efH{Cb74%rb5-VwQ+n)XaC~i zZt}UQ0f3SNxlVIaxQ>k`FU02AR20AgQ#0T!oJa5vMKch`=1cHDd>Nh#zU0mYff}4C zc?2y#*BY3v> z%6Ms5cDfg-4#guSp9I<@>yT7+EzVRN!VGgOne--X#l0IfCK0K>1mnTuNGSCWY`GRM zW?sBv@O7g)<7}^WgL92NdgF{JmtWE+x%dysom|4>gVi+|Jo41(`PXFCR|+LJkM>&6 zO51<*svsDt$0&5S331OQFG0|{Dx^nS%d6M{S@lJ@LB@Ll;ieJH2oDJyvQoG|;Qf&emSrb>4X%m8=6{e!RIej&N9T#lDHO&*46twRAge!g$J~_94%ZhBpBv3P-byz zxHV^nbAzpIi!+XQp{<)MvM=mqX}m_(+HR9PF4vi5-6N(PYc0mLw%)F_td~2pLcP z6Mk?v^6$oSAzYw^Z!EpwOug>Bpv%Hu)_>ZVZLm3Txq3|(Lc4*(+>x<6XzJSq?DLR| zg2_A4AW@HnmqZNC_cA<-z%n9SHbWO z(y=)Qapb)&ZSqkx14H5=E4xkd9ZA_fKN*QRkjI>pjhqCbWDk7AlH=j0;@l*T+O>5T zhSMKlgwltwN#RBocaG^}ryC+?w1`E{Xdxc+N{X}k+=Fa#3$q@P;76YNggr*UJ%lWP>|m!n{xvDHV?RnWEB*3>GJgWm~&W!*M{%i3^BVc1^Q z#^tIu7Rd=GC!xB=9{;d+IQZVZSV^cp)TS0s>TrK1*R%;Zt_k5b*B)sL0@z0>)XAC2 z-b=A4cbxX##@>WSL*eB02*PP+<5b`?s&VY`4RaAk+`nPVBhlncPB^ic*4nm$$61`e zgGHvK=?1iFnSnJ^Wa2Hi;gbhn&h${~HEi+I(d-#x26)crdA%@++v6xg_#PM7d$$)+ zU#M}SML{{9=hW!&KQ)!CyE^l=z#q)wBf0je8&U7BVWL4E0>WW?Um1(Y6`hYUkv7RJ z%+^*12IR?MDRW31jZyYp+C+R8HECa61A;Z(gw0(!=%lRqsW6!V=xg9XIRtWF4MQH@ zgGDL1ds#d&=Cb8e;u7xXk#JUrY-kMGgEmIv_bz^N(He)|Qtz)>mp%huiFmrgezr?@;%6K`fr^P<(yF#4lJjI< zZdPgXW~PhDlWQk@`xNFL?iHmZQ}WWntdhoIxp6EYnefHgSjlb=l@y25UEo@FTS*Tr zkNCB`_bUwB$IMywF>_sZyf|{8jXk*L#IJ0X6Tu?93yZL%rVxJ#(T)3hbJ53gp1L&1 zVU%NSC@Xafa;mv1n8Z=kvt{RJrEaAe4~Ot6Pt&Y`A?+EgfT77VSTQh|Ty8yuW zgm6;ZW ze8n?Z0mD4cUMe3$d{ zvp5_Q{ukW*PmM?GzmKP!Kii?2#G^6!7i^}rj?bBz@1-h|&lHY{(O{bv+U&&5%+shjt6JtMuXp>y4UQFsIN;t6 zqGdPQ7nxwo>-IC$@`n9v+wu$hdAC&aY*1TdY>5Y3d+x|KKZLKgJU*l_{i5}G!RGrx z#Z#Dj(VBEE)){_)$V8>uUN7wb$sFC|io)0U^c@!Fi^k5P}igu1dI-XL{YYwx%dc9)uXhY&n|fQGjP;TC$s7!`NV zHqW6S`KR^c0aSYZnD$@xbw}pt&4l&|9vD0ff zDAm4(Jb$0%+O;+kFb4wr7jvtH`vfy2de>K7GI=4%IEB3&t-;LzBd5N~!jsaZj^9q& z?np~3lbEsggi=y-Bd%<0zjy&8{3x*?ZR8!a$0_FRHOvu5wYiyo%w=x`!h9sh=iPkA ztCV9ZR|M|+zF_(_^ny%Wesi8-uE;>N1h`@Wd| z`4H1C!o1w%rD&Uzn;L!E0M(vdip3O#VIw*4i7a-|J@pLVbUNzJ-#l5U?-1>AUqP4)?)MHAP{2`%xST70L~WOU!<|lX<#Y zoReL5Sz$!J4#oV4)(u3d>$A8Jz5u2Avr+1mDODHd*z1J!V49d~aSlx7xDfH1f`yU7 zoaBBCegV@Mhj!;qXJ7KMf_(QZJlLj(!Id1#9!I+Z6U6r;NF-<~%#J_UOHSx^fhWHg zz#)b6Cd=S-Dc9JzDQN~CNi_7!`S=wn_(+(2zbOZSmB+K+Rwsd;TPX?+-K&i0tO6&7_5K+>5IV%7{1{dtbk#eXRyM{8x>D^6;{Bo+%s4K!_%I@3K*X8 z3|4r)+Ru8Hc8r1jY(Hy-E85TYv%cwy_EU}%eX+mW^Ee^voyQ&dA}E|f-u7^l?22_& zhc^I_ceFMq7*5v0P%RB=y76*co(n>w2TsE;zjMMfE`#HAVJPD+ltQnfb>;GD&GiLA zDOu09?@8Q@06Y z6-{AeqLCB^BwCWfI5-_ot@LS}WHa{Xt^O9a)sfUHe5AgOO{<*bYFm-9^mo_M@c<)}0@0=RG6dkHjRC)C*`TeM`ihX)R3yvB|N?%R}Q_d7Gg; zSl3>Mr+9_ACCC5Nt2paG|41Dkhg=2xo#O0ZU9GlmKx@e@Jp~d+y#b7LAvO{N&lC>e zIteF)0cZ1AVa#;=AHsgT1^?qvo%uHf3eV@wUHHEjbQ>H?xzFDPgu_f>vLh!>X|S%1 zhQAdtWe3JZ*pP}GM$OKxyFD<5M3uN=J z#!%AEcBx3>{1lCy*|BMG5%G21*j2$NG`cP#pSCV=lGKIa3bHaX1ul(DfolT=yEyQf zSqnU&+VydoF^m$I2tMo@DGY|y zjpV6kp?l${Ll9TknIj072%5>!BNuzJ1UJp+6=vbApXF9bPOz?8fgK1QN*`wmIsOIW zv4%I--un0&=6?bHe;V^1R}Gne3t{Vo|Gxu!cUZmkaRlXZtdIOGKER4#H_PNIt4>y9 zF#cu61y-6{3bK-&|8+IxqULk0rZ3AkKlK%-9ZAN*owsIePiy|;qMI75yFrI-v(JHD zbQjBaRA1!r&&YZ&Ip3_X|2y3$_=q;mQdI_p!83jLe83oh2jJT-nYB|m5Uq(S$ zMs}6t<^G2?lIvR{qGg46nhV6!TpzizJaT=j0}Iiv4!Ok4^G%wC9!V&7rL1i_mg)62L1>@wod!(bm1>ugmhz!__qyFy7YIZ0A*E(2nwN>@m6%Ena3a`itX@ZKYqqSjs8j1$PC8>?z5)V#|k9(5Or?bp6@LBQy zz-J84@Z#OQTQ7e9h8Hk{_N&^u1nb7xN0E4TZVSmDq5+~2yUJn@4kv`-E&DWdcIyLzUe5AHx)2`>m z6$w6niN-3b?Psfs8vB_SwijcOveXXL)>la}#}$jDm@CD;Uq&Qcjbz-mzu*_hp(5XV z{5uXK!^gjq>}R`l%6^unXWGy9>3R0EEWOBno|Rr|Kg-iA?PrJdI{R6HnG(#8EQ3T%C+u6keTV4~O#KX>ctFn&oT9^7{JJDs(Gbhbp9apKtC#Wnui7&C z@+*idS-X(Y(^zeu?>ng;2e4Lu4i9o-4M&o@P-un2XYDXNRJT?3?x+6joT5lcJGoYi zM3T5Et}TjqO(Ln?z~odCv1bfB!&~98{FVIfDxAV|$!L!?Ip|Z!;6)+Rne(-zM^3OZ zH)KpB<}4lxy@5uh72Q+6#AivVT{6)Ud~eVPN#QAmU2A!{6=!!V%&q9vtyONtIo%?; z6}>+R)CS_Y6+LL~d4?HZDpWLPDtc-A;_SNWoYHIRqmfF3e6Eev#!-y-j6^CbQHY|@ zu4h)H{k8ZCFVk`k^6;!CwTfRGvtLEXcX|E0@GHU0 z9X-5reEttU6Br+i$eS1m?0)|HYyY#u=@FP_94VjuOBbA7S7bWGW!K;fH(NQCFXQ7` zZ+ZdQ=+`dtR=O}B*;TdPNzI`~oF;mD3r?+_pxm()9BA!L?xg~$@ z0fT3%>C^jWZPs2?Mnf|&=z+ReXeB>mk!bCR(2S8Z6^2&wvsIDFN&W^+YtIhNxP=u( zp_Tm1D>At^N=owqcTQqoOV%=9(@x^Md) zaHO+WxxtdLEA$sjcrFi_+cAD!{NtBpznI1VUdlm!Gw%#y!ldTz|x z$(Z5oq)hdDsKz(aGT5l+VB>w#O#Sbq-VSUgYp#``Y5458G5?rQr;aSgHZ`NmyeV-_ZC+{8m@lYVg$l(BxI;_dt~{K$TQvnDx~8uwu18108=w3H_Q zee+xC@iUv_g@I4Y4?AJ zHMRouTF+nw4Bzz(R-`i>o6OP7N>1TNc5*5`qct9i$^NmT4A zdnkDmfKc)I7ROGg6;$tfu#nOv8Z|!p{JlL$F zCwEKD7fW14Bw5H)s@zSda9|Fnj-aJ{;ZpzDfkOGVB~Nc5ksy!d{61p(1NN&n^Kh_K zhAF5CXYPcvo=x7#9zXkOjlAcoSvVwQyM`}*TEo&sMTnayk%ozO`JUUKeOl}G|JpiH zn(qZT@M%cdXCR68`C*sX-#(2y>)&ySviyjHc~3RK9vLuppE6wK|Itt4to$7341VbE zqJQJB!++;5QJ$ZhaY~<;{2QMYx&I5Ni4OTuU*Es@@BBvpw|+6t^JBie!{#>lujM%t z7v{B7!jUKOexa_899bQBs_X6)Lg^Km)e*``RbtNjmPp9nG|LhR<;W5V*{f7tB9Zu& zu?TK_dpyF$j5Q~V*$Ny6C0kT?r0 zjvRC70?jsf&8$F_{7jU2Y*HO8cR{LyXKA<>Jz<418gAn4ztv>**U6cNUX z>R<Eu;Gdy1rXI3CEp0$X<3K)Lu8LWT-&t9a3 z6)^n7Ggtw`R?lFCchdGgc}<8DvHcfH@n@ui&A86XlGoVz(OpaYf(FA8~f&Ur9&vyh)gnNd%fEmJ*&g| z!*$f(P}zce1^eC)ZV&L;wgq<=_`F-p$zq;#q?G*oX}d5-8sd!f z4YcDon#b^2+b-DrQ+N#9i^6d7AFw4K#o4PmXy47YcQ4XJ-X4E?8lrrajVAkyJ)T74T3mbZyUJZ*W4hV-@e9;rNMFZCEF3?l zPek5c%j2820D}AHqiOK&U!qr7jD7u!`@7#PC}P7b{0Irhh_5RcwsnQ_-$OpU5I)<(+<~```e(}ewi}K zt3K^{;yu#Tu@9}+x zcq(vu3;BlTv=-0VfEgcgJjKmqfa7%d+*dL35q(83o>|)U6&KkXepz3>COy3-={Sbd z^@e-cj-P)hIMUwowEI%~+~9NADdVs~9onX{S|af6YyO!jHU%*pEm)aZktTePA8olG zQbr^4Nf_%Q+>`|~f6g)*k;Y%u#t--#V@0{fVKjCl`Ym)P??A8Oh^!8I*Ijg5eFVGvyPYXKf{o%acBGj-kW#V)i>hT0DOp7HUGhn=IJYpj?lyRh*|2Po zYz4_5<&74{iekxpi24D+l0?+LZW=6%wfvfHgA|5t2ZSWz4c-p$WX+EyXC zU|Yw*6TT_Nz%j%p0mdzk7Dmr~5VP&Hlmf-A3R~6P9$(ba^^L%@{PLqVRm7z7it>_p z`GQHsGfCyO>_sz|6yB7_NxXLdAsixu&8#TS3*ODoPug}qEvdX@8-G%W%%u9_ngSpP zl|N4z?fX5J?E%ogi`~9kgS~p@&W<#59;I-6jkeqgC2+*P-73~QXqBB$2X*I46L-JiRL;oCa`^ zZdL87*fE=hoc7wtq-&ZA>@2?uiM)f?pIL~=ThPH~o>p2NNEGAS z#!qC1`OY-5Lkn9cORyUbRDO1ooMap=YA_lDuEz%ddf`-*kIzB)?1fL9$uJ#^*_Un1 zjrbgl-k^#LUd|_!+%uq*z+c^znflyo%bU=LT{&+cdZNaMwskkf(U)6GeIInEs^&${!?yN67v8}oh0IFziE`hlY_ z9vF~aYTrG%{p@btyY=kev#~FCUADOi+rM9i@7HGGTb)rT^n@OLTYBovQ<~V~+Ix)o z)wf|AGuoVuFW&Ju#&jAoW*AOU=0cR`6rw!vrqp$8jDMITfw2`Y#&SEL@XtU`zSzwP zMQ0b|e~h|$8HR26pYsW6nlbpqEsK4Q&9=0+$N%&2{}KG3h5tL_f7W3`(0M2tiB_gR8cqPaC4^v!LV7|hL)NHExE9aHGz)C z;I*YLT)!{X?n1;@+p%_6TefU&OWjz_ZLBl5Uo73;C2S&b);`>g+k+jht}HU!>uB%T z`S)0HeFDt<%h(o~(i+;I3Xq*|x7XY8oY-Y-ZN52K&WM*6U0s=PR&?4`6EzzG9D&yg zm~CUl)s>+Da|@ea*il+jesyJu8CJBmQ`lUEmigx5MtV4>6Gyv??PI)wS*_?m4^+HzfP)y6z9^B5VOd_lAR&m>C+e|?wVe?@pZr|;Ab!B_=O7-m>+ncY{-rg~6 z938|m{xyIo&s{nv4<`oeSAjJA9EO=R8>xDt~$Y_7E#F1PkO1HZ;k z0uE1X#|RnoGfsHSWXxeK=ikLIt?8R7&BZ=t2~AMf5qqF7G-f|a?J@ha6N1O z+V<7T!Mwe&rE^PI!t3m|RBTI)D9r(PvdgQL!*JJxxsJF8JHJ}Vd#H$Qxz~E>jbjB@ z)B_2&JkOR2Ot+3KosXYy;&Gs~kfr`O3$S!~9ZLi8OqsbX@5bmio8`9d`U2M7iW1}P ztz^90%=5PN{jO44jc>#Y%m#4lP`BE0e?;9dGt-qmwxwC-MO(MkW_GXHX}RwN$US6s z+q!kO?qTzeEgkJv-gTIH*t}~?Jqq&i<9%N@zqio~Q8H$U`Os$lmy-PCc9a6>LV2qs$htL-q{F~14}>rWufcc^!}p@!352Q&%w$~r3^Uuz3$_lo@+fUL z>ul*FTiRjP2XF&r&c&t5cJp%_2k9kk>wa!F+7hbGI`a$jBcIRT;CFAZ?le zHBfDy>pCZ=+Vm~I2ixna7UYD(e+w?ixnj=1?q9`rm)&l!qizXtyQP8K=GNS9uzExZ z^}|)%zF;jK8^4&9S66cT{VZfKfx$#ppog1R@xzDWBL zo7FnoyZ-2%XBSr5^t7|0%x?2+@9xfKUmmvG@4|D~)K_*h=a?vKzR&YlX(g*Ah) z9TVsN-B!h|SZ*tzK3T*$aKD`i+(%*aQ5PJ$O#e8y!#g)w4{fn+uzT(8z}?9IqF_C? zUk=W}c5(1NY-<9GvHdXcWGden5T+=P<+do_Dc`Ch(~XaBvL{TfQV-{8Mjv)@Ju zH^=thtJ$xkgj-%$`e((raUJ#DN){Klo7-i7ZjPDrs4bZ%3*STO54QBE`CauU+{?rs zW8I^sxnL9SYP!490+eFrN>_TSO(U+qavo<(>21C#kW$XNilMmrZ|6#zDhg1la;3M+ z{upX)y1LTu%l??#+Vqf;9kT*+t}VTqyQ%G=+yXPum0IE>a8?@ZN;QQ;afTe~O4pRI zZn!Ho)el5zv@6ZBrSZ0OZ_Z=I&r>z!D7PwE0|%TB<{?_KHDvOu)Z{LPhiSKJ&fG9L?P`(9)MPuTIy zc^P@)%{5orT^xxPnIc!pZ!;9vy6s)5W1C2{*mQEG?-dQjGmctU+E!G6(%G)GA9Zcb zdA2k+=Md`Jn!&E_p9QU>C1!*xwJL0b(iN`s4swZ`uRHFZvtC8%8?N-kS>MTyo0YER zuTj^|tZ{WmQPG3X!Xqox5 zE3NKQgVHfqy1QHV=vfB8k&tsRXF<1KD21Pt(x#3>O}WW;rCl8hP>Q?KZ_wKgroxrp zE9i$3UvHw9bL#$CH*Hl~@tukM9rKXCp z(T--kD=n;;h*w1?xze(V8>5}gO|DcLzciXKx4BYXd~CGZw0Ka1vXr1|iEBzrcHd=4C zy3#S!bu&9%DO^1^+F*X^O7|CiE85+>?MhD;y%cRU@4M31<2#}~%t2RL8UIzZr}?`p z)inMtdbar=SL)sPXOyy+%2=P~r$#bQPd)%1S%apj%-5rMFXy3t=9_UbjQWsY$ zNQ?;dHVv*+p13iqx9Q_bkJgU}^f4E>(l_gG%<5x?xzhB;5rMvDlq=0_yfLerR?rQaR+J-;go8A^Rjs ztz79lC0VfxOdD6)UXq7Wxhrj`i^m3-gez^WI}4?5u2dcRTkb$}jxEj2=@+^%I?(iY zb*)f0$P96HrKlTZE^~D}(q3q;bfue0I>s(E6QyJ>L(9SDE?3u~peA;a`HCxbD`-IJ z0V&~F*C#f_T)oWp2&IbXCFXG{nS$~`u@NTcDO+bQ>F{#)rKZM}E=Fmjxx|&;t(=M9 zEqA>ujVmrNqfDD`3fBSOF?`X~xzhRdGf}$Im0A}Mjg2;)pOcpH>Pur|3|}+E>NlOM z$HcBM-*Kg170onPnpd8ey6cL^$Hp1l(%P20@uc%=)5et!;#hFC`MxW?oxCn~jrpl7 zttx&w`&!d^wQvhNy_`MKJm5-0k=b?T2d?yL+0@u1{NSCmye)eu-sP-xrB}M%61(2~ z-Icz8k+|Np!a*vB~BFS2|VL9GhZpdO_-*3XO?PHFI34sMFloH1n90?Ab77 zmb=o^7{QeJmMaa#th>d0*Oe~Ath>c*bfryghnic>R#$qZZ2?L@v!z$f>hhtu%iJe* z_N>NxPX2o}k3O};bFr4jR{2WVXLSpp?tK^G(blXx=t|GF=6&qnUFi>XL-7>%e_ZMB zbp%B~s^P}0X0ybVnDyOenJY2tyUn*;>C*0x;7=p})|Dor zG|RO6u0&XY(rj~?E3HRqj+t*u^UNLH3(Q>exGTMi(pSuCX=z7do>`wMJ&8X|`g186 zu8#Sp%{m*wywLiY*nD%XEzLDOv)9D#HOcR>Zm!8e=|1z0EiE=Lgf_&!YPznM%-${= z6?nj$?MfGRV`;oAnJz=k17^A_J%uZ>2h0pxnv2Yy3O!&Ru%$=M!*ws?k5WDEO2;a8 z#TJ_lQpz#iUXDFtev&EejV&>Mw55CTEcth_M@{Ve(ubG3EDbzvdbrY>tmCmK%w?|h zaNWt+ljc5Kdepp~%xbmN-1j26#pZC~xxuGR@k`dr|3}={z{hn|_s-mvEGw2QDT-_q zTecM0Q4~kA$4$GBJ+q(^C+C;>*tHFt?Fn;*k8N(awc>=iMlq@7Bc@-l zduCr>KfmT9W|NQIT)z<5aD-Ew8Ja&+drikhH6b?Gad8AYbxC)PI6C3{Uzc1S!5E+2 z%MRebGqsG*0<7|a&eb*I=$Kb|&n5je;)Vnp=^CsNlM`$lSL?+*1j{bmRU?Bg*mvg* z);x$5|2tE84a$l71gmZztC8*qcK!Upn$M68|DCC7Le8;@e#~wnt@0vIJ*q2c5yXN=&0#R=i*iDrPoz{h;Qb&0h(2_w0MRo~rqw`J#`F z_YnIBpYySc{}tHZiJ{+P4lVt8&5z9sV$AoLWy^kE^B<;FjQJk(>Yj(q&&`!S_ObIT zYky&G^s&v2b8CNPCVcFdjSm~oKI&t;S3ZnyWxW0oYWE(qyzOCAVej;@#ce0?wBg%6 z_Rb3)HdVIuv~o7B>@&0NFCJAa-!u@;71LT>A^b&X}LKOyRqTTV)EKF@M{&thUasktwLPG}w)TDQAPd!N;k>}UJHpvy&;L@``h2@kFs*aGeU*=~&X?JXWy)*o7us&Y^c>|vJ0h5tyU5MWztSK3T~y{h)*_KyQ> zXYDKPBZ|%bYxLn-`z0TH41KuPJ{EB9t-a1Z8(?^o!2ZzZWZ&1?pZXa4zSbIX#Bat5 z`+TC$&h|0(z0WrI*j?Pq*k&L5<9WAMtg{y>hCXC!`|Wjp-mS|fYd6{rKDK|^n}BT% zINx47U~9hS`hIuq4Ynu1-dnrbzB<4@RJ+x_HNgI?cGx}~V4tYH#r|7>eWrGYT_MW{ z_4#P+ZhI)e{=PP29}lqa)E=;xeciSGgWALPF2N3)`<6XXeV46~W#`SaPh9%0Iq$R= z_}E`wy1=~CwkU=c{D#u+REf%fhwx{q_+b>t0xi=WSp1vDYG&`hb1R$8w0JK48DC802i8`$7B5 z0IM{|?Ci&!J}b?i+QtZW+%8f~to4Mw*vHtT6LxvPxwrNsc1?giUhz@8&F7@meaybv z$7ppQvm*g#rTMrW_w%T;`|PBTv4#8W8w1Y9x%b<52UsPZ1pY|``-D9a!T!R2B7!|& zKdad6dYn&u(mvv23voX2N&96Vdlvh+zqF6}*pFK3fqmP@K8n-OPuXXD?31na!2a3C z94idR(+S`x>tvSe=hu(fO`9pSJUTY)$6^^J&|v z7{hbiHawW_e`<;g6bN?#99&32z+>>_W z6QR_n>{h{!;EC*Jd&-XZSflNod&(XZ?5zFA6&6ojANnrKowe_3>Hu~|Fzw$X_8Wp} zA0Dw!3U&nV3tT_<5&ILr9BVmkFPjc)Iqk1Nywmad4#MTQJ5UPianbYiBGNzF5D#mc zco*vScIMu+FoeUqjtKD^aASi@bs*{K7l7@ zq-^RW+_-{eKi@+7;>$?+Q6p_b>(4_fXE`fcRi~tAD-SlZ&W$S^#kCl=o-mItW552k zhdlo;^f^z*0-CR{uQcP3iX+0@>o7)%m#i@-&%KK{nm@gW zHNO^;hjiBLtcX0NxwMTa&rD@!=5f~bcGzLG-I?j0SOuku@`rL#58s;ST6F2ByGVbe zj`VWtRqcHqBdhjYVSXlailtmDPjs{FOqTQFbhV!s=ZWU3?dd$y^z$;KHGK)jiz7uF z*oS$CH>1Vh&XjutW|Py8^6bMLOqiYGRic#A(R8I=E}r4)lCie3x_PGCV{KQ+dhtqW zt5U}3YtWu*%rlz)e@%H-=0a4H(ezK@m)zVuPqg>p<&^OM7hPq0PNY)FXOiDZ$Z|Jq#KdVPsJRp#Tr5$A04z;D4{Z65lq zOPyy<|2NCdk*{T2^FCQ0b#zqckI1~xF^XE_MvS8;{iq?ENJW|43 z2ajE0-YV;qwi1QPUueF)Ey9>o3o2XW_wF@6JJC2k2Y-3E9b?kK&Xqu#6**eh^A;Ee)r5ttO1 z2DEsd@P>{i^FB$R16*Kkv2W;TGiiyc(-KV|2F03h34Fb9c6uLP*=;(#J684po~`Qx zdj{CTBmoa>!e9~ z`KFWL=b37ot?c|NtWc%8r}cZdiS$&%EPI*23(Q+8uCOE2_Drpz(32sdhO@%A*`WRDpSXRU1g)%LJA*41a;Ch%_W z?Oj>>KJWI{NtF5=ZoOP>_)KQXQ)%A@?X45pK4U7|-)=83_w~HrK47NKKY?^_>ny zo4ii%TXh}Y1JYvB`(}HWm-L1@y1ZV{S0MLG=nEx(rFYmn-P7+4i-cp4>L#yXZiloD zworMi_kj5cp4@eMJuOq-DX*>Nuy+hR^`O*re+c#5e(Ak{UC6y1y1l~Q33$f)7RKVc z-dXQ64c|xlj)mX#j@iYn7SExcn>PnfoW8oe3Glqd?TJ%1k=Tg)++XRw39_+fO4#9j z%wFBJ8jtchg4ELH#EBrCP24ZH0`C|7+%IIGJDy6MwcX2~Pn@$~TJ}QXXI^jXzb0(r$psr>$&WApS)#|gv%R+B z@1)%x?`GIG_nez;kN0p-X9eYaC1n0o)5ButoDpAJN{d>Fn-y*LIgH5N-qxNh((TJ{ ztT-m~s5$Y5j+>DlY=0eKZ~JIPbK__U?+U5lBKQ$-#1odw3`(76I_N7JdsOUjk?*?3r8)ZHAsS3hJ zao_5&cewMeDk~q0Pk4&5a9dh4eVP4%3QPewLF6Q-_Y^ZO4j^H z<>3S&XCmQ|dDE2*2-=C>3?%w1cxP;!?@?h>K@LVUtqCVkP}Rd>m3z02^#h;1uWm((n zQOe?N1oBVWuSlBwv*F3UQ8gR4-<|+mXub{DVh+rnZCcG)q?efQ0bXK$0C<`C5#S2* z?|@gB{{(!6`4!;R_(`1E@Sv<=qtviT%5Igi!&3HDQueh{cBhmbm9l%K?3k%W4HITA zV8Jv39yBilyxp__9x@jJ-f21j-)b%cyvy_ezT3PU@DI&ZfPZY(0Di#q10FTk1D-I0 zfcKhV!28WDfPZ0r2k=v71n?oV7w~gt9Pp&c0sgJ%;qRmue=ogwTzc^j(u--yeMWMh zm)sYS>*1Y|+h==bT;P!fY%{LR@Ky7D*@~lwK3FRXd(>B>g#H@9%cagfGlF{ha0~Z|s(z_|Na!O%9})V9*=N30KZ<)V zPgLcF=ZNGUk=!H5H4S%4?t7%{amhU{xyO;)(Qra?PnwI&lXWLW@<)ZzZrO`IOZpKX zvX94+o~}D?nLaJ_(~^E#(oaje9q*+*S=WwVlsi-1C+VFY`*KL&5uqHB+@nG{E|lX! zIVqIWLOCszrzQQgq)meLBoeGYkzoCa#BosCh0-pR0l?|H5uuC-<&cy*B9x<&J}v3f zlKZrz6BSY?zS450x?R%kl3r4Ap_!`h6u3^{0O0S{j|k6*@Qey2ExAX8enjYZ3jJ+D zKQ8p+LO&stj|n_2^wUCrR47jie` zNgo%U6^RK1mStH3r;ey_ew(w(@iK3%s)(!IjjE9spAlR`;K`jEiG zLOCqyqXLf!JSp&$rP7gl%!8ddRpLFfu@#iwF+z#xJF>Fz?}k<0uKp1EbyqnlLDs&nz>Ss zz&3$v1ojF{3Opq6sKAqRIfG70dRo%ck~VcxkH9v8YXtTR+$k_A@Q}d60*?wjCh(-d zQv#<2o)u{8rDlO`0@n!a6_^xwSl}^%&oo?U9;t6TpQV}p#JhXvj#l%tY9Ch!C(XR1$1`jo(FfoBDpmr3gaTLrcWT=FvU z&ywzy^iD}9C4ETJhb4Vf(#IryLf|QZX9e13*3%|%Ni+Mqv-ybmUfn1tPu3k4`kj(~ zRNz^m*b7;z^+L{|Hc79!ka8v^eOTbJ3t8Ib7L(_sz-fV|RZ0OqS$DLR zEuIuOEzq=y3QsA^ebCHx1xJKYkfrkVh6?jr$YdbmD2;3>~ zkieq?PYRqCXqE`4z?}jQ2|OzBq`+x`YdYAMHJ6fqr@%u3j|w~~a9W^QCUOcimq}XS zA%RB)o)kDO&~yopz?}jQDP=k7YXlw@cv9fBK(j(}1@06$EztBxZ35Q_+$r#oz-M}> z;ntN>R^U;ACk2|zrL4edf#wRK2wWp@r@%u3j|w~~a9W_bQuqa~5qR`Uv7(oYJpf{T zfB6x!wEiU0PuA^RMat1t?}t<;R?$|?D})oTPwXS%@~^(MS`d*ASW>2)R6B<@c9S>lnzbrt;;w^iIz@#htvt@uerqOz{?6_we_ zLzVBZ{F}8o3r{_!Qd0smFfcT|x6lZ#0|-cHyh{1*%SoAXI&ZzQa5$O2AF z`U?vSNdHuzX<^!1dJymv9d`i!efRGIe*GerYL-&3x{NJqy9XA(1?gjp-wn88KGVmS zybtj4C4UO|k&8(A{!+s8E++iY`JV***!)v~SM_`qaLY={{O(1pzilbg_jVE9(L;D3 zLAbw_@NYyjDd8NJ9#yYksaq@m0q~3Sz6EA+WrWu)YXQ8si|IRh2>(UOs_hxEz;{b8o)CI8_XA>wpIg?3 zQlGw*I=Ob``# zdBk{l`}H)ShqI3aX5s~av(2M;epQcKPZgjy@yjrnjg?5h4DTiL`|;I)7vki>!_2G& zTnN>AI6-RwT!fnVt?eejR=j)aVYW5{UIbpxw1dmT`PyQ@rO4s$IJcwzWq=;e+Lj{S z1&HHN{4xUWtN?mAed|OTXWK}x1h2)3%rc~}0I!GHz8sX71LCd*xGYZSdXQcXE(;%U zInq~w3va#ydhl+mkiHg>zy8ec;;aGWF9=_S^jbjA^nuI53tfYBKe+IwIiP1YfD88( z06qApKBTV)^l%>3kMt%$&uj)4z99hU!G8@Py%i9rTHxY)ZZ{x31TJfa0X_J(L8Na2 z^vuoR!h7g|9(>&p(ys>e%xl2KH`ul#{W@@2^E-f^*#RzVb^>}P2`&ro_!^`~z-941 z+Ut-`feZIz06nt@TzFp|&@*XpS$v;u1nGU?viOcy3h8lhS$ubA57Jq1;Z1lz4{wd_ zLplfO!QYMp7LboGR{(l==j!!H9{}{=ee+1;9Vw)5L%xMCo<#a~8>k&g_tH&7T5#<~X=4&NmMu{ZVrS@Ls&L>8Mfa-dOIL)NZ5Zw`es1Syb5p6 zSUeH_4$?dEMhu=U0^%1l>{+B!fS%cHpGJBQpocGxJ&SZ25cX`JLwXDlr_c5r(zgM6 z`1;TfkbWbeXWnH08RZ13(XVqko3-`_F6!YHq|x7**vGrCXN zbM}{ZtM^(waec^3BvvNYCq@!)PW*A=zQm^ztra&^HqE+Z*0r;~JnLJtW>;NU^~$Op zRby2Zhxmj)`rnyWe3Ujq_;l5O;kHpJ?PlC7Dy4k|H!DhMe}cPsrL<4rK0z_+r81|JGyW+JIGv-$WR|I&?j9 z_}>ci*aH4tV4uhH2z;>6|NDR~bgvSx_cM5bcJB%E4(~bhQ}2hSCGjh>BayH>5=(7W zMF;*Z!@uSB%8EPek19TB+r1Ckw^!b0@2UKt-Gb*^KdN}n?w$2-;9rjXCT~Y#vDa1A z?!CHdu{TxqLHmxX)!zT8(%-`~SN9)GjZ79&Lwi$WV}052@nmN7+R+_5dRCbI$+5{4 z{$73U>K!{)>_B2$YGN!olDa9GODA`YrSjMA@-wa-*|B3?I*;6`zOiIJ-?O@h{H5fT zam1c0VyUlKC1f<+vuZVy8&ZXJ>0D~0kj+gErEg2IaX;(kWV*0Eo9jQAF7)Q7G9x0F zxq5v%GrB36*)y5kBiyKDC{?&Qo7;!aL#|JcIbvUSVk&~h)z*W~Orkxreljz%v&Rf4 z^ZTH!iLq26oy`noCvzhykhe^ZjZrg54)kXx$5S~UBR`0}BVY$eYr6{+UP?_V$=PsltwdJU%m@cZq>a;qsN{ z>YT7&d*zNDKq&l56@I0;i32-43E_9HbRw-ZH>9Q{V{0;<1ASdu#7pL;fQTuqlonUI z7FW6!QT;?NJCe%h+1TaU%H>+-asz2zeucT3z3_*KTvsU96|VU!lpTzIRqQ$$uhb0x z&&w5CrGH*Q)70c@bM@xz=p=^JY#mD$c4u?r_{QhZRKAcJ?;aRLyhA+=4!ug*ckD33 zse^^yTq-FU>yiacU<8t*M5xUGk+Qk;o^&QT77)oXSW1L_1q|b^F3ba8X`7QHzSfx9 zl--jaaYBX`k?-D+%A|70+Ljv0=0=AK$pS_kc&TMdt(%hh!p%9@$Z&c*wY{JXlo4s) zWkg6@Mq^+5pcmR^w8l~zD=ejnymw+El^KQUjVB8QgF2Wgr;&4TvM@1OC}E8uQqt{dJX`hu65lqN!7w^%h;2z7*f0s+ zt2u42-M3@M+T@6Oq|}&FSC&(qRh8$I+F&`yKpxgsPA(n#a*mS0EN2+-$D}+5-7Y5v zIw;R_OHY|PXlFyI-2U`Ps=U-dCSOQq;&S@3qcQwjVyRfx)PKciZ%x6uX9`?I%A{MD z+MR?`eleEq6Jy!rsH`t##kZy4tYCogxzUxXtmu~Hc#J%(C_ZOXdRGq4d}fB>)cC|! zEGhBD*JEXi&nYsaat%dos62OgY9gi=LnFELL?J$JAcF}RpVd#-F_BB>W2zj;>`&$5 zGPWjjk>T4u0q-AEd>ed7Dn}Jzz+&>(r4R|Ewx!0iak&HenQ~;sEmzCUdsCSivV4o1 zA$Lc_W+X@|vl|W<3a3YZE$8}NDl@XTT)6(sp0RX3Cc{}!c@f|EXkIaysmz`@`i4|t zIGY_~A;e9S$+7aH8(cSV(2^SP;vz zAf!rwwXeXhj$faTW8=~_nS+5OW3vZyu&(mTgOy(cfjAbdoM|rA$+3aV?(EEbh&A@a zl^@8j<60Zj__}PS(6<-ib87Ga*0FNwI53-&SYBty+n$*zSLe6xJhCyR!wp86`Sy;b zlX>hs$}@6%VyMB$#pJn-v_W~ zKxML3H&8uR?!ny6d$B_pn!xT|LvPq;KEU8-M)nQom^r`z!H>6uGm101jpDmYcwIQA zdmKMDGlRQs#a4G)YIlkYO3LJAw`|}!82~d-^V2IOt(^yvtpybB?FH$}awRXwKu2ch za27Uukiuaf==YHcR>H7O`=VYrz>5MuVJ)Uml+D=JBJ`8;gS+xsuJchEWbmUysUU)~ zbXj~TOy$(k(m2vY4=>D^e~N+MJsI6bmy831@d<2$`VWqXi#F?%`%-2%0SpMiP8O-P zDXffsdYA_h&MKULHJg)#k-e#WfMZOe>Hf_AbS|5rR|?47HwVam|0F1S+F=HG5|qtL zgX^-B((YuYfa%PzZ6gktAPHI`wmz2~_bF6Y7%PjOBIr<3qhuL}XxQuzTNp>1&DjWR zB+3!aC_X8{UX%ilA4TEtiV4AiLO1n~6Be!>-LFnh(C`cv8_c1CqzB+ZCE*U2%x<#y z6~KsTNoHd%4-&MwRl27`wf(n&_!BC;f)uOaMoCGE5>2-U`h0`>r5PNX-& zup7=GU|^klvpJD7sH-C%XF(mLh^b8rYW7I%Sp(X8d_0=K*xd@H9S2SJHr{ zCkv7-=P#0iyXQ$5Wm9&cQVZDjOB$B5i&YNDu^&Uc6t?GkNrL$m;rVE08Wx491ZI{W zNlvJZa0*GcBq4hONg>*kzbTwSN&>2tzg#!_$5Ncpf>W??we@YiE0-35xd4rhI26w}*J z2IBZQ+i**Yfz!$z;4z-`Q#o|kC=C}8WL*3`rK-vy?o_k4fZsscg>!w=KfWt9I+_{{ zDRf;BHYcZy=zSzhqll2zg%cr#YjB7KsqI`N1I(;T?V8-Phburxi!K}?)t#7!6e=>r zdh_|z_^z?3;dCKNW^fo~!l8e3=7d>p%N|m6Pa|_BB)Y@zkTRUiLCxzK$REHHgD`{V z`XRO!JJeJ%6B4xRsocgiv>u@cJCTsp^^HBg37ZA1CFPmi*758TnaQy-u5GD3lVeFd z`EZL-c?DQ&cBl7D=A?=+dk9AWsa%M!&+?%|h$CL(f>W5{%9Ic3^4!38A@tgjEVQJX z(f-$Cw_cP%ixUC3bRU#dB!9~!j5G(|lq`e|4PkPQL~y4qc-Ya&Xoi-?xp7!lNq#IA zlKb|iM)u+CBElKCv5-sVP%wX-fueH-ggzmg{>oTyE|;7NiEu;7@e&$Of0CnvnXw3; z>x_hPnMj7e774wO-jyCp7b3Y^8S%;UI+^y{^ZMM*(bi63!VimSix<%pL*S4WY|5mD z5If+GoXqC5o;~@FNDer|nxf}V#t&OH*UcfbV?Q4-nH&U#QSZmX00U=KhKEWZ@&TS; zbZ;Qin?(Z^o?D4_EH!|0z=MOk z&HAzA9v96G@6BO=arom1{vdYy)0H_lCvzG89nNl?#2FJUg6>g`2viBg=+%lT>)@Y5 ziu|sf8JgUc*A)LuY~~pTYF>v$-}Dm<5Zp{4&PWujhk4R@Kgp*8i2lvcfi(XNXD0!v zIsbf5cwKroMv&({jN3P5N0M?XCqcY_LTBW(M_5>givgvQ06}4OGXY=ZU{D7}PpKt; zERvpJ+pKt#92P3CCJ`Fq_>kKkoM#|`bs$&JBnxcDyxnU?(?-IrzU0{0E^KxUx}b@h zQ@i$Nv-_lSK6I1>rynKOFJ^%TDar02=@@jP2N9P8^`r zgf15!Vv6YHREk=1nkk&6H1f%zrmBF)n}!ZcX?=VcGUm)M`bbeX;oKXKNt`BQhwZST z2k0FG5uIdonD5r}%8Lhx+))!UvV@sIOHDI3PXSlO^#zc0sPg~*CY>TrM#Zg8ksH=pq0vQ2DA?* z(4M(Io5sB|C~sgSo8fq^OYcu}#T8<(I7{^*rm;eZW86X{lR6M0ta@((w~pA5m#p91*pE+U5R7ugm!3r;0ONa>C}}i>XTup~cN?12ZvS?H?(joHFdK5& z$%zOKryarEZ3#H}H1yiBT+EU=4^yP-Qkt85 zbght+PR&o!(fLVt^p^K=-^Ltcb~~TPNFTX|>H`>QErL=YqV54rkRK2>;K_%3hQU*b z5TSwiSCY7dxTG}Om&~W!MGMhK1lutRjfI(vtwL-|HcaoxL=b;t;9uUzvBi*cIJ+r( z0G*`=!HKm7X*r{NeN2(bgP3nD;s-G(DT?Wv%onob@OnNjCq0q_Q_GAdbE8V3b!QObGLJGZu6_A6Htidg+YMi^&zm0RDr3pa~b) z$}GrE%#=-s3+v4V`MN2_WMKf3$3dy=VMcinpGR1&SM>7kIGT!bt}+dVJs60lLsInQ6KGx_qqN6brV8 zk#RwEfYX`0k&{EjU);J$)3TS!>oqm#9rGj~Tr1?JBkzJ6OiOv-OnHkRL5sq$K<8CF zCVY*rP3F@hlH(I39knW~`9dr6WzF>958DB$yDYHM zdT=D*p81M$qBu>7KAHZmge`_VMh6q+n~0S0dmKhq+PeQpP+E5BV(;asy0i>UVEgY# ze4^me=pA;U`uN%4j^l*ZFQI}ax#EjG`5_rs6CT$ny)i;O%DxL?34b z`mA0$qE87_M*n%d(1WM*B5#PXID&Rep9~IeIZLorFsf6tTUJUOPT(ZXf9`6s^7s|2 zIJX4m=JY6Pz;oi!O{v{@i)LcS0Jgg6k#qqu8>|iM2`5)hE|dUebG!{8Qb+=u6I2sk z=M@(5T7x-1NRpG15L=(l;b};aIjr{xq@15rht2EF{$mlJPE+!ed{XEqeLL{64Jib& zQWO){Pvw+=WeU-;LC^$~pibp2S)GhLZDU9zI&n8ogfBqkNRT`E)Is5r(9?fP#}yKDQ%M|s z|B8y#;L@b8OHScz3GYvEIY*mvhU{;?H0{j^OQ~ zG1PA6u$-T6A$_lp#g|6?b-j3FlalYj+m)yd@)zNYi}T~^A-}05AIuOfqLy0Lq8Q$T zL;nqq@C6FZpiSZl*|L`eaj2110TDFTatGI9{~SlIT@PNwHS+CZvQmOd89N!HU^tSl&^Rpt0vs9#=k( z_jaMfO8%u4^G)DMj1+Bf3~!{e?*-7Tl-4{qavT%#n@*P71Ktd3ne-)yvmVpQ5>ZZ_ zZRJ*Dt_AIOx=y*MkOZ(#kVWyqJDGa-l4_&s3cV2xyNo5`i=R%m<@xkG@Xz8*El zX-IiFN5^4v^i`Z2w4)GL>!*f8T3DVmj`O%NSN1~|{OTv_$b-s$4+0y--%C(y5^uj> zfp^tcptn8ve}%pQe>umMr8q~i1H^mQ)b)#&nXmn&<+%3fi8yAY&{yzpTC9$~B7(tc zi6zT)PW@)!jZIrGApIQm8#~f%$p}ZBUns64ZhYAqTcND<|GQN4n3amb@?iHaC)777 z)Hi1IHG`PZyQLiG#TaDO663(s$6bQ&0Z`9f_+9}2w&GpVKD=qfQk2JOYcEy+=&_Q2P19zyKOr+=5+(K^g}R%lt1>FqBuX|Z z_EYNJ(3;4H(wH~o<2Z61q+cn*{d!z}X-!%WEDk;S~xbbfIr6t6<8+gaoR^a|b=vxj~1F~3KOmG;MJ=75YDHt#6MF_DM^ zKHpLN@y9H7l+w}Xml$Z}@a!0U%0CGyLhm0^IO6n8A;pb8OQSc?Z2_aBqr^PU^4M9u zjH`Vq=M0*?uDDiuac%ddulQ_>(oKq-)GB>f_Ct zA5ubVA}9AM{Hyhh!6M0tdK*b)bii26r=c$TJyLWeit8HlYZ(`fab~GB5nRS9#7q07 zy`sJBqSZ7|cFxXV|J0yTk>b2rF;B5Xm=(3mXC%tKgsElu0F(OjqA6!tj7BjhEBV({ zYgzQ8TFW7|z|rC&8Rar<8(~ie1CMP*&@N=ue8dS2E>fcx|ye}kA$^0^Nb|E#Y zY1j(W^gFUb!*a=Gnn>rWmy_Q6{=SK^(K*nwKArQ@Hs1`G#&>9xH;f)QcC3YC2Tjjm zojTGggP(@}96fIInMYfsmu0jlyD`{w5iTuZY|#=RwC(&w&dfCDl;e3w9j|e_JX*_3 zS+yw><{NB?G03eF&Cr7x*k}m_@=BZnNx7p`pB^je;xP80ocumrSORv5`4i&wPQB1T zG?q|)Y6hzu#(=Rn&kZ;RK^kM=(s5(JJX#QE8Ttd;_fzxx(H8d$#d~XxJUKXSoPX>C zR}18LamGS@{8xYAw!l{4nJ8+i<6B! zZk1p}6R&yBoD6EE$BS7fx;P`5Pyg`iV>((UB&-{T{InE*jc%Y%*o9f8`$0y~AxG4A zWua+mg3;|-z&z^n=Owfn;=W&l6*`*pWXi=lpi_({{W0b`M$=EtceF0-PH2^S;>FPv z-wn^n*+PxbkCGZ-@E9Q$m77$yiIEmx&wlQU*SM_9njfQY@w1v6H>L&DO5g6{Q|KD= zj$_9;NFN9}ASH3e8Pt2I8J<0H=1#)L&~iD~zz^Lhg;uJmxVD*N8p*+P0iDgX4X$<} z&9xu$MB7(CiFz=)lrf0cp=Yk+oIj`$JqWR|2jlSH=s_j_a%^>tr2KwLX1J!~dN9Sh z=k%eDQJK*OU$hR=Eg`+MEO#2pY5Mx0G1@q7Weg+SD}A8$$-!8E0MMO1#m>3c(NAdH zr<`GI&3&;(P#sdUa;deqqJ?PNDVeX)7C4@EDB3=Kb?LmN)xEl?Cdxxj^*M3=m3@PE zYTh8d=3Gvr7HW*8aOOLQ-pWsR+z_PQ*u|~mMs&*9jrGvx>9J@}Y%PM%XMG{=>eTX> z0r(1k(wGj`!Z?nR&Wr49@O9fLU#R<-*?1LO)_r-n;>Y!6CY>RgLhn-05a%AxKiRt? z99kf5+Q|2!(bH0LDu-G`>{-yN8v?H1EQZqBIX}3|;QD3iGzNa&k0b5;Vd$1Qnjakr z+8##&u%S=<>Nt9v!~f`W1Iy6L0t$LtOevjnoN?q}os@+9v^1XzEf(QYUzlH7o6g|9 z)U(v2@^kD>llGBo6YG2)G{k$0!=AdRpWM+N%aZ{}2ao6Xm|l@~ikZ@=u_vD&C=K7n zTj1*C$&}-C-jQw7FZM~l0^jWSla|A_O;a>Kl;$>+f}Sh+m-9mQG9uNa*st&D;qUeW zr$w8lVT=t^%nNHG2jig4kdX7)RO=2HsfbRv-f=g_6P4n!h-2YN**;~?qOMk1iFm>$ zE9zpE&gF8}ait3KOG@K6o+G(x74#8oBa0EEzHtI1dWztSi}OqELF<9W8dcT_^yh%A zE~pz{x~Kd_wDxko_&RaECVHnoW$#n?U+uq$BK8`k#McJzxPUElt)x^uU8k4a5BYF% zzF4Eq{i0btQ#}Vga|M)L%io{BB;tc5#kH!~Prkj4_| zON+DONjW7^`z^KsoYJ61KwlHwb?NDm(?o>gYa*n?YXU32aMFv+yuYN3x|+rMM$skn zOWRQYFixG;_CcEyuq)9pW{hGS#T$a0aMm)H)=1B${sEeUzjL^YR9V(>INg(CD)-TT zp($dVOAogQ(W=QB@^#&fP$*TnUT?UU;^^B<7Z^>(Jd z;koDyFTHPD#V)x2;xh#G<3)WO`tSA;xAP&tw&0IlZ(J{?@p`#_@&)8lgYY$Wp4 z8Lxcd?9YS4EbRj)YvGN68NDKYlYup|X61`UkEQzu0}E%JA-AUEdQ)!U?4O(@&f$64 zn8;@8813-6ksrgrkMeY!BNX;W&&x-+v#VVPexBcO^h_;J?gFeOnpbW=%BwX5-dJh~ zBB;7`c#0TCa<+7w*Cii!sxzGcu!QEv z>^T})nh{a>l*fpS&`iTR(W*Y5keSjz+o#W^yh3R!<%!c0%b2Aumf+a(Os)KRR41Mp z(dUdv8+@ihPR=~8vwYIXJn9de3&Q&1+k}>DH=vGSpO2?>`aDth{aAxAI(jq0SqA&Z z2!(%56>rX9_QOK57$aH`W&y@Gg26&UEKUxVGjrCVYz8{Un9t#E-A^wF>2YPr$JWz` zZg`6cQE?+>=e+~c=oi5;pV2c{QAZ7XLoW6P5HdJPDMOIPXmh5Rj&+b!V?EZRK9FOr z&y(FfBGWZm#OGoyUGK~0_f=Xeqd?ZGlD*W~tu2`an;_u<84E_FTt5OYhVye;1#ef7 z&btQKPql18Ths@~Pjgrz)Qk8tXoUM@_EASQz%Z&VT{zAo28GV zG7_{~T57l41#$O6E|(i3c$(Fhfsdzbs$b4fO4kZMmBn18PQw~nW|VekKW}r zl%RF#nW%wxDWQOu6k0HzL00$69Rltb@ogLQ7^x~vnWg=xX9_-oE0fx;p4*RzW_X4M zpV7emisPb|ZR4X6irR-oo#ZmL{W4>3g|uj?md_jMD+L3O%;seqFp7*b_DQ_E8PclN z=?M17t)R$M@2rt+#qoDgZ#42?<=UJLoX;3nZ;<-{&>!h${_@7nL ze7zf0Iv3oXDBh0ZY>?jv32sNlTYqesmZ;UM6e@Qp7c9N8A96FU*GQSC>!y(_%LL|K zNaIK|9%VlO(N8|tr%k#TiDeu``s(vUS7ha39XK7tugKCdOgNNv|i2ol#*)M>Zjt{P(D+~k~|-vq-e8lw`d`Y zJCf{^ZCDSFk;87nc}QEulGF>I0-3t4;M4se+cmYSS>AvF))3}8yJBhX7WvoAVe6cK zSYzgp;-?oldYpF12W{4_N2y!gXh3eRBE)4Z7Bkn~T`0ddz+SL41qbj5UQti4jp zvi2_g3+I3IR!p=cN7h~!w&6G8l9xMA0(}*?UAmIeqv~D3NU8Ry zFL5=*$qJ8hd8u^a?ax=B?v)rPx87?@@ZDFrI-N%JRKcxCT;XRdiyJ>Ydv`U&Nd*gT z+kz3|ZklIhdRvxqavu90tdlhm=ScDdg&vRVfj(8@n$24tuyCw2tZP)-3~e6NJ^f8F%@5mec6DRS9f@3&Ym#6Af(5YWf`+H zx<8t6N8ee@72VHk{OZn%%vHslznS;pZVNN5fpySwc#cR9X&Uxmy>b+evu%v>IDIo7 ztT7k7@#qS43=m{~^p@sgR5nN^9IC1UZSp?e%C6gE%HiX!F z&VbmXoS8TByj{n@?IBF9%hy$iXQWv3p;gWe$`NWcq)@8{S`8`MHhUuX^3gW>BhP6v zj2Y!QjiiKwyUab@W%g6=ZpU5j#W$jLKBWqGH@qwF_D4ZvI6yflx7(?+rs&>?=Kq?b9ldweUzL2*Obcce0;gos{)x-dU*Q{aWd;3eG(dLMX$?c zj;Y7@{4>j%MNORb^xWL#(OYPmHtDEwbDnt|WzHq0)hol_G_r;gT1zQkvA@<5v~XH0 z&nDEu9p*oYsMCCB%hWYFC_h(w-X`G;4btd=OULzqJAc!oJZ{g`i=MbORV{)MJMDpQ zWL(aD-<8_J2&nWZj+@rQ{hZ!a>@d?sr7S#wu3wx<(H_W~0O%P{0W|KwDB#?&2wxn{ z|L0i$%@v#T2C#VuQ9j$?DL~W?O*@}@Xb$5zTG=^&UIc!mP5lOU0cr7cT*pgoJdYOW z2PV;Hm0SFnj6L6>xmEfiw6;>NxUpb8l%9L}4I(}D)By>&r{I|;Z6cuH>7Y9;AxB(| zEMewsgmhfdlSp&U_~`{9y}YdQnL6cRA7tgIBmIZ4H;qE<<;)Lpj(=F93%~P7+v5`{ zH`FEX|aUp${Pz*9YdZ z4_qnf7pW_*YrO3w{-ud?rHr~XjyJA;SvNb#P2W%Z(KRW$+j09Ov$Qz=ppPvrhnNx? zDWw`{gfvKe@mftuj%U#U*(+6H~yMzloT;KT%N z1nC9be{i2&st3#;v_Fm#Dm%Rp&ll-AVL^>-M`^4}X_Sz(u7FSLzzCxcfOzK1@z&@? zW=AcbH7Nysz%wF;MSGBw6XddP-5zf5>Xn{xLt7N31@@6=Y;-2E7h!r&j?I4aY;2hTB(Mq8}gXy0mvZQ zsMgqyzSz;qODPXaG17)sQOZxvXQ}eBv{fv_Q6Q&j9Dq$TB4nGiI;@(A;`FWrDS8%W zng)c%XGi4H98?E@ISy=FbDM0t^vY5j(ZvrQu zm&Ns${)z3ejsbXluB_p#3ua<7Pg=5ZcY2{0=ET)aIyJ&~cK5+{IHzbs)JPc(z1)Xf z$^wX58NbjQ(bv#c=hE%re5NiMD_l!{!ghE8K%7uP>+ zH5?U<6Qb?VH;@{ZE|pB))sEF_QY?)8)IA_H>+m-ddG}$d{j=H zT3w~J(GPL{tEIox6Dzia8HCxQEov*i7in^G@L31X0%Y&lwiYeXTXB_k_h&gi8sDOS zuoc$E-U2Rnb@M(6cl6vfx;p}4U))Tvm%CQGz~%VQN!v5(pwG1tjr@KaU2t`0U9=_H zAvRDN#@zZu9{DoHnqM5(l9MN!EKlD^E#lpB%#R{m>eqZef8psV{z6xP?c96PmURT8 zW9{@~I%tc^^I~>kR)ux_rZ&O)O$WJ+}Pfj1I)BTlUcBiO+BT`B%*(HQcCwJ4XVyp=0> z?IuWcD^?=bV`}Na0<4ND$SW;z-7Id2Pe?fXS+kLrlqcHK1Zzc0kb1%OupaI{IRC?E z1FY3HbGJ2$*~mPNB=jkQZM)w50y(bEXi2yB@$DZ(A}o$Qf|Po9QOkB*X-#&W1D!UL^}UEs%arlDb@ABRFN0@s3q4fctKfzYDo<+ zxtF6@aXH>IU^$(k95I#)FlpIgU|!1D9X(BhC4}ERI|oav_bV>LDYfMMm`53 zy)^P*os2y85ze7(?!7bSxcAONdc0JKxa-Kn^?>g}KtFXXAHhX$w5ENa8tfXWW6Byk zds|pq^UK#3z4xTK#rlOE;a(8e0LIyzuZVBtMpO~Szc)oq2V5c_W&-2`lu@F8lp6fL z(Ax?wM>C?8XMd2ubJt+C$HH})*_$UPHpH?yDN`!uXe-$pSD$fN1fcVE;B zY2$pluNr0#qBg~{)HWcr%|6hF2c8t#4r#tG#oKqq_pX$Oqph*7+>^k}k6^H<5G(CF z`zh-%L}_Hk)fQnb+ah`KHF7qx4CgNA3Qur(&cwM}gu@mUr)Hws zA(h&}^9sy6?!5Vq3gvSN! zx>CyOhMc@F#e9vOXz4*3mhRGJC8cilUD)ek9C@m$v7*6lo0vv|7Mcq4qM9O=n&Ns) zo;+|qLty_n^FxaEAevuXk9sGrvU--z(hkGT1Xz;8;-0`Ouk*j|BxVXLBje{W(Ky~G z#eAi8agRbTNz2wd+m6FvzB&#!bGVz-ba8EtN;{S_R`Jo)pzfBS0o-+GZRdo-xopL^ zIiAq_abIZUX6_8{qGG-?N{f9Dbs5h>Ceha+i8-|Qx(3Dh7K!#S+VuL|$*PZzU<(G3 z!;_x4b5F{_S-|ofWzJWgeQ{otP}*+r=c?l=m5`ca8CnodXJNyWsB4NdKx`+#pf#p{ zft;w;N#mTN>>7>nSp)0T6J?ds<#EJ0pP0)Q(F-Zdy{|@$oR5q-0^C0Zc6hw}h*1!) zGCrXH!c1t1Ms|$P8JF?goM*K*h&cJyL1}Et2nXwy)VCKU)B}*q&#RdTWU-DHgOOrTM&Wj9yOiZ}UC6_?QNkcNC73^59FW zp|q$&o~<@+0!@86R|P5G%(+UMMnQYP>7U`vFXoO)#1fQ<9-LhCyYw>bAE^->ZHpGb z4cVH=&68K1DK54l4@ZO&>Av5HtXz}zX^Pse^08&;a}G~foyT{lv=}X%(>i+T_;ZA5 zgQlAMD}Kk&RFfj91>2C~`+RZ!Rk?V#mFF~k(iv)un!(I!;a5OP^8#%amE;U89-ji& zXY>neBy`04{M^+r#afft)9|lSnewSptES`nD!v8hg{~xhyT&;jFN?8vIb0VaIk>Ox za*E5uw*sjlJNyZr6LJh?*5Wx~kj8UDmyWLi>n~~mggxnq)0Q!su%{w?ahU&OB zamC!!hy^x@xf!HIV=7^MSy*Wg%kt#(66`A}2mN>Wj?u96g%LfiHOVKI%h^JC3C?AG zGllQ}D8HWEX$$cZpx5vqdLqOXn*09<))LK&uK}@yd}EAf*F4!%IXVCIDb2Zn%HCPI zks>Ruo*pI1jyA}Zdu6fc9tQ{kCLUXkSp{WY?+>&wa_vo!mlMY z#9Sm!OEguQr}yP~pONv3#zuO_gZWXqS`oQnID=8!`v#jSEzM-KW(S`+_r@4*&JXwoM4?&HW&DQU0jRbd-a zCZxzYy7XKSo9uSykmjf1GhI5atnfn~XrhZJ;=EJFC`$KB>cwOC zhduP)A@@0?)xT@WnEhgJT>Uztai@3XyGOMfzIVw!X{;-@R>%H29OrVPXGTJN+ekIT zk>h+Lr#>ado7uR-?6A07tIDh8btJVs)3kwb+`~AUZL=-5&A6W{7SAVS-;Hrm4EY#W zO{+!6jSX)A>a0?)hQ5gW0VbB|Fg-O7=QrQkpzQPmJOwmpUDMcez$zR)u4U$#o&nUr ze#YMT9)#na#(f6v>3I@v zG2TVE+(jRe+>zKBB2V|=zc|w<9p7}&^A)UY^I2OAy(6AKPG1rSwQol)+*?xHd>>3T z5k5_VJuD4r9IsZC;9TQ52g`9!$}a@>i$uIB$JmOqLv^Y*0{F}~8sB29V0B`VkeT)I z)HFOp3EOmM|90uP`HApxkECZUF*9~md2OY=k3Z$%s^a`GTjx5Ehj&!(s^5s=2*WDd zIR`@?dXdsLEPAJR-)Ijy`xz(tYn9A?;{L3Z_0i>1E6$cAw#2;Tu7<60v>30dRJ2** zT=N)ds>Zc6SHWma@~lf%8Lq$lvZwe_Sv!g-nC09n=)K_ho{`_QX?t0TJ!36r@wiB& z9OYxBDa)cv5Dm^2h#Q5~Y=soT*a1ODgV@b_({}Zb(%xcG_t0(6n z>V$0YTFe0=S^>r~L(iN63-jBx38O~tV#qY3CF5ao5U2=`( zSrd0}kRF;1DN&0gmFp4xr}Gsqk_&163=xkT<%`yIfPME@Sbe(`Bjm5JeAXqF4rvb{ zrB=tNhkYvdGiCv;miaOIkvYb^QcF{7)vq@7qm|pF2EJ>?bP{8zRFLzc)v8vE43plGVp{YLt6kZS7zRVqSv5~hENAj#kj}kJU)k9o@ky!9(OwA z;B!*Ds<>=vON>?dT^;rUKYfM2T+?{<GP*_%q0jlOVJpvp8M?H;(qoUoXQDbf{-# zyD%d-x|BeoKS;nm8tYKsOwE!OV8RKVf)lGO&MNq>Z^<3lW}Z_pZejnZMO~FpGu~QZ z{Li-Zgpzu7o}cY78m86oT#z2wH1IZvV(OPDEAuGyRAar2AfT(cyy#v8LConL(v7|0MDXFGh z?xDKGb5k2(Nk-O`KkjCO9SB>c&o3^ix{O<~;&w`u1NU*D6W-GDpIV3pCLx^_4UitM z0n9ykPD(&4;(3<#cniF0M(A9XOuMG{qek+uZ;WW8JQlt)igRwW6vr5=9lmMFUC_9B z7B&%jt!S$j{+W^#x56mLm9zLVVgy4AjDpw#Ap8$kPw{Ybn8P&oehnc#v{L5M53)V3 zo|I@1lEJ>=A4ui6(oZobe5b(p@3Sb6lRjE6`r4@Vx?F11G-`=x->l!h0N z9fQy;Z$@gYKtIGtfu};Pk@w3@C+|-d^D(9f-?9(h5}H4V-m-43F^mZG2BxXxUsF4X zSb(>AWkhRvgDSvUqIu<#D=+KeQ@KINkQR-bIn3P_@?h_ykYwa#uYt$s>5f)t?2tpDk0Kn ztX=0{{xnSEx^eo-vP-;Uu$tE7E*|#Z`&xZs-@?X|I7V%bBMF zo^tPLF)yOEunpp-hx9BgkfZP%C>o^?;xA9QFOfMHUF+?2ELmJaPp>(?tc9g`i=_Bn z&maQu-@0Wy9~TE`?Ho_mz&8P5?f4Fg-V72<=D3a`*C_TyPRF1xtP^!N0@LsJ$TRdh zjU)9W7(HHGoL}w<{J67{e@)Xiv`jC?n1?%2j=E{0?#ifDN;P#XLx~v$gS(FO2#%GE zwb9RT-g149`wd4er4mr%?7OZYu(U?z7E=xG7nahZHmW5|`!>|0t2Cc6$J-NYR-PHw z#?@ghZWg@Moh$3cI6zCT4V|-Ln;Oj<-0I->12`8Pr)$eX*K$^k+meW}YQwq^!{h7L zoK3oBVg9v+xx6!XNy*cdPFRq(U>c&F96yd7BLwP#V`Un*30C~2LGmCEvM@>{2iHD~ z{2ZQ&`DygVrORzj`B($n=q>88$bm2Fl}Lhp5h;4A?DWE($lG?%F6RXGAmv38jV0Mj zm*;#TOJVMyeb~I*mZj8uh5-H5F&2&Bi-(Hv^4^diJL);g$L9!Uj@BV*d{2<|F&$qP zu?~K15pd2e;M99JA4AS~?PE1; zCl_sA*Bot^_NG*><)(>kMtNj@$k;}yQ4gdgOap7D-*ao4X<$wfMf%S<#T>OHrf?=D zmgJ{}i#~ry%5$e7F+nZ!87~qy!iAL-?P?T49_F*%kV3uj>j1oOt&tUZqP8_c4p=px z<%sw#_kTDdAfDYW$@( zd45C-ES|Bn9rJI*xy1p-p27s?W)vTsp+$=t+Tf=6j1CoPT|i?yK^@{!}9?0x?%e=S7e!ZwypAzWv39Zd^u^i7fyYM81r#U>;m`MiP!&1u4(U1Pd5c?Jr;r6=v zm0!}VRW2*RRnwhVw9CI~aYv!uPwZVM>O>a$<)Y)8G=N7cjCnW~YG&EIOFMG}t0`?qG z);N_awB5ijz`7~Z3?nCNQ&eWH8-2yCX5Jc5FR2`+NLJ=J9=_?X-0`yFY*OB&))kgd zA>(T7koVh_$Ksm++|8;VEY_>asNRP4Fuo?HJ@qk+b(rVuQcJ=!L38lw;L&qw?lS|K z{FR=gOv~av8nXm;;nHkJ<0A!!jDoCdKKQYWK^S0EfxVz-fY6@qglU01so^{%#l2&~C@timmC!~> z;TK%7{=lzs7Es@TUz3=SG>ogvV9gKpFa84(AZ|s3$2gW2#`S6#l2eP&I{F#Sar<%Zbw}pH-T! zEzkqk0&;NgL*2}{s$NcwDL3b=a=-ZVKHKkF2urYj=Rsb2)X4JeEmtkB(bQ6qMqioc z?2hZJd{GPf!uVqr@y##YlT%|64E`X*;_6{8El79b><4WMqXZvEtJhsFZG-)zt%Njk zx?a;JnZq%}jv3J*_s`rrYdw^d^(h}}f>lytj%T>{Acfc^e= zvYjFv@(`yye0!AK`ixj+8Mt{XfcF&G1Gh^FdE7jc{XXizZJM^YXSYLmmZm+xOj^nt zpNeT*68roXvM5*BqbbfqjH4?J3^9(w{1|8P7W9B`X3%e_RTuwGyp}Kx!@gc}Bze*WWoE*w!Dhp`Y;5WQD=CPi(nVjjEnA0p9mN`V77VjI%&%{lY)?((c zB}ONRt!hc*dM)=6g@bDVsmjL`eFXpdY3YlmLu=H0mV}S39Y(LmP$y${YU7;DdE#uz z;+LMn{PJ1ClS#;ix-c&wEuRr{o=^(z{3H#1xpaID=!eKb&&D{OeN}HJn8@Jr;%i{P z*$U5iQJb{xr=@jG$Crf`M9+L~j2SO_*6&#ZYaWI+-IJ*3^9GI)Z;rF?eBMSr?lkE! ziBroFT)0(JfYr_xOf}a^xr2h1nBrKMe&s=V*b-Ja(K5dkp<3qtRBy{t`$~`NC-Z3k z%ER@LcMCY;j>1(Hl(r}j&#mKYgT^5bJaZNK;RDb^`HSBN_eBlD`u`(XgH5juO@39u)c(*=^M{RzLx`PZZUv_Vhp$NyX+ePuRK0prU zs~_R+gdS6G=W@JBp?6Hl7kX$Br2L8C7G>pqBckw=%XHLT$YHM<3TIBO^Asthk0KHUJ4UZltZFOh+h*?$p1Ee6DI?6vVpu8@^7e zsJ10mgneKx3kQD%XDj5qzS_<~c0B9_R}7 zVEu=c>OBnVLf0sV`+ITBF-IXsRPz$GpdNT8sfTtzS`xT=!2pM~Q{N7clS;fPbf90B zie2$wvzi;TtAJ0_y!g8L44xd}ofG;);#}p2v0rdGoK>7b%%he7+j?OqoOLsvyey?R zCdUuudsDQhavANaupV9QUuu*}X>g>{(f z?T}lf#H}vshw(XNM!xP>`Pa7WEA6mkoR>)O%6LiBhWJ12AVe9zYs1Y3fBTjDkT=atH5n|KTq{wWjyV<8Y%h4RO z^k&qnZv-=1o8eTvgDXaqE8h3;cNIduQeE+en$}|)C=GkS*+-9N8u;roMU)oSMG9wi zX0+a^>4f>K7qi_Mg7BEmh_`xmw zV6+WTpaBX52AYSURow48XJ%)(T&8k>0!5o8=gysb&pr3tbIv{I%$+}C=e$8)dZGrg zp1zfwVSSt*NXvWUhToEvsB~qcr?-%mDE3KB>}8L$Sd{m@&X0KR$@q^{(Zcd8!}P$U zSdVekpVnr5B%f(QZJw|kFZsxO@;Tm49^*~&y~fKrVgQ%qEnth_y1dT?5h*E9%Zgbj z@2=zVe`3C;GtY9b3!EvxEWFnBj_YZDAT8hAzrvY3_r~RQZ_wc~j>P`39(T7Q7q^NT z5yw^7iq{oo23ClRcNTGmnOa(x&NziI+xQ;adHk`45jNjwn>ohY3)5p=IZz0b=iZ=S zuG8}la7Y9FW{w)!y6*8<7%yRo2czC|2{;%bZuPxIzO_s1H^%^G;8I-I-3#X+zf4AZ z`bx|b+6VZ*8lOHRkJhjTr@qhHnT1KEZCr&lJHHFvAg8z0S{)F*G&0;`d>?xhEBNlR0F1sFBf z<5%#Q7f-x9DerE}ambntXoSa>_8h$_@>p`x_DhuYZVP@M;`JJVdyjkSz4HsgpRx5Li>p7?vgB#{ZfwR;vYHjM;dox4s6*Z55^o{w+D(p^TKIVCNq89dh& zFFBC5-qb@Qt?SV;)9)0p(Xvo3Nx%BEGUch!yS*Vcaz78?2If@s7@`uW0ug9)^_9A zLIWP@)i%MrMVl>Xre({_wVpJ0bY-|#zt2NjwAHj`JS#}(Fo*apLLDQ$70-0_UFnR1 z`CWFcdmMT52(N$XeN?oMO`HcWVW!as>v00Dc%;pVlVZhKpFr_G3AH?Yl7*IVD?EY$ z&uBh}tAez#dN%MoV;Z18;=G|vOphQk*IgPK#GD4xW2+ch?B`tbN>?-PsCGACE1A}aK_!^bnuSj2HjpLX0KeX$bp(+T{W8~**f*nn9Wf&|a*XkyJ{KU?;+f4D zdXMxzaP{N^@9HCkU3`!?+4mZ!!mBMy+Zea0yvBYQxU9TzYxir2?_b3jhhddxurk{; z(^~Hyz>`{!!|P6C8^u-NQD^{t*C;mCw^7KS=b`%5UiB+{YYSHO&uyH8^u9bppbw+} z*ZUt;KIA3WXs8$DZ+1SeD$Vk)0^Wg730wm|R1$=w{&P)3qu->C5uv`rRPO^^#}U_k z*`s-g>k~=|qhLxoX-AK$D<{I8e8rS7dTteLh(#V7g719QJc4Z+{my_V51E_7!)dhS zS1I+&l*tjFb|YV{{HtaFPYidrHs?-)8hxIbqhch?S)z1veMg@cX8c5pNBv{`l-RY4 zhNB?|>DA55jf^}`K$5SRS@fSsSWCuG{us(fP;(Hp4Vfpw=OMFK#xfm`=QVS~+=?L{ z0>mw2;ft?{@8CC6v(blf5Oa;+=;~?fzS%P{Iyb=ATZqH=;>hezBLS5a^*8NBWP-QN z@U3&aTNC!XHi|PD!g5c}A+jp+>zz%r57_tNJY=IL@+&!v($o&o;wvtmo6%G73m4G( zfm0d2Qzv*Gfhp>a{4N+lYmqbW7<#mxNz37kc7rttie-~Hw@Q%`AmnQMmBRh*SN z;8B^LO=+R!8HVm!4tOw}_RV>hrIvQW&=yUYzK&w2S5P2B)h~b|( zr_sQqjD#z)JmXeBMY()U>9i)$g4&j9Rxew{*j&%bXv;YNQ){5skba%K?WRb0gy#^l z7IQ1uBre&c4X-9%`hS47?|fa_GCC(3M4ydSY&^-?@)VCxS1AH)w`%6g&*IH={&9+flJEBjb*C&0v zA`s7Yz;hj({zup0O)wtIgY#LgK?EwFs1fhReCm-bKQnte$yCC%b)>e zYA4T&QBq`%EqK+B*L0B!lCn<8=xdPPJl3k#f$a>SR$)cgL~@TK9TvZM15ctq49{}_ zzK!tvA<;wVjrlRn7ij_HjI|@*PDybLK6F3+jPqSk{|r{&O#YmtPf2=_sk0Y$j~LfM z%{*w~+w#cI?+YCxpkx$&g*wIFK}$dz`vZ)NmSdHE9p9AalYVT6qdg}@E4UJ>F;t>? z)cAdX-iN)O_uyzeo#B)Ly@z@h#u9v|0(npF=s6i=o@aZ5uif)~#aB?C%omwa4|bm? zY_@X(cXH#*Q+lZRjJYVk^vs2RSM@E8SOv!s#?lI(j8)@-ti8O*v>a?tG=sNwd_IDAGRA7cXK$f^Ch-(T+2pBw(kPa52Byung)IJhcDQE zJqOg6T=WuN3NHc50|~b8dC2m zltPeF+CWK(ltg#X=Nu4Vcr~kL^vK@hmcr;A{0Gsy{lWLF@OpS1gNt+F1yWrzH7nmV zfI#0~K`W8PxJ=DB#`vzufimCkb8}(4Y7?SV%415l&lbQj?DA6Pg02fzI8!!A;yidT zXuyBFX23NUHJ5_+3$AOig)Qyu9d0pfZZl;If^j%Ju$@AH zC_r>D3EHlzF4YXX{DNhuh;DP}(QVHKR|btR(SwX;ilQZc*ly)Y7<9$;{D$x04_(;B zrrp3{&|dJ20}22S8MQEsN`JVJ^XrhxRV(;mxtSA*)a;rA288Wh`d>EC$E*6^SGAl$ zQ{{-jTk7F164q|I;MXreW)YXTm;>QsmSq7FP^d?IDg&vR92Cz10nz7{4V4L_&vYWx zQ3e^>LDjMZRMh?gh6CQ&WvP^Mdq)>U3@!QtwJAUcU5ds~@&(&%I@AHOwq`_|Yakwc zh0=mNOpGy3~ z7FY(5@D66KcLSR)Tzb3Ceq1C4N9$DwkRjDt>o zf`1QSP-EH)%d% zIg7rmi*SBT+Xct)C@mC3a0z3m7u{T=?h!zy*O1Knk7OzhGaj2J!9dTEcPG25mws190vrGyMI8*JUMcP2f= z*ppr$!-m}_g_7`q7~_K=#+4kln=%JKgU(ptg{qtP;5Ed$2hoQzt+4k>81sigd&v9Q zle2#ud{%ng`@0*puRa<6;)3_rZ%x0r`_X@bTf{GCF|nDz7nvLjbC86|6_~h8JSH%D zCWnO_lPfdnV}dmuSa~Mfm{gerOhP6#Cfk|xGugppCzD-Fb~E_~lL01mCJiQoO!hEo zGWiw~%UG6EXyokz{ynD9y5laS%UFSX`tNve zb5HL;UC6kH3J%xdt@?voma0+oV1{?qhW#)QVIlN9w*QW3|j8Zrb$d zHcbU~LJ#Gx^f1T4Ps@m>W7aUR3zw5IFPEBm%MXWaKU@ZDOX717AHmAQeA5j3^+J;& z3jzgbp3Qh6m<(Uek6G~GXi_H>>iZD7bmAEFA+87_+f@J(bWm=p#b9GNAFCcl|J)aw zE~wL|Udc#Q$e^K^WZ@KH!Du~dW;=X}#@~z`lF$LNuhLZ7)tU)S9&bBuq>EQ(OsOmKy1E; z2n~BL-rMmWL(uYg4=#vGc+dq18!Ukw#5Bag0_c2H$N&+BQ*U`r zhaJx@AS4PQ76CZ%u}&UXFaeD2IYY+BR?iK=)*xeJ^SmJpSWfPSU|&#DLUlOAS|^s5AAYg5vI?*#{^-aEOuPOdTh}IM89RKrxzAmrx$^AWODJ%*B7oC(`Om?`PO1Txoh*s z=4WTefpy9<=QlM!zck;PoFnmT7}BAm$F9uI#zQ!{IJdew{s%{9#||AmI@MZx38P!M z_Bv4uStre*#Fx0%_HQRT!U*mv&D#kGay#TE*RXRp1{T3J|Y%@gcd1T*&mCKUcR z*mhecLf=%3jh$K@(m)$@gTYqk_m7`{^?|X@O|pk)v0dB?avUD%kHcZq^&qypsJok~ zBLoAq?C<%hiK*IOJhAR?-+A^g|7v#s>remU8^kfXx^iVyb!c?y@()I16&k(PT7#;M zZj$iw{ADwB=ES!Sf7`_9*8ep|N0Q$^Gji|FTbIB3_h0?Zzx@(qCBNc6#zld8w`TObtAn6{OR{cKxKgt1EJB$n`64Ay1iYdd& z^X78Gox%3<0}#^4gIPOmQlm%ha_8Sgmy=M@3n*mpnR$uX{W^NKF7 z)OW59buev3{|K%Y@GdF-5MTh;v%sTIhbC75IFk5|Td_sYOP|S|UF10XOvcY6xn9yK zxu3pO4wD!Gug3A3!CGb%_a}!jgMbp!$>QkdV9Gy(_XCsHC*;ZmuRHNh4c-H@bsO^i VfAOzr8!kH3xghZS-~T%f{1>NC5|sb| literal 133120 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 B=F$KF delta 5844 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 you send Gotify messages to a server - - - - + + + ..\FileFlows.Plugin.dll + + + diff --git a/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderDurationStart.cs b/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderDurationStart.cs new file mode 100644 index 00000000..d20df50c --- /dev/null +++ b/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderDurationStart.cs @@ -0,0 +1,64 @@ +namespace FileFlows.VideoNodes.FfmpegBuilderNodes; + +/// +/// Flow element that allows you to cut a video short +/// +public class FFmpegBuilderDurationStart : FfmpegBuilderNode +{ + /// + public override int Inputs => 1; + /// + public override int Outputs => 2; + /// + public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder/duration-start"; + /// + public override string Icon => "fas fa-clock"; + + + /// + /// Gets or sets the time for this file + /// + [Time(1)] + public TimeSpan Duration { get; set; } + /// + /// Gets or sets when to start the cut + /// + [Time(2)] + public TimeSpan Start { get; set; } + + /// + public override int Execute(NodeParameters args) + { + var model = GetModel(); + var videoDuration = model.VideoInfo.VideoStreams[0].Duration; + if (Duration.TotalSeconds == 0 && Start.TotalSeconds == 0) + { + args.Logger?.ILog("Neither Duration or Start have been set"); + return 2; + } + + if (Duration >= videoDuration) + { + args.Logger?.ILog("Video is shorter than the time requested."); + return 2; + } + + + if (Start > videoDuration) + { + args.Logger?.ILog("The video is shorter than the starting time"); + return 2; + } + + if (Start + Duration > videoDuration) + { + args.Logger?.ILog("The video is shorter than the starting time and duration combined"); + return 2; + } + + model.StartTime = Start; + model.CutDuration = Duration; + args.Logger?.ILog($"Cutting the video from '{Start}' for '{Duration}'"); + return 1; + } +} \ No newline at end of file diff --git a/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderWatermark.cs b/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderWatermark.cs new file mode 100644 index 00000000..b3ab1d3e --- /dev/null +++ b/VideoNodes/FfmpegBuilderNodes/FFmpegBuilderWatermark.cs @@ -0,0 +1,302 @@ +using System.Globalization; +using FileFlows.Plugin.Types; +using FileFlows.VideoNodes.FfmpegBuilderNodes.Models; + +namespace FileFlows.VideoNodes.FfmpegBuilderNodes; + +/// +/// Flow element that adds a watermark to a video file +/// +public class FFmpegBuilderWatermark: FfmpegBuilderNode +{ + /// + public override int Inputs => 1; + /// + public override int Outputs => 1; + /// + public override string HelpUrl => "https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder/watermark"; + /// + public override string Icon => "far fa-copyright"; + /// + public override bool Enterprise => true; + + /// + /// Gets or sets the watermark image + /// + [File(1)] + [Required] + public string Image { get; set; } + + /// + /// Gets or sets the position + /// + [Select(nameof(PositionOptions), 2)] + [DefaultValue(WatermarkPosition.BottomRight)] + public WatermarkPosition Position { get; set; } + + private static List _PositionOptions; + /// + /// Gets the available position options + /// + public static List PositionOptions + { + get + { + if (_PositionOptions == null) + { + _PositionOptions = new () + { + new () { Label = $"Enums.{nameof(WatermarkPosition)}.{nameof(WatermarkPosition.Center)}", Value = WatermarkPosition.Center }, + new () { Label = $"Enums.{nameof(WatermarkPosition)}.{nameof(WatermarkPosition.TopLeft)}", Value = WatermarkPosition.TopLeft }, + new () { Label = $"Enums.{nameof(WatermarkPosition)}.{nameof(WatermarkPosition.TopRight)}", Value = WatermarkPosition.TopRight }, + new () { Label = $"Enums.{nameof(WatermarkPosition)}.{nameof(WatermarkPosition.BottomRight)}", Value = WatermarkPosition.BottomRight }, + new () { Label = $"Enums.{nameof(WatermarkPosition)}.{nameof(WatermarkPosition.BottomLeft)}", Value = WatermarkPosition.BottomLeft } + }; + } + + return _PositionOptions; + } + } + + /// + /// Gets or sets the x-axis position of the watermark + /// + [NumberPercent(3, "Labels.Pixels", 10, true)] + [ConditionEquals(nameof(Position), WatermarkPosition.Center, inverse: true)] + public NumberPercent XPos { get; set; } + + /// + /// Gets or sets the y-axis position of the watermark + /// + [NumberPercent(4, "Labels.Pixels", 10, true)] + [ConditionEquals(nameof(Position), WatermarkPosition.Center, inverse: true)] + public NumberPercent YPos { get; set; } + + + /// + /// Gets or sets the width of the watermark + /// + [NumberPercent(5, "Labels.Pixels", 0, false)] + public NumberPercent Width { get; set; } + + /// + /// Gets or sets the height of the watermark + /// + [NumberPercent(6, "Labels.Pixels", 0, false)] + public NumberPercent Height { get; set; } + + /// + /// Gets or sets the opacity of the watermark + /// + [Slider(7)] + [Range(0, 100)] + [DefaultValue(100)] + public int Opacity { get; set; } + + /// + public override int Execute(NodeParameters args) + { + var localResult = args.FileService.GetLocalPath(Image); + if (localResult.Failed(out string error)) + { + args.FailureReason = "Failed to get watermark image: " + error; + args.Logger?.ELog(args.FailureReason); + return -1; + } + + var localFile = localResult.Value; + + // ffmpeg -i input.mp4 -i watermark.png -filter_complex "[1][0]scale2ref=oh*mdar:ih*0.2[logo][video];[video][logo]overlay=(main_w-overlay_w):(main_h-overlay_h)" output_bottom_right.mp4 + + var model = GetModel(); + model.InputFiles.Add(new (localFile)); + string filter; + + int xPos = XPos.Value; + if (XPos.Percentage) + { + float percentage = XPos.Value / 100f; + xPos = (int)Math.Round(model.VideoInfo.VideoStreams[0].Width * percentage); + } + int yPos = YPos.Value; + if (YPos.Percentage) + { + float percentage = YPos.Value / 100f; + yPos = (int)Math.Round(model.VideoInfo.VideoStreams[0].Height * percentage); + } + + switch (Position) + { + case WatermarkPosition.TopLeft: + args.Logger?.ILog("Top Left watermark"); + filter = xPos + ":" + yPos; + break; + case WatermarkPosition.TopRight: + args.Logger?.ILog("Top Right watermark"); + filter = $"W-w-{xPos}:{yPos}"; + break; + case WatermarkPosition.BottomRight: + args.Logger?.ILog("Bottom Right watermark"); + filter = $"W-w-{xPos}:H-h-{yPos}"; + break; + case WatermarkPosition.BottomLeft: + args.Logger?.ILog("Bottom Left watermark"); + filter = $"{xPos}:H-h-{yPos}"; + break; + case WatermarkPosition.Center: + default: + args.Logger?.ILog("Centering watermark"); + filter = "(W-w)/2:(H-h)/2"; + break; + } + + List filterParts = new List() + { + "overlay=" + filter + }; + // + // if (Opacity is > 0 and < 100) + // { + // string opacity = (Opacity / 100f).ToString(); + // filter = $"[::wmindex::]format=rgba,colorchannelmixer=aa={opacity}[wm];[0][wm]" + filter; + // } + // + // int width = Width?.Value ?? 0; + // if (width> 0 && Width.Percentage) + // { + // float percentage = Width.Value / 100f; + // width = (int)Math.Round(model.VideoInfo.VideoStreams[0].Width * percentage); + // } + // + // int height = Height?.Value ?? 0; + // if (height > 0 && Height.Percentage) + // { + // float percentage = Height.Value / 100f; + // height = (int)Math.Round(model.VideoInfo.VideoStreams[0].Height * percentage); + // } + // + // if (width > 0 && height > 0) + // { + // // scale width/height + // } + // else if (width > 0) + // { + // // scale width + // } + // else if (height > 0) + // { + // // scale height + // } + + string watermarkLabel = "[::wmindex::]"; + int insertIndex = 0; + if (Opacity > 0 && Opacity < 100) + { + string opacity = (Opacity / 100f).ToString(CultureInfo.InvariantCulture); + filterParts.Insert(insertIndex, $"{watermarkLabel}format=rgba,colorchannelmixer=aa={opacity}[wm];"); + ++insertIndex; + watermarkLabel = "[wm]"; + } + + int width = Width?.Value ?? 0; + if (width > 0 && Width.Percentage) + { + float percentage = Width.Value / 100f; + width = (int)Math.Round(model.VideoInfo.VideoStreams[0].Width * percentage); + } + + int height = Height?.Value ?? 0; + if (height > 0 && Height.Percentage) + { + float percentage = Height.Value / 100f; + height = (int)Math.Round(model.VideoInfo.VideoStreams[0].Height * percentage); + } + + if (width > 0 && height > 0) + { + filterParts.Insert(insertIndex++, $"{watermarkLabel}scale={width}:{height}[wm];"); + } + else if (width > 0) + { + filterParts.Insert(insertIndex++, $"{watermarkLabel}scale={width}:-1[wm];"); + } + else if (height > 0) + { + // Scale height, maintain aspect ratio for width + filterParts.Insert(insertIndex++, $"{watermarkLabel}scale=-1:{height}[wm];"); + } + + filterParts.Insert(insertIndex++, "[0]" + watermarkLabel); + + filter = string.Join(string.Empty, filterParts); + + //= + // "[::wmindex::]" + "[0]scale2ref=oh*mdar:ih*0.2[logo][video];[video][logo]overlay=(main_w-overlay_w):(main_h-overlay_h)"; + // filter = + // //$"overlay=10:10"; + // "overlay=(main_w-overlay_w):(main_h-overlay_h)"; + + //model.VideoStreams[0].FilterComplex.Add(filter); + model.Watermark = new() + { + Image = localFile, + Filter = filter + }; + model.ForceEncode = true; + + return 1; + } + + + /// + /// Enum representing the position of a watermark. + /// + public enum WatermarkPosition + { + /// + /// Center position. + /// + Center = 0, + + /// + /// Top-left position. + /// + TopLeft = 1, + + /// + /// Top-right position. + /// + TopRight = 2, + + /// + /// Bottom-right position. + /// + BottomRight = 3, + + /// + /// Bottom-left position. + /// + BottomLeft = 4, + + /// + /// Custom position. + /// + Custom = 5 + } + +} + +/// +/// The watermark model of the FFmpegBuilder +/// +internal class WatermarkModel +{ + /// + /// The image for the watermark + /// + public string Image { get; init; } + /// + /// The filter for the watermark + /// + public string Filter { get; init; } +} \ No newline at end of file diff --git a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs index c6dfb718..844c134a 100644 --- a/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs +++ b/VideoNodes/FfmpegBuilderNodes/FfmpegBuilderExecutor.cs @@ -247,7 +247,30 @@ public class FfmpegBuilderExecutor: FfmpegBuilderNode startArgs.Add("-i"); startArgs.Add(file.FileName); } + + if (model.Watermark != null) + { + startArgs.AddRange(new[] + { + "-i", + model.Watermark.Image, + "-filter_complex", + model.Watermark.Filter.Replace("::wmindex::", (model.InputFiles.Count - 1).ToString()) + "[watermark]" + }); + + for (int i = 0; i < ffArgs.Count; i++) + { + if (ffArgs[i] == "0:v:0") + ffArgs[i] = "[watermark]"; + } + } + startArgs.Add("-y"); + if(model.CutDuration != null) + startArgs.AddRange(new [] { "-t", model.CutDuration.Value.ToString()}); + if(model.StartTime != null) + startArgs.AddRange(new [] { "-ss", model.StartTime.Value.ToString()}); + if (extension.ToLower() == "mp4" && ffArgs.IndexOf("-movflags") < 0 && startArgs.IndexOf("-movflgs") < 0) { startArgs.AddRange(new[] { "-movflags", "+faststart" }); diff --git a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs index 13078f82..9d64e533 100644 --- a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs +++ b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegModel.cs @@ -73,6 +73,22 @@ { this._VideoInfo = info; } + + + /// + /// Gets or sets a watermark to apply + /// + internal WatermarkModel Watermark { get; set; } + + /// + /// Gets or sets the cut duration of the video, ie the -t variable + /// + public TimeSpan? CutDuration { get; set; } + + /// + /// Gets or sets the start time of hte video, ie the -ss variable + /// + public TimeSpan? StartTime { get; set; } internal static FfmpegModel CreateModel(VideoInfo info) { diff --git a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegVideoStream.cs b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegVideoStream.cs index 5d08f8aa..d30709d2 100644 --- a/VideoNodes/FfmpegBuilderNodes/Models/FfmpegVideoStream.cs +++ b/VideoNodes/FfmpegBuilderNodes/Models/FfmpegVideoStream.cs @@ -15,6 +15,15 @@ public class FfmpegVideoStream : FfmpegStream } private List _OptionalFilter = new List(); + private List _FilterComplex = new List(); + public List FilterComplex + { + get => _FilterComplex; + set + { + _FilterComplex = value ?? new List(); + } + } /// /// Gets or sets filters that will process but only if processing is needed, these won't trigger a has changed /// value of the video file by themselves @@ -96,6 +105,12 @@ public class FfmpegVideoStream : FfmpegStream results.Add("-filter:v:" + args.OutputTypeIndex); results.Add(string.Join(", ", Filter.Concat(OptionalFilter)).Replace("{index}", args.OutputTypeIndex.ToString())); } + + if (FilterComplex?.Any() == true) + { + results.Add("-filter_complex:v:" + args.OutputTypeIndex); + results.Add(string.Join(", ", FilterComplex).Replace("{index}", args.OutputTypeIndex.ToString())); + } } if (string.IsNullOrWhiteSpace(this.Title) == false) diff --git a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_AudioConverterTests.cs b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_AudioConverterTests.cs index ce76f2f9..6d568ba5 100644 --- a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_AudioConverterTests.cs +++ b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_AudioConverterTests.cs @@ -197,7 +197,7 @@ public class FfmpegBuilder_AudioConverterTests: TestBase string log = logger.ToString(); Assert.AreEqual(1, result); - var newInfo = vi.Read(args.WorkingFile); + var newInfo = vi.Read(args.WorkingFile).Value; Assert.AreEqual("opus", newInfo.AudioStreams[0].Codec); } diff --git a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_VideoEncodeTests.cs b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_VideoEncodeTests.cs index 4832d661..a4d680de 100644 --- a/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_VideoEncodeTests.cs +++ b/VideoNodes/Tests/FfmpegBuilderTests/FfmpegBuilder_VideoEncodeTests.cs @@ -186,7 +186,7 @@ public class FfmpegBuilder_VideoEncode_VideoEncodeTests: TestBase string ffmpeg = FfmpegPath; var vi = new VideoInfoHelper(ffmpeg, logger); var vii = vi.Read(TestFile_BasicMkv); - var args = new NodeParameters(TestFile_BasicMkv, logger, false, string.Empty, null); + var args = new NodeParameters(TestFile_BasicMkv, logger, false, string.Empty, new LocalFileService()); args.GetToolPathActual = (string tool) => ffmpeg; args.TempPath = TempPath; args.Parameters.Add("VideoInfo", vii); @@ -209,6 +209,53 @@ public class FfmpegBuilder_VideoEncode_VideoEncodeTests: TestBase string log = logger.ToString(); Assert.AreEqual(1, result); } + + + + [TestMethod] + public void FfmpegBuilder_VideoEncode_Watermark() + { + var logger = new TestLogger(); + string ffmpeg = FfmpegPath; + var vi = new VideoInfoHelper(ffmpeg, logger); + var vii = vi.Read(TestFile_BasicMkv); + var args = new NodeParameters(TestFile_BasicMkv, logger, false, string.Empty, new LocalFileService()); + args.GetToolPathActual = (string tool) => ffmpeg; + args.TempPath = TempPath; + args.Parameters.Add("VideoInfo", vii); + + FfmpegBuilderStart ffStart = new(); + ffStart.PreExecute(args); + Assert.AreEqual(1, ffStart.Execute(args)); + + FfmpegBuilderVideoEncode ffEncode = new(); + ffEncode.Quality = 28; + ffEncode.Encoder = "CPU"; + ffEncode.Speed = "fast"; + ffEncode.Codec = "av1"; + ffEncode.PreExecute(args); + ffEncode.Execute(args); + + FFmpegBuilderWatermark ffWatermark = new(); + ffWatermark.Image = "/home/john/Videos/watermark.png"; + ffWatermark.Position = FFmpegBuilderWatermark.WatermarkPosition.BottomRight; + ffWatermark.Height = new(); + ffWatermark.Width = new() { Value = 5, Percentage = true}; + ffWatermark.XPos = new() { Value = 10, Percentage = true }; + ffWatermark.YPos = new() { Value = 5, Percentage = true }; + ffWatermark.Opacity = 50; + + ffWatermark.PreExecute(args); + ffWatermark.Execute(args); + + FfmpegBuilderExecutor ffExecutor = new(); + ffExecutor.HardwareDecoding = false; + ffExecutor.PreExecute(args); + int result = ffExecutor.Execute(args); + string log = logger.ToString(); + TestContext.WriteLine(log); + Assert.AreEqual(1, result); + } } #endif \ No newline at end of file diff --git a/VideoNodes/Tests/_TestBase.cs b/VideoNodes/Tests/_TestBase.cs index 05546f7a..cdecfd38 100644 --- a/VideoNodes/Tests/_TestBase.cs +++ b/VideoNodes/Tests/_TestBase.cs @@ -11,6 +11,14 @@ namespace VideoNodes.Tests; [TestClass] public abstract class TestBase { + private TestContext testContextInstance; + + public TestContext TestContext + { + get { return testContextInstance; } + set { testContextInstance = value; } + } + public string TestPath { get; private set; } public string TempPath { get; private set; } public string FfmpegPath { get; private set; } diff --git a/VideoNodes/i18n/de.json b/VideoNodes/i18n/de.json new file mode 100644 index 00000000..ecc31939 --- /dev/null +++ b/VideoNodes/i18n/de.json @@ -0,0 +1,840 @@ +{ + "H": { + "264": "H.264", + "265": "H.265" + }, + "5": { "1": "5.1" }, + "7": { "1": "7.1" }, + "Enums": { + "WatermarkPosition": { + "Center": "Zentriert", + "TopLeft": "Oben links", + "TopRight": "Oben rechts", + "BottomRight": "Unten rechts", + "BottomLeft": "Unten links" + } + }, + "Flow": { + "Parts": { + "DisableAmd": { + "Label": "Deaktiviert AMD", + "Description": "Deaktiviert den AMD AMF Hardware-Encoder", + "Outputs": { + "1": "Deaktiviert" + } + }, + "DisableIntelQsv": { + "Label": "Deaktiviert Intel QSV", + "Description": "Deaktiviert den Intel QSV-Hardware-Encoder", + "Outputs": { + "1": "Deaktiviert" + } + }, + "DisableNvidia": { + "Label": "Deaktiviert NVIDIA", + "Description": "Deaktiviert den NVIDIA Hardware-Encoder", + "Outputs": { + "1": "Deaktiviert" + } + }, + "DisableVaapi": { + "Label": "Deaktiviert VAAPI", + "Description": "Deaktiviert den VAAPI-Hardware-Encoder", + "Outputs": { + "1": "Deaktiviert" + } + }, + "AudioToVideo": { + "Description": "Konvertiert eine Audiodatei in eine Videodatei und erzeugt ein Video auf der Grundlage des Audios.", + "Fields": { + "Visualization": "Visualisierung", + "Visualization-Help": "Die Visualisierung, die im generierten Video verwendet werden soll. Siehe Hilfe für Beispiele", + "Container": "Container", + "Resolution": "Auflösung", + "Codec": "Codec", + "HardwareEncoding": "Hardware-Encodierung", + "HardwareEncoding-Help": "Wenn diese Option angekreuzt ist, wird geprüft, ob auf dem Verarbeitungsknoten Hardware-Encoder gefunden werden, und wenn dies der Fall ist, wird die Hardware-Kodierung verwendet, andernfalls wird auf die CPU-Kodierung zurückgegriffen.", + "Color": "Farbe", + "Color-Help": "Optionaler #RRGGBB-Farbcode für die Schallwellen, muss im Format #RRGGBB sein, zum Beispiel #FF0090" + } + }, + "CanUseHardwareEncoding": { + "Description": "Prüft, ob der angegebene Hardware-Encoder derzeit für den Flow verfügbar ist.", + "Fields": { + "Encoder": "Encoder", + "Encoder-Help": "Der zu überprüfende Hardware-Decoder" + } + }, + "ComskipRemoveAds": { + "Description": "Verwendet eine EDL-Datei von comskip und entfernt Werbespots mit dieser Datei.", + "Outputs": { + "1": "Werbespots entfernt, in temporärer Datei gespeichert", + "2": "Keine Werbespots entdeckt" + }, + "Fields": { + "RunComskipIfNoEdl": "Starte Comskip", + "RunComskipIfNoEdl-Help":"Führen Sie comskip gegen die Datei aus, wenn keine comskip (EDL)-Datei gefunden wird." + } + }, + "VideoFile": { + "Description": "Eine Eingangsvideodatei, deren Videoinformationen gelesen wurden und die verarbeitet werden kann.", + "Outputs": { + "1": "Video-Datei aus der Bibliothek" + }, + "Fields": { + "ProbeSize": "Testgröße", + "ProbeSize-Suffix": "MB", + "ProbeSize-Help": "Die Testgröße, die bei der Ausführung von FFMPEG verwendet werden soll." + } + }, + "FfmpegBuilderStart": { + "Label": "FFMPEG Builder: Start", + "Outputs": { + "1": "FFMPEG Builder erstellt und bereit zum Hinzufügen von FFMPEG Builder-Nodes zu" + }, + "Description": "Erzeugt eine Instanz des FFMPEG Builder, der ein FFMPEG-Argument erstellen kann, das dann mit dem FFMPEG Executor ausgeführt wird." + }, + "FfmpegBuilderDeinterlace": { + "Label": "FFMPEG Builder: Deinterlace", + "Outputs": { + "1": "Deinterlace-Filter zum Videostrom hinzugefügt" + }, + "Fields": { + "Mode": "Modus", + "Mode-Help": "Die zu verwendende Deinterlacing-Methode. Siehe Hilfe für weitere Informationen." + } + }, + "FfmpegBuilderExecutor": { + "Label": "FFMPEG Builder: Executor", + "Outputs": { + "1": "FFMPEG Builder wurde erfolgreich ausgeführt und eine neue temporäre Datei erstellt", + "2": "Keine Änderungen in FFMPEG Builder erkannt, Datei nicht erstellt" + }, + "Description": "Führt einen FFMPEG-Builder-Befehl aus, der von anderen FFMPEG-Builder-Knoten erstellt wurde.", + "Fields": { + "HardwareDecoding": "Hardware Decoding", + "HardwareDecoding-Help": "Wenn der Executor versuchen soll, die Hardware-Dekodierung zu verwenden. Falls nicht verfügbar, wird die Ausführung ohne aktivierte Hardware-Dekodierung fortgesetzt.", + "Strictness": "Strikt", + "Strictness-Help": "Ermöglicht es Ihnen, die Strenge von FFmpeg einzustellen. Für die meisten Benutzer sollte diese Einstellung auf 'Experimentell' belassen werden." + } + }, + "FfmpegBuilderAddInputFile": { + "Label": "FFMPEG-Builder: Eingabedatei hinzufügen", + "Outputs": { + "1": "Datei gefunden und hinzugefügt", + "2": "Datei nicht gefunden" + }, + "Fields": { + "Pattern": "Muster", + "Pattern-Help": "Ein regulärer Ausdruck für die Suche nach Eingabedateien", + "UseSourceDirectory": "Quellenverzeichnis verwenden", + "UseSourceDirectory-Help": "Wenn diese Option aktiviert ist, wird das ursprüngliche Quellverzeichnis durchsucht, andernfalls wird das Arbeitsverzeichnis verwendet." + } + }, + "FfmpegBuilderAudioAddTrack": { + "Label": "FFMPEG Builder: Audio-Spur hinzufügen", + "Outputs": { + "1": "Audiospur zum FFMPEG Builder hinzugefügt" + }, + "Description": "Fügt dem FFMPEG Builder eine neue Audiospur hinzu, die bei der Ausführung des Builders hinzugefügt wird.", + "Fields": { + "Index": "Index", + "Index-Help": "Der Index, an dem die neue Tonspur eingefügt werden soll. Um die neue Audiospur als erste Spur einzufügen, setzen Sie diesen Wert auf 0.", + "Channels": "Kanäle", + "Channels-Help": "Die Anzahl der Kanäle dieser neuen Audiospur.\nWenn Sie mehr Kanäle als die Quelle angeben, wird FFMPEG sie automatisch hochmischen.\nWenn Sie weniger Kanäle als die Quelle angeben, wird FFMPEG sie automatisch heruntermischen.", + "Bitrate": "Bitrate", + "Bitrate-Help": "Bitrate der neuen Tonspur.", + "Codec": "Codec", + "Codec-Help": "Der Codec, der für die Audiokodierung verwendet wird.", + "SampleRate": "Musterrate", + "SampleRate-Help": "Die Abtastrate, die für die neue Audiospur verwendet werden soll.", + "Language": "Sprache", + "Language-Help": "Optionaler [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) Sprachcode zu verwenden. Es wird versucht, eine Tonspur mit diesem Sprachcode zu finden, wenn nicht, wird die beste Tonspur verwendet.", + "NewTitle": "Neuer Titel", + "NewTitle-Help": "Optionaler Titel für die neu erstellte Audiospur. Wenn leer gelassen, wird der Quellentitel verwendet.", + "RemoveTitle": "Titel entfernen", + "RemoveTitle-Help": "Wenn der Titel der Quelle entfernt werden soll und der Track keinen Titel haben soll.", + "BitratePerChannel": "Bitrate pro Kanal", + "BitratePerChannel-Help": "Wenn die angegebene Bitrate pro Kanal sein soll" + } + }, + "FfmpegBuilderAudioAdjustVolume": { + "Label": "FFMPEG Builder: Audio-Lautstärke anpassen", + "Outputs": { + "1": "Lautstärkefilter für Audiospuren zu FFMPEG Builder hinzugefügt.", + "2": "Audiospuren wurden nicht angepasst" + }, + "Description": "Passt die Lautstärke von Audiospuren in einer Videodatei mit FFMPEG an.", + "Fields": { + "AllAudio": "Alle Audiospuren", + "AllAudio-Help": "Ob alle Audiospuren normalisiert werden sollen oder nur die erste Spur.", + "VolumePercent": "Lautstärke in Prozent", + "VolumePercent-Help": "Der Prozentsatz der eingestellten Lautstärke.\n100 bedeutet keine Einstellung\n50 bedeutet halbe Lautstärke\n0 bedeutet stummgeschaltet", + "Pattern": "Muster", + "Pattern-Help": "Ein regulärer Ausdruck für die Übereinstimmung, z. B. \"commentary\", um Kommentarspuren zu entfernen.", + "NotMatching": "Nicht zutreffend", + "NotMatching-Help": "Wenn Audiospuren, die nicht dem Muster entsprechen, entfernt werden sollen.", + "UseLanguageCode": "Sprachcode verwenden", + "UseLanguageCode-Help": "Wenn der Sprachcode der Tonspur anstelle des Titels verwendet werden soll." + } + }, + "FfmpegBuilderAudioConverter": { + "Label": "FFMPEG Builder: Audio-Konverter", + "Outputs": { + "1": "Zu konvertierende Spuren", + "2": "Keine zu konvertierenden Spuren" + }, + "Description": "Ermöglicht die Konvertierung aller Spuren, die den zu konvertierenden Parametern entsprechen.", + "Fields": { + "Channels": "Kanäle", + "Channels-Help": "Die Anzahl der Kanäle dieser neuen Audiospur.\nWenn Sie mehr Kanäle als die Quelle angeben, wird FFMPEG sie automatisch hochmischen.\nWenn Sie weniger Kanäle als die Quelle angeben, wird FFMPEG sie automatisch heruntermischen.", + "PcmFormat": "Format", + "PcmFormat-Help": "Das PCM-Format, das für die Codierung von PCM-Audio verwendet werden soll.", + "Bitrate": "Bitrate", + "Bitrate-Help": "Bitrate der Tonspur", + "Codec": "Codec", + "Codec-Help": "Der Codec, der für die Audiokodierung verwendet wird.", + "Field": "Feld", + "Field-Help": "Das Feld, mit dem das Muster verglichen werden soll. Lassen Sie das Muster leer, um alles abzugleichen, für das kein Wert festgelegt wurde.", + "Pattern": "Muster", + "Pattern-Help": "Eine Zeichenkette oder ein regulärer Ausdruck, die bzw. der abgeglichen werden soll, z. B. \"commentary\" für eine genaue Übereinstimmung mit einem Kommentar oder \".*commentary.*\" für eine Übereinstimmung mit einem Kommentar an einer beliebigen Stelle der Zeichenkette", + "NotMatching": "Nicht zutreffend", + "NotMatching-Help": "Wenn Audiospuren, die nicht dem Muster entsprechen, konvertiert werden sollen." + } + }, + "FfmpegBuilderAudioNormalization": { + "Label": "FFMPEG-Builder: Audio-Normalisierung", + "Outputs": { + "1": "Die Audiospuren wurden normalisiert und dem FFMPEG Builder hinzugefügt.", + "2": "Es wurden keine normalisierten Audiospuren gefunden." + }, + "Description": "Normalisiert alle Audiospuren in einer Videodatei mit FFMPEGs loudnorm-Filter.", + "Fields": { + "TwoPass": "Zwei Durchgänge", + "TwoPass-Help": "Wenn die Audiospuren in zwei Durchgängen normalisiert werden sollen. Dies verbessert die Normalisierung, erhöht aber die Verarbeitungszeit.", + "AllAudio": "Alle Audiospuren", + "AllAudio-Help": "Ob alle Audiospuren normalisiert werden sollen oder nur die erste Spur.", + "Pattern": "Muster", + "Pattern-Help": "Ein regulärer Ausdruck für die Übereinstimmung, z. B. \"commentary\", um Kommentarspuren zu entfernen.", + "NotMatching": "Nicht zutreffend", + "NotMatching-Help": "Wenn Audiospuren, die nicht dem Muster entsprechen, entfernt werden sollen.", + "UseLanguageCode": "Sprachcode verwenden", + "UseLanguageCode-Help": "Wenn der Sprachcode der Tonspur anstelle des Titels verwendet werden soll." + } + }, + "FfmpegBuilderAudioTrackRemover": { + "Label": "FFMPEG Builder: Spur-Entferner", + "Outputs": { + "1": "Spuren zum Entfernen eingestellt", + "2": "Spuren NICHT auf entfernt eingestellt" + }, + "Description": "Ermöglicht das Entfernen von Titeln auf der Grundlage ihres Titels oder ihres Sprachcodes.\n\nJeder Titel (oder Sprachcode, wenn er auf \"Sprachcode verwenden\" eingestellt ist), der leer ist, wird unabhängig vom Muster NICHT entfernt.", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Tracks, die im FFMPEG Builder neu angeordnet werden sollen.", + "RemoveAll": "Alle entfernen", + "RemoveAll-Help": "Entfernt alle aktuellen Spuren aus der Ausgabedatei. Mit Spur hinzufügen können Sie anschließend Spuren bestimmter Codecs hinzufügen.", + "Pattern": "Muster", + "Pattern-Help": "Ein regulärer Ausdruck für die Übereinstimmung, z. B. \"commentary\" zum Entfernen von Kommentarspuren", + "NotMatching": "Nicht übereinstimmend", + "NotMatching-Help": "Wenn Audiospuren, die nicht dem Muster entsprechen, entfernt werden sollen", + "UseLanguageCode": "Sprachcode verwenden", + "UseLanguageCode-Help": "Wenn der Sprachcode des Titels anstelle des Titels verwendet werden soll", + "RemoveIndex": "Index entfernen", + "RemoveIndex-Help": "Der Startindex, ab dem die Spuren entfernt werden sollen. Damit können Sie alle oder alle passenden Spuren nach dem Startindex entfernen.\nAuf Null setzen, um alle übereinstimmenden Parameter zu entfernen.\nSetzen Sie den Wert auf 1, um den ersten Track zu behalten und alle weiteren, die den Parametern entsprechen, zu entfernen.", + "MatchType": "Übereinstimmungen", + "MatchType-Help": "Der zu vergleichende Wert." + } + }, + "FfmpegBuilderAudioTrackReorder": { + "Label": "FFMPEG-Builder: Spur neu ordnen", + "Outputs": { + "1": "Spuren in FFMPEG Builder neu sortiert", + "2": "Spuren NICHT neu sortiert" + }, + "Description": "Ermöglicht es Ihnen, die Spuren in der gewünschten Reihenfolge neu anzuordnen.\n\nGeben Sie die Sprachen/Audiocodecs/Kanäle in der von Ihnen gewünschten Reihenfolge ein. Nicht aufgeführte Sprachen werden nach den in der ursprünglichen Reihenfolge eingegebenen Sprachen angeordnet.\nWenn es mehrere Titel mit der gleichen Sprache/dem gleichen Codec/den gleichen Kanälen gibt, werden sie zuerst in der von Ihnen eingegebenen Reihenfolge und dann in ihrer ursprünglichen Reihenfolge angeordnet.\n\nBeachten Sie, dass der erste Titel nach der Neuordnung als Standardtitel festgelegt wird.\n\nAusgabe 1: Spuren wurden neu geordnet\nAusgabe 2: Spuren mussten nicht neu geordnet werden", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Spuren, die im FFMPEG Builder neu angeordnet werden sollen.", + "OrderedTracks": "Geordnete Codecs", + "OrderedTracks-Help": "Die Reihenfolge der Codecs zu den Tracks nach. Dies geschieht nach den Sprachen (falls vorhanden).", + "Languages": "Sprachen", + "Languages-Help": "Die Reihenfolge der Sprachen, nach denen die Titel sortiert werden sollen. Diese Sortierung wird vor dem Codec durchgeführt.", + "Channels": "Kanäle", + "Channels-Help": "Die Reihenfolge der Audiokanäle, nach der die Audiospuren sortiert werden sollen. Diese Sortierung wird vor den Sprachen vorgenommen.\nZum Beispiel: \"5.1\",\"7.1\",\"6.2\",\"2\"" + } + }, + "FfmpegBuilderAudioSetLanguage": { + "Label": "FFMPEG Builder: Sprache einstellen", + "Outputs": { + "1": "Spuren in FFMPEG Builder aktualisiert", + "2": "Spuren NICHT aktualisiert" + }, + "Description": "Hier können Sie die Sprache für alle Titel einstellen, für die keine Sprache festgelegt ist. Wenn für den Titel eine Sprache eingestellt ist, wird er übersprungen.\n\nAusgabe 1: Die Spuren wurden aktualisiert\nAusgabe 2: Es mussten keine Spuren aktualisiert werden", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Spur, für die die Sprache eingestellt werden soll.", + "Language": "Sprache", + "Language-Help": "Der zu verwendende [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) Sprachcode." + } + }, + "FfmpegBuilderAutoChapters": { + "Label": "FFMPEG Builder: Auto-Kapitel", + "Description": "Automatische Erkennung von Szenenwechseln im Video zur Erstellung von Kapiteln.", + "Outputs": { + "1": "Erstellte und dem FFMPEG Builder hinzugefügte Kapitel", + "2": "Keine Kapitel erkannt oder Video hatte bereits Kapitel" + }, + "Fields": { + "MinimumLength": "Minimale Länge", + "MinimumLength-Suffix": "Sekunden", + "MinimumLength-Help": "Die Mindestlänge eines Kapitels in Sekunden", + "Percent": "Prozent", + "Percent-Suffix": "%", + "Percent-Help": "Der prozentuale Schwellenwert, der für die Szenenerkennung verwendet wird, ändert sich. Ein guter Wert ist 45 %." + } + }, + "FfmpegBuilderComskipChapters": { + "Label": "FFMPEG-Builder: Comskip-Kapitel", + "Description": "Verwendet eine Comskip-EDL-Datei und erstellt Kapitel anhand dieser EDL-Comskip-Datei.", + "Outputs": { + "1": "Werbekapitel erstellt, zu FFMPEG Builder hinzugefügt", + "2": "Keine Werbespots entdeckt" + }, + "Fields": { + "RunComskipIfNoEdl": "Comskip ausführen", + "RunComskipIfNoEdl-Help":"Führen Sie comskip gegen die Datei aus, wenn keine comskip (EDL)-Datei gefunden wird." + } + }, + "FfmpegBuilderCustomParameters": { + "Label": "FFMPEG-Builder: Benutzerdefinierte Parameter", + "Description": "Ermöglicht es Ihnen, dem FFMPEG Builder benutzerdefinierte Parameter zur Ausführung hinzuzufügen", + "Outputs": { + "1": "Parameter hinzugefügt" + }, + "Fields": { + "Parameters": "Parameter", + "Parameters-Help": "Die Parameter, die dem FFMPEG Builder zur Ausführung hinzugefügt werden sollen", + "ForceEncode": "Encode erzwingen", + "ForceEncode-Help": "Wenn dies den FFMPEG Builder Executor zwingen soll, immer auszuführen, auch wenn keine Änderungen festgestellt werden, die normalerweise die Ausführung des Executors erfordern würden." + } + }, + "FfmpegBuilderHdrToSdr": { + "Label": "FFMPEG-Builder: HDR zu SDR", + "Description": "Prüft, ob ein Videostream HDR ist, und wenn ja, aktualisiert er den FFMPEG Builder, um ihn in SDR zu konvertieren.", + "Outputs": { + "1": "HDR-Stream erkannt und FFMPEG Builder zur Konvertierung aktualisiert", + "2": "Kein HDR-Stream gefunden" + } + }, + "FfmpegBuilderKeepOriginalLanguage": { + "Label": "FFMPEG-Builder: Originalsprache beibehalten", + "Outputs": { + "1": "Die Spuren wurden geändert", + "2": "Es wurden keine Spuren geändert" + }, + "Description": "Dieses Flow-Element behält nur die ursprüngliche Sprache und alle zusätzlichen Sprachen, die der Benutzer definiert.\n\nAlle anderen Sprachströme werden entfernt/zur Löschung markiert.", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Spuren, die aktualisiert werden sollen", + "AdditionalLanguages": "Weitere Sprachen", + "AdditionalLanguages-Help": "Eine optionale Liste zusätzlicher Sprachcodes, die auf den Spuren mit fehlenden Sprachen einzustellen sind.\n\nEs wird empfohlen, einen [ISO 639-2 Sprachcode] (https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) zu verwenden.", + "KeepOnlyFirst": "Nur erste behalten", + "KeepOnlyFirst-Help": "Wenn diese Option aktiviert ist, wird nur die erste Spur jeder Sprache gespeichert.\n\nWenn es zum Beispiel 2 englische Spuren, 3 spanische Spuren und 1 deutsche Spur gibt. Die ursprüngliche Sprache war Spanisch, die zusätzlichen Sprachen wurden auf `en` gesetzt, dann wäre das Ergebnis 1 englische Spur und 1 spanische Spur, der Rest würde entfernt werden.", + "FirstIfNone": "Erste wenn keine", + "FirstIfNone-Help": "Wenn diese Option aktiviert ist, wird mindestens eine Spur beibehalten. Wenn keine Spuren gefunden werden, die der Originalsprache und den zusätzlichen Sprachen entsprechen, wird die erste Spur trotzdem beibehalten.\n\nDadurch wird vermieden, dass kein Ton mehr auf dem Video zu hören ist.", + "TreatEmptyAsOriginal": "Leere wie Original behandeln", + "TreatEmptyAsOriginal-Help": "Wenn diese Option aktiviert ist, wird jeder Titel, für den keine Sprache eingestellt ist, so behandelt, als wäre er in der Originalsprache.\n\nWenn beispielsweise die Originalsprache Maori ist und für einen Track keine Sprache festgelegt wurde, wird er als Maori behandelt. " + } + }, + "FfmpegBuilderMetadataRemover": { + "Label": "FFMPEG Builder: Metadata Remover", + "Description": " Entfernt Metadaten aus dem FFMPEG Builder, so dass bei der Verarbeitung der Datei die ausgewählten Metadaten entfernt werden.\n\nHinweis: Nur die Metadaten dieses Nodes sind betroffen, wenn Metadaten nach der Ausführung dieses Nodes hinzugefügt werden, sind diese nicht betroffen. ", + "Outputs": { + "1": " Metadaten aus dem FFMPEG Builder entfernt " + }, + "Fields": { + "Video": "Video", + "Video-Help": " Wenn diese Metadaten aus den Videospuren entfernt werden sollen.", + "Audio": "Audio", + "Audio-Help": " Wenn diese Metadaten von den Audiospuren entfernt werden sollen.", + "Subtitle": "Untertitel", + "Subtitle-Help": "Wenn Untertitelspuren diese Metadaten entfernt haben sollen", + "RemoveImages": "Bilder entfernen", + "RemoveImages-Help": "Wenn die in den Metadaten gefundenen Bilder entfernt werden sollen", + "RemoveTitle": "Titel entfernen", + "RemoveTitle-Help": "Wenn der Titel aus den Spuren entfernt werden soll", + "RemoveLanguage": "Sprache entfernen", + "RemoveLanguage-Help": "Wenn die Sprache aus den Spuren entfernt werden soll", + "RemoveAdditionalMetadata": "Zusätzliche Metadaten entfernen", + "RemoveAdditionalMetadata-Help": "Wenn zusätzliche Metadaten entfernt werden sollen. Zusätzliche Metadaten sind nicht standardmäßige Metadaten, die einer Videodatei z. B. von iTunes hinzugefügt wurden." + } + }, + "FfmpegBuilderDefaultOriginalLanguage": { + "Label": "FFMPEG Builder: Standard-Originalsprache", + "Outputs": { + "1": "Die Spuren wurden geändert", + "2": "Es wurden keine Spuren geändert" + }, + "Description": "Dieses Flow-Element versucht, die Spuren in der Originalsprache als Standard zu setzen. Es versucht, die erste Spur zu finden, die mit der Originalsprache übereinstimmt, und setzt diese dann als Standard.\n\nWenn keine Spuren in der Originalsprache gefunden werden, werden keine Änderungen vorgenommen.", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Spur, die aktualisiert werden soll.", + "MakeFirst": "Setze erste Spur", + "MakeFirst-Help": "Wenn die Originalsprache der Spur die erste Spur werden soll." + } + }, + "FfmpegBuilderTrackSorter": { + "Label": "FFMPEG-Builder: Track-Sortierer", + "Outputs": { + "1": "Tracks wurden geändert", + "2": "Es wurden keine Tracks geändert" + }, + "Description": "Dieses Flow-Element sortiert Tracks auf der Grundlage der vom Benutzer festgelegten Sortieroptionen.", + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art der Tracks, die aktualisiert werden sollen.", + "Sorters": "Sortierer", + "Sorters-Help": "Fügen Sie eine oder mehrere Sortieroptionen hinzu, nach denen die Tracks sortiert werden sollen.", + "SortersKey": "Feld", + "SortersValue": "Wert" + } + }, + "FfmpegBuilderSubtitleClearDefault": { + "Label": "FFMPEG Builder: Untertitel löschen Standard", + "Description": "Mit dieser Funktion wird die Standardmarkierung von Untertiteln gelöscht.", + "Fields": { + "LeaveForced": "Belasse erzwungenen Untertitel", + "LeaveForced-Help": "Wenn diese Option aktiviert ist, werden alle erzwungenen Untertitel nicht berührt, sondern behalten ihre ursprüngliche Einstellung bei. Diese Funktion wird vor der Funktion ''Erzwungene Standardeinstellung'' ausgeführt, hat also Vorrang.", + "SetForcedDefault": "Erzwungene Standardeinstellung", + "SetForcedDefault-Help": "Wenn diese Option aktiviert ist, wird der erste gefundene Untertitel, bei dem das Feld ''Erzwungen'' gesetzt ist, als Standard festgelegt, bei allen anderen wird die Standardmarkierung gelöscht." + }, + "Outputs": { + "1": "Die Standardflags für Untertitel wurden geändert", + "2": "An den Untertiteln wurden keine Änderungen vorgenommen" + } + }, + "FfmpegBuilderSubtitleFormatRemover": { + "Label": "FFMPEG Builder: Untertitel-Format-Entferner", + "Description": "Entfernt Untertitel aus einer Videodatei, falls gefunden.", + "Outputs": { + "1": "In FFMPEG Builder zum Entfernen markierter Untertitel", + "2": "Keine Untertitel zum Entfernen" + }, + "Fields": { + "SubtitlesToRemove": "Zu entfernende Untertitel", + "RemoveAll": "Alle entfernen", + "RemoveAll-Help": "Wenn diese Option aktiviert ist, werden alle Untertitel aus der Datei entfernt, andernfalls werden nur die unten ausgewählten Untertitel entfernt." + } + }, + "FfmpegBuilderSubtitleTrackRemover": { + "Label": "FFMPEG Builder: Untertitelspur-Entferner", + "Outputs": { + "1": "In FFMPEG Builder zum Entfernen markierte Untertitel", + "2": "Keine Untertitel zum Entfernen" + }, + "Description": "Ermöglicht das Entfernen von Untertiteln auf der Grundlage ihres Titels oder ihrer Sprachcodes.\n\nJede Sprache (oder jeder Titel, wenn er auf \"Use Title\"), die leer sind, werden unabhängig vom Muster NICHT entfernt.", + "Fields": { + "Pattern": "Muster", + "Pattern-Help": "Ein regulärer Ausdruck für die Übereinstimmung, z. B. \"eng\", um englische Spur zu entfernen.", + "NotMatching": "Nicht übereinstimmend", + "NotMatching-Help": "Wenn Untertitel, die nicht dem Muster entsprechen, entfernt werden sollen", + "UseLanguageCode": "Sprachcode verwenden", + "UseLanguageCode-Help": "Wenn der Sprachcode der Tonspur anstelle des Titels verwendet werden soll" + } + }, + "FfmpegBuilderSubtitleTrackMerge": { + "Label": "FFMPEG Builder: Untertitelspur zusammenführen", + "Outputs": { + "1": "Untertitel gefunden und hinzugefügt", + "2": "Keine Untertitel gefunden" + }, + "Fields": { + "Subtitles": "Untertitel", + "Subtitles-Help": "Wählen Sie aus, nach welchen Untertiteln Sie suchen möchten, um sie hinzuzufügen", + "UseSourceDirectory": "Quellenverzeichnis verwenden", + "UseSourceDirectory-Help": "Wenn diese Option aktiviert ist, wird das ursprüngliche Quellverzeichnis durchsucht, andernfalls wird das Arbeitsverzeichnis verwendet.", + "MatchFilename": "Dateiname anpassen", + "MatchFilename-Help": "Wenn diese Option aktiviert ist, werden nur Untertitel mit dem gleichen Dateinamen wie die Eingabedatei oder die Arbeitsdatei zusammengeführt.", + "DeleteAfterwards": "Nach Zusammenführung löschen", + "DeleteAfterwards-Help": "Wenn die Untertiteldatei nach dem Zusammenführen gelöscht werden soll" + } + }, + "FfmpegBuilderCropBlackBars": { + "Label": "FFMPEG-Builder: Schwarze Balken schneiden", + "Description": "FFMPEG Builder wurde aktualisiert, um schwarze Balken zu schneiden, wenn sie erkannt werden", + "Outputs": { + "1": "FFMPEG Builder aktualisiert, um schwarze Balken zu beschneiden", + "2": "Keine schwarzen Balken erkannt, kein Schneiden notwendig" + }, + "Fields": { + "CroppingThreshold": "Schwellenwert", + "CroppingThreshold-Help": "Die Anzahl der Pixel, die zum Zuschneiden größer sein muss als diese. Wenn z. B. nur 5 Pixel als schwarzer Bereich erkannt werden, können Sie dies als zu klein zum Zuschneiden betrachten." + } + }, + "FfmpegBuilderPreExecute": { + "Label": "FFMPEG Buidler: Pre-Execute", + "Description": "Mit diesem Element können Sie benutzerdefinierten Code unmittelbar vor der [FFmpeg Builder: Executor](https://fileflows.com/docs/plugins/video-nodes/ffmpeg-builder) FFmpeg-Ausführung einfügen.\n\nDamit können Sie die an FFmpeg übergebenen Argumente ändern.", + "Outputs": { + "1": "Pre-Execute eingestellt" + }, + "Fields": { + "Code": "Code" + } + }, + "FfmpegBuilderProres": { + "Label": "FFMPEG Buidler: Prores", + "Description": "Kodiert das Video in das Prores-Format.", + "Outputs": { + "1": "Video auf die Verwendung von Prores eingestellt" + }, + "Fields": { + "Encoder": "Encoder", + "Encoder-Help": "Welcher FFmpeg Prores-Encoder zu verwenden ist.", + "Quality": "Qualität", + "Quality-Help": "0 für maximale Qualität, 32 für minimale Qualität. 9 bis 13 sind gute Werte für die Verwendung.", + "Profile": "Profil", + "PixelFormat": "Pixel Format" + } + }, + "FfmpegBuilderRemoveAttachments": { + "Label": "FFMPEG Builder: Anhänge entfernen", + "Description": "Entfernt alle Anhänge aus dem Video, falls es welche gibt.", + "Outputs": { + "1": "FFMPEG Builder ist so eingestellt, dass Anhänge entfernt werden." + } + }, + "FfmpegBuilderRemuxToMkv": { + "Label": "FFMPEG Builder: Remuxen zu MKV", + "Description": "Remuxen einer Videodatei in einen MKV-Container.", + "Outputs": { + "1": "FFMPEG Builder für den Remux zu MKV eingestellt" + } + }, + "FfmpegBuilderRemuxToMxf": { + "Label": "FFMPEG Builder: Remux zu MXF", + "Description": "Remuxen einer Videodatei in einen MXF-Container.", + "Outputs": { + "1": "FFMPEG Builder für den Remux zu MXF eingestellt" + } + }, + "FfmpegBuilderRemuxToMP4": { + "Label": "FFMPEG Builder: Remuxen zu MP4", + "Description": "Remuxen einer Videodatei in einen MP4-Container.", + "Outputs": { + "1": "FFMPEG Builder für den Remux zu MP4 eingestellt" + }, + "Fields": { + "UseHvc1": "HVC1 verwenden", + "UseHvc1-Help": "Wenn HVC1 anstelle des Standardwerts HEV1 verwendet werden soll" + } + }, + "FfmpegBuilderRemuxToMov": { + "Label": "FFMPEG Builder: Remux zu MOV", + "Description": "Remuxen einer Videodatei in einen MOV-Container.", + "Outputs": { + "1": "FFMPEG Builder ist auf Remuxen zu MOV eingestellt" + } + }, + "FfmpegBuilderRemuxToWebm": { + "Label": "FFMPEG Builder: Remuxen zu WEBM", + "Description": "Remuxen einer Videodatei in einen WEGM-Container.", + "Outputs": { + "1": "FFMPEG Builder für den Remux zu WEGM eingestellt" + } + }, + "FfmpegBuilderScaler": { + "Label": "FFMPEG Builder: Video-Skalierer", + "Description": "Damit können Sie ein Video auf die angegebenen Abmessungen skalieren. Das Seitenverhältnis des Videos wird beibehalten, d.h. wenn das Video 1920x1000 ist, wird es auf 1280x668 skaliert, wenn Sie 720P wählen.", + "Outputs": { + "1": "FFMPEG Builder Skalierungsfilter hinzugefügt", + "2": "Das Video war bereits in/nahe der skalierten Auflösung" + }, + "Fields": { + "Force": "Force", + "Force-Help": "Wenn diese Option aktiviert ist, wird die Skalierung des Videos auch dann erzwungen, wenn die Arbeitsdatei bereits diese Auflösung (oder nahe dieser Auflösung) aufweist.", + "OnlyIfLarger": "Nur wenn größer", + "OnlyIfLarger-Help": "Das Video wird nur dann auf diese Auflösung skaliert, wenn das Video aktuell größer als diese Auflösung ist.", + "Resolution": "Auflösung" + } + }, + "FfmpegBuilderSetDefaultTrack": { + "Label": "FFMPEG-Builder: Standardspur festlegen", + "Description": "Legen Sie eine Spur als Standard im FFmpeg-Builder fest.", + "Outputs": { + "1": "Spur als Standard eingestellt", + "2": "Spur konnte nicht als Standard festgelegt werden" + }, + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art des Tracks, die im FFMPEG Builder als Standard eingestellt werden soll.", + "Language": "Sprache", + "Language-Help": "Optional zu verwendender [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) Sprachcode.", + "Index": "Index", + "Index-Help": "Der Index des Titels, der als Standard festgelegt werden soll, wird nur verwendet, wenn keine Sprache angegeben ist." + } + }, + "FfmpegBuilderSetFps": { + "Label": "FFMPEG-Builder: FPS einstellen", + "Description": "Stellen Sie die Bilder pro Sekunde (FPS) im FFmpeg Builder ein.", + "Outputs": { + "1": "FPS aktualisiert", + "2": "Es waren keine Änderungen erforderlich." + }, + "Fields": { + "Fps": "FPS", + "Fps-Help": "Die gewünschten FPS, wenn die Eingangs-FPS und die gewünschten FPS nicht übereinstimmen, konvertiert FFMPEG sie, z. B. (23.976, 24, 30, 60).", + "OnlyIfHigher": "Nur wenn höher", + "OnlyIfHigher-Help": "Wenn die FPS nur dann angepasst werden sollen, wenn die aktuellen FPS höher sind als die aktuellen." + } + }, + "FfmpegBuilderSetTrackTitles": { + "Label": "FFMPEG-Builder: Track-Titel festlegen", + "Description": "Setzen von Titeln auf der Grundlage eines Formatierers im FFmpeg-Builder.", + "Outputs": { + "1": "Track-Titel aktualisiert", + "2": "Es wurden keine Titelnamen geändert." + }, + "Fields": { + "StreamType": "Typ", + "StreamType-Help": "Die Art des Tracks, die im FFMPEG Builder als Standard eingestellt werden soll.", + "Format": "Format", + "Format-Help": "Der zu verwendende Formatierer, siehe _Hilfe_ für weitere Informationen.", + "Separator": "Trennzeichen", + "Separator-Help": "Das Zeichenketten-Trennzeichen, das zwischen den Formatwerten verwendet wird, um sicherzustellen, dass keine leeren Werte gespeichert werden.", + "CommentaryFormat": "Kommentar", + "CommentaryFormat-Help": "Wie Kommentarspuren behandelt werden sollen, können Sie mit dem gleichen Format wie andere Spuren oder mit einer anderen Methode festlegen." + } + }, + "FfmpegBuilderVideo10Bit": { + "Label": "FFMPEG Builder: Video 10 Bit", + "Description": "Stellt FFMPEG Builder so ein, dass die Videoströme in 10 Bit kodiert werden", + "Outputs": { + "1": "FFMPEG Builder-Videostreams, die in 10 Bit kodiert sind" + } + }, + "FfmpegBuilderVideoBitrate": { + "Label": "FFMPEG-Builder: Video-Bitrate", + "Description": "Legt den FFMPEG Builder auf die Kodierung des Videos mit der angegebenen Bitrate fest.", + "Outputs": { + "1": "FFMPEG Builder Videostreams aktualisiert" + }, + "Fields": { + "Bitrate": "Bitrate", + "Bitrate-Suffix": "KB / %", + "Bitrate-Help": "Die Ziel-Bitrate des Videos in Kilobytes", + "Percent": "Prozentsatz", + "Percent-Help": "Wenn Sie diese Option auswählen, wird die Bitrate als Prozentsatz der aktuellen Bitrate berechnet." + } + }, + "FfmpegBuilderVideoMaxBitrate": { + "Label": "FFMPEG-Builder: Video Max Bitrate", + "Description": "Legt fest, dass der FFMPEG Builder die Bitrate des Videos begrenzt", + "Outputs": { + "1": "FFMPEG Builder Videostreams aktualisiert" + }, + "Fields": { + "Bitrate": "Maximale Bitrate", + "Bitrate-Suffix": "KB", + "Bitrate-Help": "Die maximale Bitrate des Videos in Kilobytes" + } + }, + "FfmpegBuilderVideoCodec": { + "Label": "FFMPEG Builder: Video Codec", + "Description": "Legt fest, dass FFMPEG Builder die Videoströme im angegebenen Codec kodieren soll.", + "Outputs": { + "1": "FFMPEG Builder-Stream zur Kodierung eingestellt", + "2": "Video bereits im Zielcodec, wird nicht neu kodiert" + }, + "Fields": { + "VideoCodec": "Video Codec", + "VideoCodec-Help": "Der Videocodec, in dem das Video vorliegen soll, z. B. hevc, h264.\nWenn diese Option leer gelassen wird, werden alle Original-Videospuren kopiert.", + "VideoCodecParameters": "Video-Codec-Parameter", + "VideoCodecParameters-Help": "Die für die Codierung des Videos zu verwendenden Parameter, z. B. \"hevc_nvenc -preset hq -crf 23\" in hevc zu kodieren, wobei die HQ-Voreinstellung mit einem konstanten Ratenfaktor von 23 und die NVIDIA-Hardwarebeschleunigung verwendet wird.", + "Force": "Encode Erzwingen", + "Force-Help": "Erzwingt eine Kodierung des Videos, auch wenn es sich bereits im Ziel-Video-Codec befindet", + "DisableOtherVideoStreams": "Nur Erster", + "DisableOtherVideoStreams-Help": "Wenn dieses Kontrollkästchen bei mehreren Videostreams in der Datei aktiviert ist, werden nach der Ausführung alle Videostreams bis auf den ersten aus der Datei entfernt." + } + }, + "FfmpegBuilderVideoEncode": { + "Label": "FFMPEG Builder: Video-Encode", + "Description": "Stellt den FFMPEG Builder für die Codierung des Videos mit einfach zu verwendenden Voreinstellungen ein", + "Outputs": { + "1": "FFMPEG Builder-Videoströme zum Encode eingestellt" + }, + "Fields": { + "Codec": "Codec", + "Speed": "Geschwindigkeit", + "Encoder": "Encoder", + "Encoder-Help": "Der Encoder, dessen Verwendung erzwungen werden soll. Wenn Sie einen Hardware-Encoder angeben, der nicht verfügbar ist, schlägt die Kodierung fehl.", + "HardwareEncoding": "Hardware Encode", + "HardwareEncoding-Help": "Wenn diese Option angekreuzt ist, wird geprüft, ob auf dem Verarbeitungsknoten Hardware-Encoder gefunden werden, und wenn dies der Fall ist, wird die Hardware-Kodierung verwendet, andernfalls wird auf die CPU-Kodierung zurückgegriffen.", + "Quality": "Qualität", + "Quality-Help": "Eine logarithmische Qualitätsskala, d. h. kleine Änderungen an diesem Schieberegler führen zu großen Änderungen der Dateigröße/Qualität.\nJe niedriger die Zahl, desto höher die Qualität.", + "Quality-Suffix": "(Höhere Qualität, größere Datei)" + } + }, + "FfmpegBuilderVideoTag": { + "Label": "FFMPEG Builder: Video Tag", + "Description": "Legt ein Video-Tag für die Datei fest", + "Outputs": { + "1": "FFMPEG Builder-Tag hinzugefügt" + }, + "Fields": { + "Tag": "Tag", + "Tag-Help": "Das Tag, das der Videodatei hinzugefügt werden soll" + } + }, + "FFmpegBuilderWatermark": { + "Label": "FFmpeg Builder: Wasserzeichen", + "Description": "Fügt einem Videodatei ein Wasserzeichen hinzu.", + "Outputs": { + "1": "Wasserzeichen hinzugefügt" + }, + "Fields": { + "Image": "Bild", + "Image-Help": "Die Bilddatei für das Wasserzeichen. Verwenden Sie für beste Ergebnisse eine PNG-Datei.", + "Position": "Position", + "Position-Help": "Wo soll das Wasserzeichen platziert werden?", + "Opacity": "Deckkraft", + "Opacity-Help": "Passt die Transparenz des eingeblendeten Bildes an, von 0 (vollständig transparent) bis 100 (vollständig deckend).", + "XPos": "X-Position", + "XPos-Help": "Die Position des Wasserzeichens auf der X-Achse", + "YPos": "Y-Position", + "YPos-Help": "Die Position des Wasserzeichens auf der Y-Achse", + "Width": "Breite", + "Width-Help": "Legen Sie eine benutzerdefinierte Breite des Bildes fest, oder stellen Sie sie auf 0 für die Quellbreite oder skaliert, wenn die Höhe festgelegt ist.", + "Height": "Höhe", + "Height-Help": "Legen Sie eine benutzerdefinierte Höhe des Bildes fest, oder stellen Sie sie auf 0 für die Quellhöhe oder skaliert, wenn die Breite festgelegt ist." + } + }, + "ReadVideoInfo": { + "Description": "Liest die Videoinformationen aus der aktuellen Arbeitsdatei und aktualisiert die vi-Variablen.", + "Outputs": { + "1": "Die Datei ist eine Videodatei und die Informationen wurden in den Flow eingetragen", + "2": "Datei war keine Videodatei oder konnte nicht gelesen werden" + } + }, + "SubtitleExtractor": { + "Description": "Extrahiert eine einzelne Untertitelspur und speichert sie am Zielort. Es können die Formate srt, ass und ssa extrahiert werden.\nDie Arbeitsdatei wird NICHT aktualisiert und bleibt mit der Eingabedatei identisch.\n\nAusgabe 1: Untertitel wurden extrahiert\nAusgabe 2: Keine Untertitel zum Extrahieren gefunden.", + "Outputs": { + "1": "Untertitel extrahiert", + "2": "Keine Untertitel extrahiert" + }, + "Fields": { + "Language": "Sprache", + "Language-Help": "Der zu verwendende [ISO 639-2](https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes) Sprachcode.", + "OutputFile": "Ausgabe-Datei", + "OutputFile-Help": "Wo soll die Ausgabedatei gespeichert werden? z. B. \"'{folder.Orig.FullName}\\{file.Orig.FileName}.srt'\" um sie zusammen mit der Originaldatei als srt-Ausgabe zu speichern.\nWenn diese Option leer gelassen wird, wird ein srt-Untertitel im selben Ordner wie die ursprüngliche Eingabedatei erstellt.", + "SetWorkingFile": "Als Arbeitsdatei festlegen", + "SetWorkingFile-Help": "Wenn diese Option aktiviert ist, wird beim Extrahieren eines Untertitels die Arbeitsdatei auf diesen extrahierten Untertitel geändert. Die ursprüngliche Arbeitsdatei wird NICHT gelöscht.", + "ForcedOnly": "Nur erzwungene", + "ForcedOnly-Help": "Wenn nur Zwangsuntertitel extrahiert werden sollen.", + "OnlyTextSubtitles": "Nur textbasierende Untertitel", + "OnlyTextSubtitles-Help": "Wenn nur Textuntertitel extrahiert werden sollen, werden alle bildbasierten Untertitel übersprungen.", + "ExtractAll": "Alle Entpacken", + "ExtractAll-Help": "Wenn alle passenden Untertitel extrahiert werden sollen." + } + }, + "VideoIsInterlaced": { + "Label": "Video ist Interlaced", + "Description": "Testet ob die Videodatei interlaced ist.", + "Outputs": { + "1": "Video ist interlaced", + "2": "Video ist nicht interlaced" + }, + "Fields": { + "Threshold": "Schwellenwert", + "Threshold-Help": "Der Prozentsatz der als Zeilensprung erkannten Bilder, den das Video haben muss, damit es als Zeilensprung gilt." + } + }, + "VideoHasErrors": { + "Label": "Video hat Fehler", + "Description": "Prüft, ob eine Videodatei Fehler enthält", + "Outputs": { + "1": "Enthält einen Fehler", + "2": "Es wurden keine Fehler entdeckt" + }, + "Fields": { + "HardwareDecoding": "Hardware-Dekodierung", + "HardwareDecoding-Help": "Wenn dies der Fall ist, wird versucht die Hardware-Dekodierung zu verwenden. Wenn dies nicht der Fall ist, wird die Ausführung ohne aktivierte Hardware-Dekodierung fortgesetzt." + } + }, + "VideoHasStream": { + "Label": "Video hat einen Stream", + "Description": "Prüft, ob eine Videodatei einen Stream enthält.", + "Outputs": { + "1": "Enthält den passenden Stream", + "2": "Enthält nicht den passenden Stream" + }, + "Fields": { + "Stream": "Typ", + "Stream-Help": "Die Art des zu suchenden Stream.", + "Title": "Titel", + "Title-Help": "Ein regulärer Ausdruck, der zur Prüfung des Stream-Titels verwendet wird.", + "Codec": "Codec", + "Codec-Help": "Ein regulärer Ausdruck, der zum Testen des Stream Codec verwendet wird.", + "Language": "Sprache", + "Language-Help": "Ein regulärer Ausdruck, der zum Testen der Streamsprache verwendet wird.", + "Channels": "Kanäle", + "Channels-Help": "Die Anzahl der Kanäle, auf die geprüft werden soll. Auf 0 setzen, um diese Prüfung zu ignorieren.", + "CheckDeleted": "Überprüfung ob gelöscht", + "CheckDeleted-Help": "Auch gelöschte Spuren sollten überprüft werden.", + "Invert": "Invertieren", + "Invert-Help": "Kehrt das Ergebnis um, sodass es effektiv zu „Video verfügt nicht über Stream“ wird" + } + }, + "VideoBitrateGreaterThan": { + "Label": "Videobitrate größer als", + "Description": "Testet, ob die Bitrate eines Videos größer als eine bestimmte Bitrate ist.", + "Outputs": { + "1": "Bitrate ist größer als", + "2": "Bitrate ist nicht größer als" + }, + "Fields": { + "Bitrate": "Bitrate", + "Bitrate-Suffix": "KBits" + } + }, + "VideoExtractAudio": { + "Label": "Audio von Video extrahieren", + "Description": "Extrahiert Audio aus einer Videodatei und speichert es in einer Datei.", + "Outputs": { + "1": "Audio extrahiert und in einer Datei gespeichert", + "2": "Es konnte kein Titel zum Extrahieren gefunden werden" + }, + "Fields": { + "Title": "Titel", + "Title-Help": "Ein regulärer Ausdruck, der zum Testen des Streamtitels verwendet wird.", + "Codec": "Codec", + "Codec-Help": "Ein regulärer Ausdruck, der zum Testen des Stream-Codecs verwendet wird.", + "Language": "Sprache", + "Language-Help": "Ein regulärer Ausdruck, der zum Testen der Stream-Sprache verwendet wird.", + "Channels": "Kanäle", + "Channels-Help": "Die Anzahl der Kanäle, in denen sich die Quellspur befinden muss, damit sie übereinstimmt. Auf 0 setzen, um eine Kanalübereinstimmung zu überspringen.", + "OutputFile": "Ausgabedatei", + "OutputFile-Help": "Wo soll die Ausgabedatei gespeichert werden? Z. B.\"'{folder.Orig.FullName}\\{file.Orig.FileName}.mp3'\" um es mit der Originaldatei als MP3-Ausgabe zu speichern.\nWenn keine Erweiterung festgelegt ist, wird der Ausgabecodec zur Bestimmung der Erweiterung verwendet.", + "SetWorkingFile": "Als Arbeitsdatei festlegen.", + "SetWorkingFile-Help": "Wenn dies aktiviert ist und ein Untertitel extrahiert wird, wird die Arbeitsdatei in diesen extrahierten Untertitel geändert. Die ursprüngliche Arbeitsdatei wird NICHT gelöscht.", + "OutputCodec": "Ausgabecodec", + "OutputCodec-Help": "Der Codec, in dem das extrahierte Audio gespeichert werden soll.", + "OutputBitrate": "Ausgabebitrate", + "OutputBitrate-Help": "Die Bitrate der extrahierten Audiospur.", + "NotMatching": "Passt nicht", + "NotMatching-Help": "Wenn eine Audiospur, die NICHT mit dem Muster übereinstimmt extrahiert werden soll." + } + }, + "VideoResolution": { + "Label": "Video Auflösung", + "Description": "Bestimmt die Auflösung eines Videos und gibt es entsprechend aus.", + "Outputs": { + "1": "Video ist 4K", + "2": "Video ist 1080p", + "3": "Video ist 720p", + "4": "Video ist SD" + } + } + } + } +} \ No newline at end of file diff --git a/VideoNodes/i18n/en.json b/VideoNodes/i18n/en.json index e29120d6..b06887fa 100644 --- a/VideoNodes/i18n/en.json +++ b/VideoNodes/i18n/en.json @@ -5,6 +5,15 @@ }, "5": { "1": "5.1" }, "7": { "1": "7.1" }, + "Enums": { + "WatermarkPosition": { + "Center": "Center", + "TopLeft": "Top Left", + "TopRight": "Top Right", + "BottomRight": "Bottom Right", + "BottomLeft": "Bottom Left" + } + }, "Flow": { "Parts": { "DisableAmd": { @@ -310,6 +319,20 @@ "ForceEncode-Help": "If this should force the FFMPEG Builder Executor to always execute even if no changes are detected that would usually require the executor to run." } }, + "FFmpegBuilderDurationStart": { + "Label": "FFMPEG Builder: Duration/Start", + "Descriptions": "This flow element enables users to define the starting point and duration for extracting a segment from a video.", + "Outputs": { + "1": "Duration/Start configured", + "2": "Failed to set duration/start" + }, + "Fields": { + "Duration": "Duration", + "Duration-Help": "The duration of the video file, if 0, will not adjust the duration.", + "Start": "Start", + "Start-Help": "The start of the video file, if 0, will not adjust the start." + } + }, "FfmpegBuilderHdrToSdr": { "Label": "FFMPEG Builder: HDR to SDR", "Description": "Checks if a video stream is HDR and if it is updates the FFMPEG Builder to convert it to SDR", @@ -679,6 +702,29 @@ "Tag-Help": "The tag to add to the video file" } }, + "FFmpegBuilderWatermark": { + "Label": "FFMPEG Builder: Watermark", + "Description": "Adds a watermark to a video file.", + "Outputs": { + "1": "Watermark added" + }, + "Fields": { + "Image": "Image", + "Image-Help": "The image file to the watermark, for best results use a PNG file.", + "Position": "Position", + "Position-Help": "Where to place the watermark", + "Opacity": "Opacity", + "Opacity-Help": "Adjusts the transparency level of the overlay image, ranging from 0 (fully transparent) to 100 (fully opaque).", + "XPos": "X-Pos", + "XPos-Help": "The position of the watermark on the x-axis", + "YPos": "Y-Pos", + "YPos-Help": "The position of the watermark on the y-axis", + "Width": "Width", + "Width-Help": "Set a custom width of the image, or set to 0 for source width or scaled if height is set.", + "Height": "Height", + "Height-Help": "Set a custom height of the image, or set to 0 for source height or scaled if width is set." + } + }, "ReadVideoInfo": { "Description": "Reads the video information from the current working file and updates the vi variables.", "Outputs": {