From 08e606df66b75eb3d200dbd29ef44e64b8c13398 Mon Sep 17 00:00:00 2001 From: mrmartinclark <75736799+mrmartinclark@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:43:26 +0100 Subject: [PATCH 1/6] Added XLIFF2 import to TransPDFTests --- Samples/TransPDFTest/GO/TransPDF_test.go | 3 +++ Samples/TransPDFTest/PHP/TransPDFTest.php | 3 +++ Samples/TransPDFTest/PYTHON/TransPDFTest.py | 3 +++ Samples/TransPDFTest/RUBY/RunTest.sh | 2 +- Samples/TransPDFTest/RUBY/TransPDFTest.rb | 3 +++ jenkinsfiles/build_alpine_go.groovy | 18 ++++++++++++++++++ 6 files changed, 31 insertions(+), 1 deletion(-) diff --git a/Samples/TransPDFTest/GO/TransPDF_test.go b/Samples/TransPDFTest/GO/TransPDF_test.go index 59feb175..3e81be74 100644 --- a/Samples/TransPDFTest/GO/TransPDF_test.go +++ b/Samples/TransPDFTest/GO/TransPDF_test.go @@ -65,6 +65,9 @@ func TestTransPDF(t *testing.T) { // Perform the translation using the pre-prepared translated xliff TransPDFApplyXLIFF(doc, inputPath + "find-replace-test_(en_to_fr).xlf", options) + // Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. + //TransPDF::ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr)-2.xlf", options) + // Save the translated PDF doc.Save(outputPath + "find-replace-test-fr.pdf", uint(SDFDocE_linearized)) doc.Close() diff --git a/Samples/TransPDFTest/PHP/TransPDFTest.php b/Samples/TransPDFTest/PHP/TransPDFTest.php index 07ff637d..183ab683 100644 --- a/Samples/TransPDFTest/PHP/TransPDFTest.php +++ b/Samples/TransPDFTest/PHP/TransPDFTest.php @@ -56,6 +56,9 @@ function main() // Perform the translation using the pre-prepared translated xliff TransPDF::ApplyXLIFF($doc, $input_path."find-replace-test_(en_to_fr).xlf", $options); + // Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. + //TransPDF::ApplyXLIFF($doc, $input_path."find-replace-test_(en_to_fr)-2.xlf", $options); + // Save the translated PDF $doc->Save($output_path."find-replace-test-fr.pdf", SDFDoc::e_linearized); $doc->Close(); diff --git a/Samples/TransPDFTest/PYTHON/TransPDFTest.py b/Samples/TransPDFTest/PYTHON/TransPDFTest.py index 4edf1092..061914c5 100644 --- a/Samples/TransPDFTest/PYTHON/TransPDFTest.py +++ b/Samples/TransPDFTest/PYTHON/TransPDFTest.py @@ -59,6 +59,9 @@ def main(): # Perform the translation using the pre-prepared translated xliff TransPDF.ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr).xlf", options) + # Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. + #TransPDF::ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr)-2.xlf", options) + # Save the translated PDF doc.Save(output_path + "find-replace-test-fr.pdf", SDFDoc.e_linearized) doc.Close() diff --git a/Samples/TransPDFTest/RUBY/RunTest.sh b/Samples/TransPDFTest/RUBY/RunTest.sh index 27b65a4c..4523748e 100755 --- a/Samples/TransPDFTest/RUBY/RunTest.sh +++ b/Samples/TransPDFTest/RUBY/RunTest.sh @@ -1,4 +1,4 @@ #!/bin/sh -TEST_NAME=TransPDFTest +TEST_NAME=TransPDFTestArabic export LD_LIBRARY_PATH=../../../PDFNetC/Lib ruby $TEST_NAME.rb diff --git a/Samples/TransPDFTest/RUBY/TransPDFTest.rb b/Samples/TransPDFTest/RUBY/TransPDFTest.rb index c6415fa8..e61b8889 100644 --- a/Samples/TransPDFTest/RUBY/TransPDFTest.rb +++ b/Samples/TransPDFTest/RUBY/TransPDFTest.rb @@ -55,6 +55,9 @@ def main() # Perform the translation using the pre-prepared translated xliff TransPDF.ApplyXLIFF(doc, $input_path + "find-replace-test_(en_to_fr).xlf", options) + # Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. + #TransPDF.ApplyXLIFF(doc, $input_path + "find-replace-test_(en_to_fr)-2.xlf", options) + # Save the translated PDF doc.Save($output_path + "find-replace-test-fr.pdf", SDFDoc::E_linearized) doc.Close diff --git a/jenkinsfiles/build_alpine_go.groovy b/jenkinsfiles/build_alpine_go.groovy index f1e7be62..a35426fe 100644 --- a/jenkinsfiles/build_alpine_go.groovy +++ b/jenkinsfiles/build_alpine_go.groovy @@ -66,6 +66,24 @@ pipeline { ''' } } + + withCredentials([string(credentialsId: 'jenkins/core-sdk-key', variable: 'ENV_LICENSE_KEY')]) { + dir('build/PDFTronGo/pdftron/samples') { + sh ''' + rm -rf TransPDFTestArabic + ./runall_go.sh + ''' + } + } + + withCredentials([string(credentialsId: 'jenkins/core-sdk-key', variable: 'ENV_LICENSE_KEY')]) { + dir('build/PDFTronGo/pdftron/samples') { + sh ''' + rm -rf TransPDFTestHebrew + ./runall_go.sh + ''' + } + } } } From 680cfd84b0b8dd3df1fcf459c3e960668b1a4490 Mon Sep 17 00:00:00 2001 From: mrmartinclark <75736799+mrmartinclark@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:58:28 +0100 Subject: [PATCH 2/6] Added Arabic samples for Go, Pythin, PHP and Ruby --- .../find-replace-test_(en_to_fr)-2.xlf | 90 ++++++++++++++++++ .../TestFiles/translation-test-(en_to_ar).xlf | 78 +++++++++++++++ .../TestFiles/translation-test-(en_to_he).xlf | 78 +++++++++++++++ Samples/TestFiles/translation-test.pdf | Bin 0 -> 130482 bytes .../GO/TransPDF_test_arabic.go | 73 ++++++++++++++ Samples/TransPDFTestArabic/PHP/RunTest.bat | 6 ++ Samples/TransPDFTestArabic/PHP/RunTest.sh | 4 + .../PHP/TransPDFTestArabic.php | 72 ++++++++++++++ .../PYTHON/TransPDFTestArabic.py | 73 ++++++++++++++ Samples/TransPDFTestArabic/RUBY/RunTest.bat | 6 ++ Samples/TransPDFTestArabic/RUBY/RunTest.sh | 4 + .../RUBY/TransPDFTestArabic.rb | 70 ++++++++++++++ 12 files changed, 554 insertions(+) create mode 100644 Samples/TestFiles/find-replace-test_(en_to_fr)-2.xlf create mode 100644 Samples/TestFiles/translation-test-(en_to_ar).xlf create mode 100644 Samples/TestFiles/translation-test-(en_to_he).xlf create mode 100644 Samples/TestFiles/translation-test.pdf create mode 100644 Samples/TransPDFTestArabic/GO/TransPDF_test_arabic.go create mode 100644 Samples/TransPDFTestArabic/PHP/RunTest.bat create mode 100644 Samples/TransPDFTestArabic/PHP/RunTest.sh create mode 100644 Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php create mode 100644 Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py create mode 100644 Samples/TransPDFTestArabic/RUBY/RunTest.bat create mode 100644 Samples/TransPDFTestArabic/RUBY/RunTest.sh create mode 100644 Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb diff --git a/Samples/TestFiles/find-replace-test_(en_to_fr)-2.xlf b/Samples/TestFiles/find-replace-test_(en_to_fr)-2.xlf new file mode 100644 index 00000000..5bbc0655 --- /dev/null +++ b/Samples/TestFiles/find-replace-test_(en_to_fr)-2.xlf @@ -0,0 +1,90 @@ + + + + + + + 2 + 2 + + + + + + You plan to embed PDF functionality into an application. But before you dive into the project, you must decide: do you go with a more expensive commercial PDF SDK — or a lower-cost alternative such as an open-source library or an open-source wrapper? + Vous envisagez d’intégrer des fonctionnalités PDF dans une application. Mais avant de vous lancer dans le projet, vous devez décider : optez-vous pour un SDK PDF commercial plus coûteux - ou une alternative moins coûteuse telle qu’une bibliothèque open source ou un wrapper open source ? + + + + + There are non-trivial costs to switching later. Developers have to re-learn the new library, re-adjust the backend, customize the UI to match what users are accustomed to, as well as migrate documents, form data, annotations, and more. + Il y a des coûts non négligeables à changer plus tard. Les développeurs doivent réapprendre la nouvelle bibliothèque, réajuster le backend, personnaliser l’interface utilisateur pour qu’elle corresponde à ce à quoi les utilisateurs sont habitués, ainsi que migrer des documents, des données de formulaire, des annotations, etc. + + + + + + According to market research conducted by Stax Inc., the average Net Promoter Score (NPS) for the top five PDF SDK vendors is 35%. And 70% of customers express interest in switching despite the high costs. + + D’après une étude de marché menée par Stax Inc., le Net Promoter Score (NPS) moyen des cinq principaux fournisseurs de SDK PDF est de 35 %. Et 70 % des clients expriment leur intérêt à changer de client malgré les coûts élevés. + + + + + This dissatisfaction implies that picking the right PDF SDK is a lot harder than it seems. And to help you avoid the same mistakes as past implementations, we’ve written this article. + Cette insatisfaction implique que choisir le bon SDK PDF est beaucoup plus difficile qu’il n’y paraît. Et pour vous aider à éviter les mêmes erreurs que les implémentations précédentes, nous avons rédigé cet article. + + + + + + (We also recently surveyed 57 unique organizations that switched from PDF.js to a commercial SDK. Read our comprehensive guide to PDF.js to learn more.) + + (Nous avons également récemment interrogé 57 organisations uniques qui sont passées d’un PDF.js à un SDK commercial. Lisez notre guide complet sur les PDF.js pour en savoir plus.) + + + + + + Overview + Aperçu + + + + diff --git a/Samples/TestFiles/translation-test-(en_to_ar).xlf b/Samples/TestFiles/translation-test-(en_to_ar).xlf new file mode 100644 index 00000000..67e4d4bf --- /dev/null +++ b/Samples/TestFiles/translation-test-(en_to_ar).xlf @@ -0,0 +1,78 @@ + + + +
+ +
+ + + +You plan to embed PDF functionality into an application. But before you dive into the project, you must decide: do you go with a more expensive commercial PDF SDK — or a lower-cost alternative such as an open-source library or an open-source wrapper? +تخطط لتضمين وظائف ملفات PDF في تطبيقك. ولكن قبل أن تبدأ المشروع، عليك أن تقرر: هل ستختار حزمة تطوير برامج PDF تجارية باهظة الثمن، أم بديلاً أقل تكلفة مثل مكتبة مفتوحة المصدر أو غلاف برمجي مفتوح المصدر؟ + + + + +There are non-trivial costs to switching later. Developers have to re-learn the new library, re-adjust the backend, customize the UI to match what users are accustomed to, as well as migrate documents, form data, annotations, and more. +هناك تكاليف غير تافهة للتبديل لاحقًا. يجب على المطورين إعادة تعلم المكتبة الجديدة، وإعادة ضبط الخلفية، وتخصيص واجهة المستخدم لتتناسب مع ما اعتاد عليه المستخدمون، بالإضافة إلى ترحيل المستندات وبيانات النماذج والتعليقات التوضيحية والمزيد. + + + + +According to market research conducted by Stax Inc., the average Net Promoter Score (NPS) for the top five PDF SDK vendors is 35%. And 70% of customers express interest in switching despite the high costs. +وفقًا لأبحاث السوق التي أجرتها شركة Stax Inc.، فإن متوسط درجة صافي المروجين (NPS) لأفضل خمسة بائعي SDK لملفات PDF هو 35%. ويعرب 70% من العملاء عن اهتمامهم بالتبديل على الرغم من التكاليف العالية. + + + + +This dissatisfaction implies that picking the right PDF SDK is a lot harder than it seems. And to help you avoid the same mistakes as past implementations, we’ve written this article. +يشير هذا الاستياء إلى أن اختيار حزمة تطوير برامج PDF المناسبة أصعب بكثير مما يبدو. وللمساعدة في تجنب ارتكاب نفس الأخطاء التي حدثت في التطبيقات السابقة، كتبنا هذا المقال. + + + + +(We also recently surveyed 57 unique organizations that switched from PDF.js to a commercial SDK. Read our comprehensive guide to PDF.js to learn more.) +(لقد أجرينا أيضًا مؤخرًا مسحًا شمل 57 منظمة فريدة انتقلت من PDF.js إلى SDK تجاري. اقرأ دليلنا الشامل حول PDF.js لمعرفة المزيد.) + + + + +Overview +نظرة عامة + + + +
+
diff --git a/Samples/TestFiles/translation-test-(en_to_he).xlf b/Samples/TestFiles/translation-test-(en_to_he).xlf new file mode 100644 index 00000000..4aa9ee20 --- /dev/null +++ b/Samples/TestFiles/translation-test-(en_to_he).xlf @@ -0,0 +1,78 @@ + + + +
+ +
+ + + +You plan to embed PDF functionality into an application. But before you dive into the project, you must decide: do you go with a more expensive commercial PDF SDK — or a lower-cost alternative such as an open-source library or an open-source wrapper? +אתם מתכננים להטמיע פונקציונליות של PDF באפליקציה. אבל לפני שאתם צוללים לתוך הפרויקט, עליכם להחליט: האם אתם בוחרים ב-PDF SDK מסחרי יקר יותר - או בחלופה זולה יותר כמו ספריית קוד פתוח או עטיפת קוד פתוח? + + + + +There are non-trivial costs to switching later. Developers have to re-learn the new library, re-adjust the backend, customize the UI to match what users are accustomed to, as well as migrate documents, form data, annotations, and more. +ישנן עלויות לא טריוויאליות למעבר מאוחר יותר. מפתחים צריכים ללמוד מחדש את הספרייה החדשה, להתאים מחדש את ה-backend, להתאים אישית את ממשק המשתמש כך שיתאים למה שהמשתמשים רגילים אליו, וכן להעביר מסמכים, נתוני טפסים, הערות ועוד. + + + + +According to market research conducted by Stax Inc., the average Net Promoter Score (NPS) for the top five PDF SDK vendors is 35%. And 70% of customers express interest in switching despite the high costs. +לפיעל פי מחקר שוק שערכה Stax Inc., ציון ה-Net Promoter Score (NPS) הממוצע עבור חמשת ספקי PDF SDK המובילים הוא 35%. ו-70% מהלקוחות מביעים עניין במעבר למרות העלויות הגבוהות. + + + + +This dissatisfaction implies that picking the right PDF SDK is a lot harder than it seems. And to help you avoid the same mistakes as past implementations, we’ve written this article. +חוסר שביעות רצון זה מרמז שבחירת ערכת פיתוח התוכנה (SDK) המתאימה ל-PDF קשה הרבה יותר ממה שנדמה. וכדי לעזור לכם להימנע מאותן טעויות כמו ביישומים קודמים, כתבנו מאמר זה. + + + + +(We also recently surveyed 57 unique organizations that switched from PDF.js to a commercial SDK. Read our comprehensive guide to PDF.js to learn more.) +(לאחרונה גם סקרנו 57 ארגונים ייחודיים שעברו מ-PDF.js ל-SDK מסחרי. קראו את המדריך המקיף שלנו ל-PDF.js למידע נוסף.) + + + + +Overview +סקירה כללית + + + +
+
diff --git a/Samples/TestFiles/translation-test.pdf b/Samples/TestFiles/translation-test.pdf new file mode 100644 index 0000000000000000000000000000000000000000..29cfe7c95c48f19dcfbcd4c484c929b86ed04530 GIT binary patch literal 130482 zcmdR12_RJ8_a9|%)20*|lvJ3N8A6RU$rcr<7)&TzjFLj7kfl}IHzFP!TB|KK&lj^b-K5OFl?{EPCyk7;-RKL>SW*3`dU}#HZ&#=^Jik)SjVShuEI6eu zrnv=pQvDF+a?9dht|VMAr(7+*Fu$(vKUn=k0;;?*+C8F^hAshGvc+=51 zjG2e4KiUBYiGT4*?oDnq|85~^bXRr}&D)Lcj>c(fU@90pP{cYifH%}`dVE@3UmT(XKsZy z@bROewbXHHE?6uMP0~`=Bx$%}SCdrHcr2cP!D?b~I5nJ>HXf&q(?qlXDC#LI1ybgM zBlx$DpX+Mv#fHZ0g29olqC1`LtBt{I*swu;13}%#&kcjq($d0U@fbW_4P2q-ztNjc z4OH{?SL%Km=Yili{7gfdzl)!TFWtk(8$8=rno{WH8WjgtV=-P{kc^;m zd|W+NZ~WI%xDW3Cv78$CBILqTJ~#o&C%}b6$ho?3ALtw4=Lt*C)dfTIqHgqa z9EL||2)Tie|0_p2kf;qni>K2dQR_hsP7MpSHe1l(2xM(6VGb4#@YKQdxU&0BA3s|k zA5T42dp7m-3;-$w44)qwPg2LDRhD@GleNKr7UBu)J9J!Kv{(E1c~R+lR9|0D4;L!b z$}j*59ZdHr=qkDg-IK;`@GSZE5;5FdDW3G+*Y&y-d;wqW=>fG&ZBMGVo33J@nk#KJ zHNcaus0WO@?P5y{N4Wj!V4$Y#>7mE^0F?mOk5wtCdM=Ovef)YC%u!KRjo~6~XzO}k z*G~m8>|&w&;9@z2K?S>ZD`)SA@+tg}NQYA+t{{-L&;jUao6$CI@bPo?2UkLeR(?LN z0WLH@b`t@@MSFTU`%(QiqH!d3sBQ6F1>a-q2bu)URnM5}=}%)_!1)SldFJNYhCVI< zkS>}U>IDRNxN1|eL=7#f3l=nADprj|Bf6@Qv06kmJell@Urp9pP1Vwb+aT|~?5CM} z`_rl3E;P>5XaqbCtKqB#p5{tb(`dEv{F`05cjg02*PHv z(F2wleByQwdfnX%=+Jc)H-OFq>e|_z52u&c?C!vfJv`|&KQzYJ6H-;03-A^|zY2G1 zcpRSG-EjrRpIYwV|3Xtb!FxYvTXL{gadC} zzc;mR5iS}&PBGy_n95hBE&hdD7T>t#=h&IO{MuFOn;-Mf-Iy`5IwA^t$L@2Qe(_^> zlhGgV_);ccO`E)8gYU$B+Qn3r06CvuvgPef0WFuFFO5EGd0xyf#6r3*b+_gDmzRIm z?Y$O=N!_|TxMFf%>mifSXB}n@m`9Gai3xjev@~Y@{4n;`sui}6&!4~BxU#JAZLHe? z|B91X>5B{P{QT{4=MvD4=WdMo81eS;2DJ|T) zenzr!4tSnc#N=DjS2ZQY1NBeG9$n{cpa1ji=f~@_f2qBb9<4KHf!RKaYPGcAh-IUV z@d|mPsiI1&B$Z7fiz4ge*6HcvQFaG{wyVV0nO@zeG+l`%7hr`7Ul6-DsMJr_`Ksvf zHM;uvkoaW%?_>7~g|9jJaJ03?YODDLvA^%S&n~?$Kkn z(WFY=;4|i1ERb_l<7p;`rXL_p0GGU6s&-i~N^-zHqWfw5+-AC`K^nbl$ zPg_7}Yhz2H{87@Z>8dG3n%}7I#qLt$G$OXo7=L+=;-2)JqsHj5YcIMjswuaC5(2G?O-@jt2Na_522OdU- zzdrtH+ ziP0Y&N~D{PEuGpd7O}z=ZPZ>}yjx^CU1*bsd<$N;(ffQ`Tg8p$k164*wHMasy<7Xf zWO&Jv!+!bC)6U(nJl}zRhq0fyIpkYs!}Yy|!X>U(Q`5idLNyI|IMDME|6}{H>;!q);+thW0AYR~p~Ew|%NFI1rFD zX8ex~))B^UhAypw*kA1NBbaRC;+l>sNMan8vouRMoYfNvdB?6wRRBPTFqX#+a`nIicp% zn>EYBJI1`szq0jek*9L0_N%NE1x?+~MQ693UJ{w8ydiVdt#r*PLbECwlt{J4r&eyU zD8C+NUb!mWVsVkFTFLGG%hmTwyUdSFKfIxCR*vWt8UOFH#@e4xb=ntJyZF7pw|{zc z!=-V`0@2_zJ3{82o;87dWO#FNa9By`_{Gulv!=8?sQgm3)V}f##Ywp1CW<8eb15^H z;eZn{Qf)J9HaL0p&CGzOVja@&X5Pt@=x{$N7Ju0$c~#mz|_ z5%YBqZE3?N;=Lf{Pfuny8#JvKrRget4_@r|)!1&-gs>mgUsG2c_s-N=WxFziN;rM( z$+^zt#7aGJ)fmsXpDV2kYvk+N*GRq9oiXX$shv$4ippbCs1w2s*Z^ChbS4LH1Rj(f8LB{tncfzRVldVV*ZFaJq`cwkqjMkw%3(Lp-czRgHT_ zHryL^XKyia?b2PLaW%=ir@WZA3^ys^$A}xxPv~D5of8|Sx9y6r6Zy(&v~uIFq|yG{ zr_K$%6fojotIUe@&tjUlp8Bs`cuv?{KF&UTU8h}1HnT%Ham=*m%$s|QB3-E#XFlAF zw@rFw|0D6%LK&MgbeZPxZTZQ@P-Xg~&Vp?%|11p1io2F>7QJHa zx91RLZ^l>1tPXlFiI*yC^}N2e*} z$>*IChcAU|o0mr(kGl4hgsxrJs!=O{>__6!wEN1nYdh|Z(@Uz!A0anhuW4#^^~-!* zV2;U*;~FPFyQsB1ObN=gx%$@j-ObKzx9|Er8)3AvA*Xy_tedZflW_ioJO3Pde@&}s z=bXT_(KBXGbJ~~uJa~1dXiPEr$5hv|On)C`r!^BTGebKqi#l^BeJty+?0Dz$-8ZMB zX3vY1JadCxyWg}oZfbv0fAlD&YwG@hmcyA_cSWb%O&%M2eU$wr>kThUp4>eb)LGqi z@%N|D;c%M-_I;1<+WF6yFHk(Zz4KwiY$0mNyr7Ba#U!?iyfv$C z98sX?f5GLVM%tk_-&cNrt9sUborH9#PL15rkB?to->X`?>hg~+@i!}t=7)BP`KL&P z@o`H?-EIkpSGWUDUu6~s9z+259U4ZURSdPEkpvcp)52*H$nYRyCKfxBeHnB|AH#(e zobkenSu0dby;pk#qJjIkV%98-seuK>*B6ejbf4gSZ3WySXea>>H#lD|rTO_o!&ViN zx~96;EDXmjg{ljNmx!8bVm0t2td<4=Pn?C}xT~Bx_VQO}K_P@SG#5JbAX{i?f>z-f zF@SGb?kn)uApf;HBth;LU4J#8f;a|R1vd+`#2+|)D&|x_x`+3y?#F0#KZYeE5PdRm z2csBpn}Ze+0%$Q>i>QIdf!|P>AVgx~=izGTvEBm`i9ebQAKQQ!2NZ`Q;UzKV)Ibwc zLo^Q8pKKuUyTWlPe>5l)3QBRm}M#q7wB0f_o|`nYwA7Je6YK#$@_*Y^oTJ3!Uf1TRO@ z!mq^Wd(vpGy}vd9!9OT6fQFp*#Xuc=e0eUCgl{%BHKh3YQ8%I;03h7YI4ltRN`QbL z2sHr&q4L0A@D0t?gUa(5=qZvI%k`jXgV+>HA^-(YGW)fFAbbM+T)=BWZNkUX#}5LT z1|Qjga$q@Q3~X>{A`2Et=m3i*5}-0c#chBDa4d0w&v+0s<9ts5!!`D2Jh+~74FOFg z!tw_9648=GB8)mX&;TbmH)x_+po6bTXgsG9WKapt)mq>)`)Y2j$>4FC@WlX2qd>Ze z4IMHs;LW%PBs5WrRk{gyJtCwTi!mnP^)%r30rx>+S#XOa`~jzi1&YBcA36a-9pISt z>a1ftT8s5+;8wVOv)egzC-}$--Adxf>RMWwoMTq_)+mtbLigMV-3K88w`>e7f68iT z_=eNMfH&}?n|ixK=RvTO7D%UfdboL`C0S?Kg+kRr6gGgeB+>9qeU{gwI6O~rT3}Sp z`)ZOv;sbuS9%T_=G&q7Bz`OO5qa;F*JqjcCdNFPoyl>0^7?9HZD`-8+(tyfhV-Ghm zHmH2y=G+P4?dRiS1C-eT1NAiUo1ihKUcgituz#BZl?PY((m*%BQfzYrV3FYF1s-7I z&YDdCh1hdKes@TVZe&j%`n%D>cCpTx9@*J7me&CJr2c zhY+|`2G1aHs{$TD;MN2@fyk{f2^_#ugC9o*N8Dz0ntRaqN*`TKZgNW1QQ~|sJPLopwJg5&BIXtKj7dY^0I4*E_P#qR<@Z&&zxX6J= zbAbZ_z;S^ifckK8BY^sFaRZ_OGX)SF(9;N@zvSWuOd}qk&q4}F4G$n@9{{_~as;4z z$l!n@1t3p6tLK0o2cE|2c%aW%aKOOcj4ezyYWayDtIX`<390_iZQ02g*@Fb2DKs&&bIBh`#)Q8Mz3!o4@nIi>o3z<^` z&|2_hE)JTYK3W_pfV$wdI5>cYgxBH-L6e9EjyGE(pq2!nxh(O37DfQ-2@asjX_C+c zpm*$3WN^T(f)+U7)B#+@g^Pp*2b`(gKbSSG@q(M6P;)M-kcT1v&#eOV-dtM@J9*!7TQHJtp93 z_<4Bs@+1-SrU(xhLKyOZ9l)5&K%eSQa|IHE8p=veU>Y{ZtV?WYzF-glPY+_OC>FMs z7Diyo8)&r__+LT8U%Hq3~B^*EDrQ?hCW_Y z4{yi=2L7;dfH&;W!xP|mj0KqWT?~zJ;M3qqY9R0pn|RI#Fns8)B2?pkt4PNGTMcno zbs%XxS`Dwcl2bLwKT$WR!Sq)*ea`?Is2rB`?^Oh2Tc9YwLaLE8CAqcy1C@mRb#^lV z?rI=t1uP2z#!{?)kSlB0Ch)x!)Qq>~zzqqy6tsx`<}@@&L;yGev`Y4z$by~m2RGW< zY>+Ms^|^g)&w=#oE~6Z_q>Jv+@TBgQ6SfvN6&D((zu>6|#ZY8|k>U1p2k_NibYn}S z1oew9siUid8y^gB!8S6;8PZR7B}^ilBv`nee%K`6)T-6Gp{eO*U4CoAcU02MQ|B@t zV@IH3tCK1g#@vveIKla(1Zub>de~SLeq*Y-+FS*(SNm?7r7y3M_!WI@mDnDSe8oj~ zim+e1cB(!3FbXwahAgHMm+2QjciqKvB*vm2GVvQv9Z(Lp9{=&1@VYGGr8UR$-*0}W z^}JLvcInnDv)mH&Phh`!#4mdybAYULmb~Hd*#j+P#~aU1-8p03@T+FRdFwlCgyw%x z&ZEr2lsy~cma8|@Y}@x?s9W^Mb62#Fo*Fkw^x>)Lk8_RlmoM=ys(Cx@unN&OX2z_K z=i@}fum;L$aUUigKDqqFevhd_hYP>QlTSZ)4%{1NbiBA&KUBVI?vD1fqlH$dYs(+* zzjyT*<<|%wuX*p6=}K-1luoD{-krz}ccQvbPn_9M}NOlh07T{h!GX-_SQ^Pc47xTFcC zJrzq=Z$>p|k3hYBfLfd}s%~p7Q|-V$G5lAJy87B*H5C%=tv2;~4^J#j{U>_A>su$k z69wKO6-@hK!;*$6zY?0`G$wxQT&ZE9Qo~9p#7ME*Xt_6AhNVxqMbWB6>7Ef&OOm5+ zot8e$bJ%sKxs!+I6^Hmr#f0rHmiTJoJ8iSX#jOrb;}(TQIEm_rq@l$XDI+6C*i%OD zne#^Er-8G|xTuK5$5qduW^c9KBaPQrtCTz=))*0fT&~ia(OPNE5T=jL6%H0Lr;JHz zN;-rc_K-TwQ!KBzAbs+#tv0V@10^nOTl-2mXZ$L$F~ujo>a}4v57Qgt7&fy$;;ZT~ zsVOBUvSSq#ji)crUK|;x5Oi|l2V>E_)~@sXMruW`peXM(xium#($9M2#N>MSasNc$ zshW~8@v~7x)k+4HNemK6(08kRA}m^b@RgCc(gKNS@!9&i$D^?eo|?8r`iA?)V$A~= zP9OKvPzbmEu%Rk?snpS(`K76)!%G`V%}Vo1?Z@qOHELEg+Vj8^zi;a!qv!h1P1DHSHCt6Yr3F4Q)nc${Qf-&846nKbKR z+%j9uCG%sG-dW8#^ZAiNV@RV+qgUhjDY5SiN1UQPc$D!rL*aRod*Z{>?ihw_?#z|? znB=J+J~HGV?0#67JdcW<>>cB7tZ==^uI%Z3@{P8CzSYF6ednUAVRJb1NbF%b%{8=-+R*QdB`6#;f;C)*3(+{4b@($%k1n&w? zGg-fayI6;pmyA<&QwgabQ?u<8FNL^Xzao*n_XYihY{pfO5if$CuYRWa zBE)G^@%rlWTJY?c z-Nd|udEV=FKepd9e|4}a>yB5==Ypce=!ry$AClgAgqjmIYimqirUgmqmQFh`%|W+- zxm`C*=dP}a4koC0Rq?7dX{oCYU6ZIiUc0=>x@oF@F4ov?X3d=V=K7A4?ew;o4xJwX z-_)2dUu~*x&2-%3c%bfZo!VHFIMqfex$(j8n?7J#<-Zk9DH2~G?mmJ%?yFbQvLw8( z!>h!w9Eu0!{5A{GP9^emJNaw#+9;7`3rufqQXrM;tP9Us_G_bx0#P$VjoDB+iCRnz zPY`&#wpt?YfXzNopCdu%)He9wSPlIL!pK5LaP~{%nzH6 zT76l>DcE$Ji%dIC$a8vzkw@Kj}WR^mq1e_w#<6 z`+kbQsOI(Wb?@%J+f}<4SbHB%kFvD<{}K zT0#%r>129+pTAk^p`~h_ClA}J&e5~gSGkROX44#|x>9rYQP2bnmT4;;x<$GxKRbEi z@F=l6;*?c)FFuWhc{s0zdLhrGO|Lr4ZyYTjB|6%>ZqZB68Xc{;c1zSrA&1|GbB;_uvggRJ zf876hd{qBvTD)xh&iK{@*MtYh<{!J5D3=(W*q-E(^z^vN@vLO!AAY23@auW>)KT(dl@f>e=Hsa2UlY0!4Ikh5zxnlc`@2!^4!)Ovf0lt~T>D`Bp|a7T@$E<7j~$=FKac$! z|3&3XM$`PJdtdFozWwI+t*bfayUh0#CXrdvV%1Xn!|O*!YgC&|+nJx_pJnaK+TV9< z_$Bu1aObSf+}~!uYr4F;x`vHJwQm33!Dm(q9#*oP&_z^dXv6{M-CFs0fJiGVq`s0f ze&7rkxI>7Qm}TxBbQ(zpY|U9@?CGbMq~jd%s+%evtAu!ymQ;$t$WXIb6FU&_?*5kZJp^F?@Qa< zR{4ckQ$nnrP1i_TsXZDk^-AccMv}@rHG)`lwuzeh(Lpq^Pc5tt=Wj zd0f#=H&^G?RGQ2CS8rawtAE=tNovA4>9G^XAKDYQ@8I48`^#XsGEb5$4RDNx~E+rJu<;nQ`G-^5t{6r?V~=9KUq->Z#1s{1aEs=cQz)g_e|> z?oU~ipc#Dgp8b{g_Yz2<#U)13hg4T)ZN715$@wQ2R%VA>ziECn+w)~sa9R1vyw*=I zv%89l4I*~S>aPD)dfO(YB3^gH?~)s4htgK$ukXBh-yyrHCVxX$@pY5ki8{eQe%-jc zEUoTZaO>~uWtNGBn>&AWmQ^?wcKzyX4Sm$5RMUn2DlabcyQ^!=>duH)d#9h74*PINSnz<0-R?NK%!s6~X6Dat;O9H|Y5NL(n%npl z!x<3+)!?L#5xWOi&@&JZ_}bjs1b)7?@_Q0gIgS>X+OVgg^v%&23n-n_6JtODV|7a_ z_6bWXb8u)wLDT&Lz=WPT)qgE?r8kWoe&EjKNMc;5;7T7~){WgE2{`)mpA-m}Fo5!) z`?`yR1AXk`peaKOA84wE>c&d$H}LWD_3?+S1qfBp5qELoCXngzp!-|V{A{RRzF>Bk zjA3Q$!GQ}PIw(2^;u}1{4kK?Urw_V9lK?^=taLvxXNAc3E{Yf zE^(|Iy8u=pFy+8OlL)MsWcOIQz4LvYk6)#uD|5uCPUS5j&PIi3#+aqd;WC|u=q;$> zC}QWeP(H{5v&cnWA7tV~Irx3PNY4-sfg8~Qcd?>#aIM&!1~{V10oj}G0p`W1oJn8A zL?$~-Y2X88n6eBzkY~?I1cJ#}SF{6!t0dg+y2D9m_$8ou2YA|q6&$vVuKOQ{#XNg{1`oDklibA5?_Jf&!5sum{5F(Es2B2=WnGAxS=8 z^C&5g20{@@NnCfs0nu^ptFp_0=9tvAph;<{qyd+qu1O#v%7M%WTcjMguwcTrZ;JvZ zdLRwqsXdP}O0ojtX!sQtLrTep4~~rs0zTHHNnbh%CKS3~S#YM6NE(1nwl{Y^nKYd# z6IoDiG7ncZ)0H_D$T4JCmDmc#_lnjt;^-n&s$|YmK5)X*wtogrNNPO#3C}SK0#5GSGhh7# zv!{OrPVzv^Z7(<_WP*(-^6O5Fv8y_i*jD*IvB?^?w{|xq{lH@5#S`H! zQ-;!|<)#nt#}i@p1!->wq@K+U?C!I{s4m1g+42@+j%0gecmcXn>=Q#wkNLA~ldZ6n z6DsOr_BVcTBKwxX!3n2VAV(l-^- zSDFx+B3t#GOy+H2=&A!a=fZIAP|kkI4^CvyGB`Nl1Q{fpaH@tt;Dil*UvR?dtDFwy z|GRU`Yi(axE@HCGZB^wY;r98W?Z3Y3&K?FrT?Y>2jNt<(oWI0**FnL_O8Vu26Jf}Q z)Yx*9u=pBVkk9j1v=cv&&XeWb_SVi<#!c&vS1=$qDEw}AGe0DeeahgFgvSazNFr?b z&>{(&_&yaA85a?tVh+d+Vh>YD?ZTA0ka6?7?W|E^D5`4H3dY0T8(_CKq%^yfAD+lg zWpH@HLj@i@5k`Dy@q}%BUwE>z&p6gcaDaj}M+Oj~?Qh)qQ%owqY=>TFU_=xO%!tvG zvoG<16bGk)a^81Pn6gC2Iw*lmg$goE{H^(i))>{+nWOlHK7pD6yVfM0acttlH9}vfZ-ILr_(7YZz*{(|uk8>UBGh{c8x2&CK` zbH2_kM8D~7x&I@OMiw}m$SW}J0!0-f1?>*k8?Vm;>D>3(N_-(j*!#gk3W<%k`{d@( zgITws?LN6ofj%Hbc-v6-3C$LP9);bPL97Lc=-6w*nrAi%&d%@AUBa9Mj`k1E`(UwA zkS-;Q111=afGupFP9+ZE+_Jq7h?Bx+Y7v@`QP+YdKY)us?qM8yiBl5SL!K}V=RcF@ zzfAW5T7IwQ2(#z}B2O-zh<|hB@(zGr@RKLEWkU2pbuB=U1OID~{(EsEEm{A~^WVhD zqBiq1Pnd=%7;(a;rO)OG$%o@=^w4g$qWA9wBPO_UFx~4vYk~jbl;YrO@ft*!t0@?f zK^CuXw*|0@cti%ND?Da^{d#EN!143hUqCHTtD7R!7x@P1=)+vOKO{=n3FB#fFws>o zqU<-ci31$do}z@(e7IJyJMRLSDnSAnQ2n<`WZnf1rW*bkS;F<@ZI&=kSRk_GQYQHu zM!>`6%2I%{I2yzOc+;*W4&zW#;;5ny$LbRc+KQ8ouRpjZWp0IMcE%*R8Nu}l=VR7r zhsB`np-_Y>s?MSCbHQNZ=pTZXJNktRf}Y7@eG3NK{)fMWzcc(D5VW2prlVOo zXY;BT$NA~2o~?G>Gv%0vYEbOjgV$p%UyXmcDkksYbq^73N|ZrK6 z6L!{PAI*H3lifu=KdSt~A<~gICNeW#6j4@!nF5LQtbKe{7TE#yKN$Kq&z?>A20?9Z zKMOCEA{dqJf2CDUvfW$o`eJsuqu~!pq$V1XAwGAN+L{EX?vZbd@-eN!raN_K>cM z0IxV_#W8F2$q)v%h+=bM)Y~VQCY!v8^S`Q_-?%IoI8C!tuBr0{71`$uPETRM@j6ZL z!YYCRwf~?6SVrfsfI1*O{ra{{OrN1E9BgdT^olWl8dGjpZSwKmR!q_H!COxF9A;>Y zgY+~zBC~`qq{z-@kdVTo3|>7&81|vcCR?AxI|&jWJBbRkd!A zV(zqKO3MTrCXq@{j6pM}Y%e%|qE!XTjoBTTN#lztV)QXc+Y1)Q={a)%uW}?9HSIsT z15s%Hf}b>??lh2B~gQze&5A+t3_4Ui)_40G%BeB1K@2zWuq<2h z+v@Pux1Sw<{=sllSSG{tU8u9nlA7yNSNm9ex@Z81Q?iG$&hu4KWEV5Io)i{d4;4k& z^r7uZxvL5CS5YL-P>^xpK>}-+tsj^?%I5wv%9Oy8<(~^C>Atj&@$uZy#?WX z`kaFOOLWHpT4IyYP&g^QtLw24x$>y;E|u-4ZRaMCC*>Fa^ZCQnSjx$l9|Nz9{B#Vm z#9imJHu41)+4l?*Sa`0MXG|k7(j$($UTYtg7||sN(h?6SpBM@!O>RdSI%2EFtYGNM z1{+hF_Ee=bk*iEpf})4#7f0!B4vpOoz|`O;$X%oZwD(d@*}Q)_9O0Z z(H{pyPi}i#24ICEgh>?)hMa70Nm#-4DhDESY*ejN@)%#{sPXy6`Vc)iHz4ySUsV5G zOsO{mlC=)CK&){897r5k>i2K>!vkBM<@@_Od3^>+nt5n4bHw;gW$DiCNsfmZW28E_ zC_u}znBKp3oiCPuE|>(%tA~an%=*x}z}zLU`5WH9#emcpfTz^X4JMh+hvI{hLD4aK zAu}T(?Sz9#^(K&Zp32BP%okB)A2YbF6qXt{9rU^ep{~QMr?5@-+I0!E}E)aX$ zKMfN1zr=$KY6Uc8SEj`H;7~IuC@^SMNs4C-pOCLC!3_*L-_78+coGg?g`X|(K@Lt~ zk@Zkegh3x#lgr&rfWOHF>(6t$Pj*@^v<-*47L=Mne+JAJN%zxA+iL=11f805<%EI)_e4sHH=5H5CsY9K;|rYCPP%(BX`xlp6}zE z^u(Pp9LJcd9n|%CB0Oj5?w&c4FQk7gaKjQ?4@eQ7`jF}=p1U;)Uz>-AHz?wmBf(9E z3^2pX1Z3PoO99SXYPQX{L}k2}+fKrLyRuE&^nP`u?%%m=Q)yMr@y8Xr4%mTdE>EZI zK)%Q#%>3YbGnVvvAd8654>7W^`S05TBf0_sD(iqka-Q8;negODZ044UC59eYvU(@SYhs#Mf_D3 z-ZtznsO+DJp&Ke3WXI5{6+w98Bkgjw8N*wz<-;*_+2E`kehSM&$Q&H5uBi4tyB02;C!m2rtbb}Ru(^3TWupM<7 zVo2=-@HSNXqCC;|#q=-_9|TT`EAF2b3w)j+iOg-73XAV#gdU6Wl)9 z#Am08JcTi8DO+_P9M0l5Ta8B&SO=-PtgS71Aw@*%hZa&6tF=!T3dwN&e-9}u2D@AS zUve}r&&|x`r=>^|?O-A8l`_QI^im+5EQ@v9H>8MeL4c4BXniC)Hjqy~k-g90j4x}WSzb*=nD!yoRM_(O z2`iEfEJ#=fmN3*a{~!{Pe_$G;SXXbB_oQkxEB~NGE6k!D_pPl+S6^^bIRkW+0R7CBDKjEy_wf8M$W>C4Y~M9LczZJGFk`rE@O4AB zu3pT}MDL9)Zg}w);hb)i4lL>GZP_NElpsaO zL@HRH;^wRBby>PJSF4PRK1-O3;p z6%t(!SP?^qA%?a82ojQUEJ#HikfrT2e9!WVmNM%*)=r0Zkg433HJl%)JhbM)feH(b z7gQvXcxXXo@r?VlzDUloAVD37_3h3=yOgv+xN7DEh>-uwLMp%5P<}o`Lp=EUZpiu` zSIOMN7tuc#JLqCqvZ1wxrQA7_QNJIxjMdA`2aL@`1fQrd;=X1{M8MRWmz)X@RX!*qbLsl@(S@1Wyef+13=c7&u*L5aP$a$he*)0S5SlxZ zEM1T97H5i%3NDJR4Xa!$)gHccl>$rx^*x)(Z{G?$4}W=ZfWkuS0Vu+v4=tc9HgVs8 zBAt4{+1vqU=X2Iyoi}Oax=Lfk=UADlSs`}6r_b@I`&O>7y>XUj#Tku5SM0LpSY!*Hc(V$au{cPGlc5NH}{(k6^~FVBqXOdW0ky|G&4qtslyu zHO1tD%XZWjRhj58rdlwCqE` zSKOz5B00u_1ax5DF1+p^OFt8Vw;KrQXIQx2{HnG4D!F8B@12=r`67z!WCn>SJcQt} zxJd5s5F^@utI+^re?@2}AVKNU= zp1lG#1SE5KNae|Tk3Q)O1W0Tg^KV z6UqG?T3NEFp?x+@Bu!L+4&i{Z=D^C8?EQ-hs~_y}t16|KnTOLZo933S^Jy5Rnb)$= zP2vRO*NA<;W)z{G<>nmc<3|v9=%|ClwbwwL0Fx#KF>+(QN8kM(atlwkjzEh@K|LP) zKTrm?&0%$f1KnDi0IeC*ql4}F!~qu6y}334xl<>{utD!Kn9a2bu!t6;S#JQVCwpC4 zg22d^tQYGW#lJq5-8w%On2mRXIz00%f`Ptk* zN5W*uj<+vG?rl1>eQEzBOagKnR6+Ko16k={a|vl2SS?t%s4KJ@btdHieVd1yh{2-j z&v`!x&u-jzuz#pwP_|6}YYK>IM|{lYm&rju?zYOY$~{I-M&2$yt~4~CeN_n<&c4b1 zXa|<)dccZsW``J7*w^jTMfzJL%z?n#-rV_Q(sZUwWC7JAF^Mr#xjizbAUSD_J7a_b z^QV|pe%TJa&cKK$$O^B!n0EL5FMAn*4U z05xcLxZZgE#1K@~+!c(5-PvcLO{g@pvM2M?)IZ0=WXX+JQw7GuB=pb2B>XKN=0GN+ z+L@o<&z#O28(Hw$$T0*g0G(5{iO7`MT1z!b{F=ObUTv}>w7R!UbyhWBL=j_;LApx4 zIhX{2aWDxmm$Yx&`Eh5LPiI0HP*!TN!HV%x@i2ZJ`;d z;XAUT`C|H?2e1DvLfD&sNe~$SlF&c@l7QR-R*;r=K>caY7{oBf9Le_WQ-e#R3VsO# zrLBCQ*knBxTH`zWWDdU#011DNfyt5_uk95W1C#Y0eQPR`fys^!vX+DH4wkdSc0IrT zx0x|S*bYgC?7tA!%G2zLkDgII&Op(2qc07O$5@~xaq3ts8Ceh?^NI!6^qj~;3`apM z2%P14G|!M!lEC6$q6yvGt#aanNcQ8<4ox96`d*xk@RxR59S~`+y}jWHGCl}=T}U^> z3(%D&pBQ3N!9_dtx&n8@L(}-5IaBzVTzIEawmUk=ZWI<>59Jitd}04Pt`gv#LpiT0 zxGcJX!P?yLWD=1nH@AHxr7pxd+42?yYa|4#7z8U6ap+=49Cpvo{=^qnq;o&GF--4G zR|!Z8QW!S-9zR%- ze91v-YwwL$2}ly;(8AjP#;b(CwDIb|_5?u22hkwlu!y-gkSVfN&&en;6jilp1>@oF z4e;31M=|>}Ur-_D2gf!IPFG>U@tR;H4|0e>h2EoY|L8C6!TP5_1*4iRkO>A+r0-)k zb3t9BmL10zRKz6iU^Nx$M0H^736U39gk2wETw$}{=Nu}$Y3N_j)By&Ox(BMq88d~LqeO!B4IIZZl$J6@w(Gsp zPYf+EfhT3oZOvK84^<>}agVF*35X^@*E+)u<{8r4KU%M_kODcCSr0L+{YRCMTt#-+4q6=wq$Gp3 zsIEmOa&rfvZI+N}%>Nb}?2)gGq%Ho7n*3Y7a_>D)31oz69b$R*pZ@)q_B!CAk7O?I)z{iJqb zI7+u0MCn$s$NdzBt~&F>`?>IB*XAYJclntX|40sU z`%?kVUk=RrLi3k!FnyR&A-2lR73q4uoynRb+02?Fxw|JPhA*rLpMS8L3On^Yz9*8O zIK;5_8_OZ`@E8BTTVJH_xzn)Ds&XcgIdQ9=Ge{*FRwcHA@x7uI4!UNo%UQz*QzDX1 zIXFyNa^s255s@6pA;pyS9(@K~i99Sy0b)AnQKAB4sx+JJz#2}-b(The;RH)lkMGFA z@I@8j@DCQ%UNIdalB+qysP-GvA^xSkSO@4QA!akvlaP~{Ad+qgBI#^Rjd$QXLrugY z1|5UNv{yWbh$NB@F{ZHT?<<}|gf|lX--+k&Atud`=93h3B|m2cKTSnaUk8h7uXqj- z$!8r}RQun8mB_<+6`=hc$exb9(n;WW4hz*Sm54qyVM&fEUrhg4Foz{K-aZw{s~uuY z`wiw0dHAjZ#B@M&Bv9}HX0J3D^~@y!lV9pg898WCzp=` zP(VC55oQv=Pk*>1SqF@%w<|4>=8A?{?TgWX-^i-uVt8^A>L!Rt@+G^1cv5!-o0&hq zfuHZ-r|m2FX$C*7P2lGnzb&zeTn1&YvdL&xQOKepakBd=PSFV2G(&|#<$i+-ZTtES z{PbBar+4pFE(w&&>aQVLv0fRn^gYV$@yh((7s!F1xVbE}UPVK%%<5FQMZ**scG3Mb z5h7W$8-fKpCzM32Pqvx>Hlpu}Gk3n6J0&)M()_3i^5}etZRjLtt1Be`ckkc7mq`5j zbIb1covjTap>gTkTYcJs3p>@L9qcE(&1@?unsY6o{_Vl*{(FnBE%^R%R@foo(}&vV zdL?f*=Nd<8FsxA72QQydUN)8a4J)(wDor7!O~J{=^{h*|qD%Rtnv@_`%RV zB=%wSr1+7f2MJbJN)o0;MwQ(ijnRsC^-sR9xGC(y{c7isqcKhowwZntz5QYB(wTO0 zb?&N{18>*Pz9@f6_OguY-fLTNjZsSv#a%{k@XtBuwr5Yuc4F}a^iJ!m!d}< zi}FpnK2~L_FZpQocyvp)c}T|X*0g|AnHPyWvz4tqE}r+gOsKCaSJDb|%ABQOi9P#V zVP3(l*6Q}uorNKUH1Qtbq>%?!Jcp{h7 z((4@n&yUC=q99%Y(f9K+3B9aQa|^Ifd^;U3_o7$9z$CEf5{Pnpn<5-SOueljKe)Ke zfLfpu)!&|V84049_lU)gu$R-IEZl@nM$v3rXwQgu?dRdp>n(!T!H1pKC z%*WUfsMzYHiiI&Zq$f^rJ}H43E{PsC7KPuKs;)LyLG0DOn`Y_DYb1U}A6q51$0J{H z(VZgf*RGvvPdz}E{3g6Ei+E|xvHbU& z-)TKBm5g1w^~x-_1pO1(Zyxc>p2!>^E1e~8czpIi3)%6;vr~7@SU3EtnQ-3v&KjZl zAC&VbvoK}P#<=C`%{1HgeHiK%{qfut?W3p0jS_u$YWm|`*M)2(J-uma$4MniHA=vKe69qs?g!W@A2f*&z%GJh8Z0%F4hl~ubR7~J?&_r)#=*u zhx_kcJx2L8!pCdg`(?V4TLPui?zd-WJy1i%qzM-_zjHWxw*!U!Rv=f+-!}%j&AJ;GbV_>nt?Ma^QkT?!uAco!G$2#jW^I?v_)ywYOX9pIIXNzA zLTOLM($$+$&DkSRZy%r*XN;=bTFX>BuulyCRim!H_E$}XM0=}Ez23tUOH==e-tYR> z$?rsgcSr@(e%P?2Val(B<~WUs-#S-nSg6#n5(+U=>^55N&6Z*56K+woDp9&;#MF}H z=v$|yPxBmh-D&RR;d#X&zEUw^yNe~hn)puJEOBwGgVVT0VG&NEIwEOkaYf3=$PxCG z(R=2+5&3E0tTHYtV)1d+GpN~HZTCpy_0=jR&xkcfgddly^k%eHS~G;{qjQCWMa(H< zlA4kZVTV1WPV*GYD=tW%ylbn?E7?Ga3)|MdQqCE_N^DH=iLZKX*v-TA#yEz}tdIDr zI!tOxiHYo31x4fO3$zzU#wi4yocO_5bg#ARJin1z(JLs*drfYQh>P^I9yu|&-hJFZ z(RZq*WK8^Q6j8O3L1hwyL=yDfDxV0879V_NB(AhTB3gX5zV7j8?1HDJZIQm=zOh*I zz=hMt{WKK9Z9ihpHzY+FRus8dH9<#4?&%7Cq%5_SG$>}N=bIyEzq|g}BDAVZGIDSg(JHrvDXb&D`yvW7aE`3Jin7ADW5VkdjYxEm{6FS09pdY^ow?VoQoF>BwsC~Mdp&O8!(SWYv~ z^T%ORYA)X8u-Oswdz5zy?~L9lN$+@jb6>jag{9TvA5}hzu04347X9>t=cv3x`4Pdp zf)fp1=d63JC22A9{qXWxfrBp( zim9gA7i5%Nc%3>sRnsok;pHXcRNYiU>c`Y<`@~BjuGge7l^x$Adma%m9#7g z@9Xd?F)WATK{>z8LbOwfJl#(I+PpSOq}c+~TbmR}r8?`vbC&(usG>mB%ur)CR8FE6 zQ^V84sG(yfg)a+lk|->kpFaPplV|Zu@f30U(p{0a7pPvI-rRZXHfV$PkK7-Ts>-XP z7ztIa&N|MsoqycW+0_#LxGZEs$D(n{_R3n*B1&i63@9@%^?&W(5YbR*;k(dk#wYW` zrXv@6TId`zT(Hpe`5wB#nwba8Hki5XGuU@%Mxw>>6xWoIDVz5<9yw>Jdr&lGMvB*> zy!^_5EAK-$rlb@xbm##)9X*V&n*3&{oDP# z-{!ub;&1s5_dTk4{d?WJyYDttB(8Xq=l(4DyGXT2<2I!oCrhrCB<#2n-7v{#xz5T7 zwvU$3gLgWaUf<_$mU?KZTIb2b_NsIAZ1q)cW1iVGhpDdAoP88D!GdMlN{4Qd?#j_rmWi#k0NR5^2*;PY*?mzvE~J>`czZyrP-Sw z|9H$;)6%$8LuhT*g^e#$8NZXu(%jPDN37b|G-<8T+KB4kITt-&8an#cWwn&HJa2hI zGW2@-xZ;aXV__c7tD#=VGilSS4)YsF%SVZh_O4s>(z8ZKE3VxVbyCRT_u-r)(~s;q z^6MY>e;yyzKbjUV8^1HYHNiFE!Lj+rE+)z)Mklr>c_ckOZgM;;SvmRO3DFblPrN(1 z^kms7@~N|@r<{&H-I?N@^6JduGo@!qXV0FKJ-7S(u=4@uKU`RGp)%DlHRqz*#p7wx zY0>GZ^nmonOHP-nFPmL1xkA2jF=IwXeCGJfs4StZjagr_-Lqfi*ymJTU3j%5cW!QG zo_b!&HHB+O^C#x-E|4tPUeHw-RM=AFTlA^et+=7YvE;>dyX%iitxL;qnBBN_)A;7~ zGD=zDE!|t!ZfoDZdWU=``>y8Qta}>wGVg2L&n(w0&#E9*tp!lKT z!<&yxAKiUy@wlpbN%hkwE1tZ1>iU%N%=6i|=j)$$yx3ABQWN!3>gB;&+1li~S#@cz zG+*V{8`j@@ZS(p?gGxW;2GCG7=Ng2bZC70(f4D=r|{2X zKgWMj`I6Bzzv!CewE2C;4Yt`?B`; z9UFd${W{z^t26hv+3%VzuP$iB(YpP62R|1UnL0r+wL!0@div8a`sQeig^!;X)e~bt zL4%Y`EA|OXD|2vYLqXI10%#Z;bE^MZ=t^%I#)S$_`1rD}10E>HdDTM3RE>SS=@wKk z8XB|I&T65(!JI`@x{sQ^C)H&w20CZs5ky1dh#+u6b@lLeL*vx(oX_Ua>NOZj0Nn=z zKS2^>WkcWSNyA}aG9t!`>PPMNtF@2;)b3K@;uh1~0z9dHhyroy|5cIrK8i#PW&VRA z37j|M|CW*%b86r+A3s-{bpbRQBo>Uhhqr+{)sOQ9$oIk#Si)e-g3w3Bki!Qq0xZ${ zc)E5Af`IM6PCSJXCHa@ejYjF{z)$|ecx&`gDo9J?gm}7zZ)k6AWV9G=W!-OyJ zz}jTN5?G2#c&t9uWK8K)PY)N0x0@#ojm6l|Xz zkNRp~H?QwDo3DXmED9z1*3EO{>Pb&Jj-XJIlTj$8Qg>if+H1cqK%vyY{U}X$@WtpB zu}|RE3E+6TyB9ssYmMZ5a7+frn>~G8sNus82Y}-Ya6I3O8t99X5c>g+p*o_?%r-NAV$Umt&ZS2QXK9N&Vj_w}Rs9v43_1spTLu^IRW zRUG;!3%@4{6%UTU8w(|)guy#Q-%Ei{BT;CSI!XgYLK&irQC27_iiYwiP;kkL&vO`!EWXj#5RtrlXx!E2X2X z>}d9C=|bQObb66hy0G%{bYUY0I|U_$sZn<5bSo=6h4lIMQ_<;U=o8uA9-S^>M0HJ9 zfes~%(CJv{0~WfX$jT1A8XXlyMW;(z**Sr4(9k(a=#wV&Nz-YnlfAwD)O6GwdwX`- zpzvX;>0(Oy>7w8t3i@Y|E^1(Hmo8>7=Q3#L22T3v(ll9c-EdWK4h@PNX5^ACWaR8* zsFp6w`3^Nl>5{1M3@5ZvloAzs8MtiJRH%OG=&9fxI3=bJpP@uG1ow)lrVBZt!TT62 zgyaA|DCyg$OF~DB!I305Qu{yl-UP6%>dG5`t0c>|Z0)wZNtWeZvMk&38b@9eJBzdL zn`1kPLt+QpAt7N2BrHwX3Mmkvlokqw7HXiSl+u>4wWZ5+Xou+-<043zd!km#*=;oABrzw+v)wc|2%& zQu(-{Y}`=lA2*h}-Sf~<4R7AwI4R*a;f4MWBHhy{H#6$J^Okm*qt{oirwfHdYpjP>Mng zpiw*k8D--#5d*;j4)X#XQOKde+8E#E{siJ8sk=7pmRyHldex_IljlZADtA z7YHlE$oj_}toLY{pyGyGu_oYd!i-jEMMFp&c{(2&(}mRDalWI^yH%N9UKO8cj(^;# zR@SB=bPF*MbU?#-M!DA=pq_VP@-(dtJf6hcK&+Xu*T8%HwJY|T<<>x_Qtzt?()BDl8wjmK_DX5Mdm}e3;R8 z3{_w}30){)_#|4>&<{ewbaMwl?@BK{<&PV{0b(?%A?ZD-Zr=G38ljgaZpZcy1gO9rFp|PSSsqK#SFpqlJ0UWqH!NIgn6_tvE1eKz;gT99pw(NJIY#7KJJKR4blV4TFLGxYlz)Z)~fPx zXDn+qJ+Q1b?2fXA*&SuAEytg_^6^@Qa}h_9xKjMd#!BeLzNnF#%S9uOxy^H$8XI61 z6Dlpvcjsi8(9{0Lm&Bof*$Rynl%{tZvLfB@s|>v! zdnj+LQPeh1(%QA-b!FCOzABU}*li{$jrSH6HcK_th2DIV;LR_xRyPZ3A|3+*?=gF7 z@%u~thx{yfL0Um#`8cn&s%u60A!n|zO^fFGp4>( z^U}a1l)&;voUBA1DAS6j8ayKQDulG!X^81^mejfP>WVWmitF;+btTU0V-K~(PG@l~ z+P`q}4ao$$E8~6WD^bjU}=m^ToU%iA>{##R{+sZe3QS^}JvOK_UccWl&o@dWIg} zrt^Bla3bjx)w0K`P_w}3OJ8L5h(B#x9383Nx^(2xOPZG6^3quQfs57`EX*j*tZH8u zY2VS|{m?aoJMY>rydux3X^p;WYv2FzjiX<=t~bM98`#cxMzQ@BiSU&QFJS`&jgE&+SC7z8d}8$M${saOY`V=ix7- zSoBFkZ^6%wMbgpOBreII*U1uir%oG%T(xNmzr&fY03mNB*2NTTz|_8F<0Y_9M?xZ4 z>L%TZVwy<(D*`(fYo_D@wur?kLyUn$evhmU5qfCH&n)FnTq)#C{3`la`N7wsEB<}r zNi-H?F?aH>;_oF3=i>r=dL*N$kmpKE3Ij!foGhCqEj2lb^YOkU>H%?Qj~{4S-BRgHa~S5AY#Sa8U-b0#i`%dK!v0+c%=~v<;boGgdEcYM**<&H zy~nfjvs04S1zU>J=N>; zQO1Dd6=+0~;?suB@fb~EY$TCK*FZ?|{A{)}nnHawiFpK&9h*2P7gQ=x`5H}unmig} ziWIgM5WoaJ6@82U_YZ&nXlv&Uuip5|E8Ro$3kv2Bb-%(-L`C_*_5+U$41V^C&R2aM zeRCQ%wPJk{xTTYCh@X<|Trn5sne z0A>?LU55n%Q%jUUg94}537`m?B1kIWWZ9Ny;B}x2t^oKTUPns=(O~3!${?1*3R01Z zRnwr((dILhBXc5FEow`=RX}oLDOhFoS&;>2D1g)PXm^O4r66<(%NWmjsc%Y?=;ARb zwCeHZ7gi(?XKidVgV)M}#Dj!uYfPfu<`6$M>@7AriWV$cSKBhwQ$FXWKYe!f@}?z? zq1?=ZWdGyuuDfw-Rn%P=sjtb}_2D(XMRs?Wx2C}2?cCAPaPj&kscCy(wl~{l?fFFG z;H|5p7E^Xf_M>uEX`QD9qClSUmHWU~%6TDTDlK;BW;lq;O9JDD#7nBmd0uvbp9r+r z0BK@~$XFDD;AF9ZjLpkLR&u_e37n+z%(W5&lYvnTp2ofuM$&LjFlXZ5Cn@^MBwTyV)U;Z3aX|93!E%r7l;uMQ9psEO#`KRUq^#OX9Pu6SUgdgkKjct zvQ!x7ma`&r-V2C09-w&ICltopOr?2r>IT@8pE%2C;LKHKUnpE_4q%X#0Tx#U(`@d} zr5nR5ZWyR-9{a?=ssq8lN8O8d1xx$t>(n`uXqI6+>7S1-Wv}Nd@zdnncJ9>xsUy_Y$;1+Y6_$`s_B|SX1 zW>wFoC7Tv>wahKZ&%_x=61fJxA(`e`HpsRkiPsydtb(9#EfZu>%r)|Q?C|t#^%gl< zM=Mw%_@9Z6(KO+bK*ZQk>2&Ib$|12uXbuXSKfN&I2aF*!d!c77j~2%njXQgJI!>ZS z`4SsyptY^%Ozon+;QVbs7iVuG&H$Kx-dJy`d~JQ>G1ELaaisCNkbbd4x(>_~Kf0$4 zS-3X9)3!{#@YMmS$b`HK!==TKEr|pr@V{#v3-U!7IU9`0b1u4VRYPsCe&Z#VU9z#h z?aHSw+54G`>((qT45WKP`HR=i+5HiIdqMN^jeUXAs;tIM?H&CsxzWD{+WpS;_~-O@ zNVY832B%9lyBgdJ53Z_6&MC;tNfC{i;f-DGhx+IE7i_JWzct6+S?8<_mYGX$*tGEA z>cFY53~ zr>5w^nq%h*9P32hMw>MHDg(wXiYl|U<$<9JLW%(Pr|{hTguGaCvECBF5fsarCa`k| zvDm~?V>wwSWG^5P${X<~6i5OZ4&xWgjwie+ASk+_9VG3mtH3f<;fvX8CZUT?Z$9$( zrdxVfT)o==_tmQ-dqVPeCSI!Vtlxg~s)` zqXAFoiA=MM2ssl=7P`e4e;$}O%_g>LY1`qf=^2nrJ;Di+vityLWDwIwM>r68yflGM zU|1w@$f6x_p_a)@wJ3$qh0d7l{D9u^G5VxMAC!0O?|inatij{1FU`y>t#^AG%3P9g zDvE;NPzgDh@dyOcdAm5b%Ns!e98ekMatf0tX!fgK3m6tjz27lak$=a$U z<2APAG*7r#^36minsFWGQv>ExF0g3B?)*kxbL;*tf9Le0CM(})b4Cx_y{T!%&ZxcQ1jT>(dR|1BGd+ivZ1RdxsI zZu_R1z=T=BwIl%7ncUaeI+V#}I&9{2!ZPDRbV7H_m^B&7I;4o)XcSGcHHdgCVHX00 zSUyTW+j^ClceZ7PW*4nOiA7>gF^7bQH_5Z-L2_p0t+CT?HabZZ2lkBp9Pwu0MwQ!Z zcsXMpoSC$x%S8pKOe3KbC9hpD> z$d^V(pS`B5>zZdr4;?&s=<3TZlPulWzj*0^7ms##AARw_r7vFJefp!HdGNu1f(^xW?GGGPR9>b4$sdSOaotXS` z8aT(J0Pq+_oai7;ZeK$6v|>b>rUR)QA`w`|>48q^MB^v}>jx`KIjzzb#0pjcp=In- z7xv19MP@5)xD=UY4Fs4+?#RfOZOtFwwc;3#tE2Z1tiCk(hef+9Vu#g5(3)B5aBiNr zrt_K?t{BC6wWcDvLHc-0W3;-uq;wS>R~IvG4W2AoKm!iQ97qoC;2>>CH___K<^m0& zCs~L6AY8^m^g~}32wy6v0En*~ z>D)yD(OC9uAc;&y0!FEpG>NSYPoPQFv(+NfVnQo4t%S;8sGy|T<$)}^W(F8OZ9!Og zb~q9_sQYDY5S@CGC8;~+4;SXjX|=~UEDX6tn>nqzY|&7mBxL7bwt2|=MN67#<+6#Z zP(vxCti|9_bGVlyrpEf>La)b_5tGFcN3NO!ky|c4yd}!wB&?THWpUaEuf(rzm1hQx z3)EtO%Gb7rbAma`S2j(aHsu7U>>riW9;jMJXF*yah2Iz*W=l!9qoQj?*}Qd|*3Bym z?>Ny{GqABIw>~-7=`0C%)s@dJv6jtSzj^(Bd16iBQ7FVvzp6|~n2q3AfbxZr)k(E`Q^}uz}{@x17Uz!4b7!L6DO5Hx|YOwdk)zNQH5YYHNrYQnavX)q8L z%e+nwO@Rd$NdVQpjaHrk6eP&=Iyx>ECIH&0&Pc<#z~ECJk$$XFs$BbgBIg&@m_e*_ zcx6AzK1JCa@h>Sn|8Ljavcs11$!aObafmlX-wYNz^PHBXWRsygd_(#j*9dc5uB};o zhRqTE^7zE}gW=?q1oBD#x7bL-D zoA^m^Lm;prC=}SB&dYPpN;e57DL9%TGm5+0x!3ZCIYuV=t12{yVr`5re}1|$?+kQW9?-+c}m!rRRW$|~5Pi0#s{^Y95&IxA=R+|f&#_YSS{FG40L16{IZ0;>; z68&8F-Cp)(@8-0ox4BIHckzaM<+e?G*!AauLz6wxI}Cr;FGJoW+V--4fYUz}U4_rm zWs^OVU4}oilGH?Y$&)&{QvPZb|2)?vUC%AVZ;Slz+^td{etvGQ^h@q;$;mAhpTYeY zH;27ThQQ=v?g)6;nBbaxS?b}g!~JpHaqbAc$8U~w5qCta#BV28D(bi*yc?FvIFoP% zXrPSKQ#okCPq?4(P5kRZyYQH36#rf7lEd=fbwAQSWcX3i)}$X9uTJ(R??}l_c_cMx z3Yku)J(0d6{cq+@^Cjlj%)ey4$>XjDo;G8}6}WuP&()*Ut8~A?6Jafldj|82m!NFK z+meo`_YjySU8dd(xF1vRMQ(8tK0>hk5@$)WsrNFs#PFheuj4F+C)9gAx5cnby*F?{ zL%w>S#N`?!_1-8yEi6>;lewUP-99Tnh3n^^R_{~!BV4t5Z^9kN?SRB<47%$LTm}9c z<@%tfK8WWr+z0R*h{ zdlE_tpzdLAH`+%n*oRWa0O{tIp|nx_MxdEb<+{=OVbnc_yTzz?H{QB2mJ4w|hLn7i zO|2S4c>~BtumrW2wU^4FUhH5{%egM(bOR%MSl-04r z-0)ul=&9rO-k9k}3urXAqkg3=6;trPc?SL~&btl`k8ad6ir)3&H;TUsCW)@L;SJFN z;cOdH2+wYIw;QRu7@bUQDdB&R;Vh2%y%;$fI~os--ZUy(jZz8Iy`Td>D37R18O5pP z66|}^Um|U|S)EF6h-#LDF0^*!$6BdSIQ4%AsFCQYi_zN{T1C`Ncp+MIqwmyG!oyzl zT(-caY^$Ac*pZP{uC2?PF;}7-Py$_0hbg*`UJ-ek70|R6ue)8cT~n!JQKF2(&%15 z5{-|rItW8l8uf`dQJjkqEb(8;xsBDo8>J@B2pVgm)gA1*o3)MbrSZ@KR{wVPOf*A% zZ9$3gI%qB^oR0cIchnXQo1+YV0DO41xw;GW4YRb}DCHu+QtJlLi$RRCLXGj7lo_qn zO+1z6n8I6W+z9V(1{dc<@%gRIWNIDNpwJi1dZJWXXEf^V#~Y<3L%5?_2zNAxhEa=x z8^RHd*$DoNw^Odea$VoNP+7#y)V`w#TCTjUG>WTL@aqK8HKDzNf69?Re z(rA>3LTF|xr4TkoP%rh5dQ4PJ^(0cqC{n3S3Y_w^7rh!|{i2*S%ZFp5L9L)%y`V}e zi^e#SR;Z^6SD;x->j2Gzz{&iqf!oe!Bu{twK?Lt`&VJ z4mSJh8pQsl5g1v``l-yZA?OGva%dV2W&I}pL)1cZNUOmet6@405?7At`xfG|GfSYi z3WZn3O4V}xv-VT}_w0;t{D$P9KzJ64YMi`ZwqaMDp{ zXCvH}ZosgAW0x*j2yAnw1YLLZ0Dp`ADgF^W!U_~;R)N$~k&4f5^vrRS*K_x=n`wW( zXn?XqpBsiy?Jzv^?isgrz$mDA3ykhot{IP6?~DuH_9v5!qEPl^aytDrJMeey6H>9R zV_7@iNkSPni!t(F;~FJ~=WOINR9wI#FVoxOF_ z3SfY6(@59qTA%`v-)dkv&ECWLWlgxw9YR31P`KXcu7O`MdVtXjOQ6J>u!0NnQe2Iw z(G-A%y~ilUT9tUOHsIV_H(QHmzC-I~zC5RQvr)nSp4QFQtN)?aRaH|^0M(mZeN}>2 zyARGkfZ~uk?jL|WNx(6H=2zo=`v%ZldV)u3t^mVTa9yDJ1_;s9nSBGK*RCe{5%~s? z$TxuS-_8ec{|mfJ^bLUTI6CGV;MQG-FNF;09gbVv&wK-X^bLr=)@(q2#W%p`^?$@O zGz1ji0OsfO7UB76tPVl)4Pg9z$`Hq`C0qWxm~Vg%{eN@Zx+8d2d;?U@*@0)YA$ceH z2Ke41m+j)XZKz-M4X_U<7H%8Kx)OW?Y`X=|NFY=G&hoD(lgl|zD+**D^#Ib6{!tT~cUAVHMyp%M-$r}J0GqNrT((YGJY6kSx z*pQ?rOA9C_(1&c&5i#e%PlJpH(l1GonO+I0SUb20U3(5^>aXP<@6b7^#(OY7w)wMwX#o5o>^*8W8D-!OBUxBw6=fWgrVo zP`t5Xs5{KOgsBuv)6>_JO?ZOA9#rU~KXx>jZjhf;Gg4xRdgG241XuBl!<8qYqqDtL5yc4_X4Yt{#Y>#td{>e>y# z;D&2gwQgv1xf(aLwydwu%&cF}?=xH9J(8NvFI#bhG9Fp6>N?7J-Ky4&4K7#1#@3c~ zlyM!fd~Ni{upLQ*Mu9#e*^GR08E>;V$*2alH35-X(6C3C)$*R99XiRB+_PY?B{#Qa za6wP9$vC)M*!x;^_ZO1W4JL~|IQq+9|L(x0zyH-Q$13#}Q=0Xu=q}XK9sM!?l2%KS zm1?OLiV9(+GndbW1*%EV7m>M6xHfFzOLq?%r&c2Ab_}5w{`gbYG*nVK_RC-W{?Y@# z`}HqJgQ&!ip8N&=Hq^2y`d5Al_a|uaZ;t4)GF8tQM3Q$b zp824&B+ud~s>=2EZeCZIlaiilO7;aCJQfd_G0*iw{b-qRKjx1wqJ!cf2d^Hg_YG3_ zr!1Ik)F93yk|rk%`TO}lM=iqrcTnP*$-nYT(RVAiJi#jn^&PrDTEAhlOiK9F?}WF| z7KT#InLT}=w#5EYH`iD_0hcR~Z-oLJt{&?U9&9!|Wclf(AE)mo=t3`)A7&g2ejPOa zG@D-sumq796~qTnQDRzH)W%u;IzSr@BjiEu1O_3}IB7*tNtyzVO<>A_JdC|8OzV}m zOrOfq!lgHSb@$MhZ&tNm-Lld!Y zjHhaTPH1X5dr<_b(?dHDWyMR48HHi=!92U)R~bC%w-Vx&M$v^hCmzq%_NU` zK5>ATICHVulKCB2YE3g(jKW$KRn`g^G6=iY-!xgS8us~dHY36 z>&(8#4)@(V+*sfLp(XAlvqeghbGjnsm5aAjG;HZCzKSnw-B8!Op()p0-xJ7j@qGH$ zJGPPc1B|5@#U3d@erf{#lA_uC)X31eEH8uB_51QuL!(!JrXqA8DA@R8)SwrtI=z{u zIoo<(uxHVreGfl1G(bA$spi#SeYClC&*nX!9&223?AhIO$NE=!!j@cX)%@PJ1^ZV9 zih3^T36C}J8516o7Zg@Tug_>5yLaQr(}z1VOT)PfU3rCh!L^qyYTLE2)ME1p_tLC^ z6i{jcrY)S}ug1c`*T^~et0DCLpYT@$bwv+zSkshdnD}gJpy*0rU22wj!e-8rPb|qV zPdl~T<&*BsEVX8tF9l~i1YUco_#?*I?wrQi3eYAOW&}7mX@N3Z!}yfd^h-0?7cDR_ zjBX-#CcQ(2^U)WtY3YhphbIvfCDR1diqKXlnt{_Z}U z|0=u#epk#jkv4gKZH2$cm+z*t1Jk)BPFF=6ej8W?bOC`DbP78&XrMxyTv7H%^TF99 zSU><}vTTvrc9PIgd1g?^cggM&_=^GBX%8D|I42mHc&j%COLeP0o2;q{m3kJy1_+M8 z6b?0uC$Rjy1#7oA^<1~L&fl?YUX^4ykmB#?>G0<_^!VqjZt|sMnm#fev2tckb+I$B zV*i4LL(Auc!=4ilCYQF<*LSRGD(kFtqVg38nNJ^S1H6=Mo z2i?_}rE89bEX?2w1w?`F3FJ5-IS)u89}Pr$gi|dOOd_h|IVqEB@A`XWDppIPOh|(E zEehl%+KIsGjT5i}(S>Xo0ts1ZKrq;_Wq?e5RshwNj)&|{L=V&3<*Rs)SP0u}z1(%X z%Wb%J;__?t`I)y1b6$$xDmeecVNbRjT{eDQ^g&CueB$&$VP1G?NeA?XMeZ?hj{ATU z8|c00$B?>c*)9X>|z-YW7;%bqB)JOwrkgdaVKQL#iNO?6NmJ~5D+BATf1 zqC)#a(y}LXm8vj6KK$D;dW%EHA+T?RjZW2BGb;vI@oK0#GR?tct%~{3(H2Y|Zxj=C zpLXMUjQ_@wuO4jlv<^uD&MzO+C3H9ow2-=cz#ek}S;o?EuRr|{1EqW>+QsNQmH zb z)64Mv6o}crR$GBHtUl0~$2WemISOGXLAVHl6foYz<=Bxf&gIC=fN&Q&3#>pMdq6{E zXrMxZzk!|_&kYC`Dl~yLU@Aj%x<M2ZC$a}m}<>-XIp!2ef8>VU;XgHG>orjKm1yG(zSAGSN+Oijbg5{TmE>p}7F&s!Re z%B;I;MYG?7rkvZZI_@ovZKufx6uhNfzwMdm>3b)BFJ#=yOV4ck+WaHWjz&MtuN-~$ z$b8{jACJEC>~{IY_Af`@`S_9V-m>u2#~0rGUHVS90XwY&k{(~<>iJN_QC34n8n@G{Mn#CAYV_a zsUP{fP@FyG3gUqtms_?KFI=&?p>g{{f9q|3{>(sM%i5L-rzOkaUh(`TFbobvLluiV z=H?#!%&tmTc~iP;Q$c-^&C@#2(KNiOR_eLrQcsD;YN}tlq^|#_l@q_QdPDB-NqM36 z(&7f6nfMFwW)CPe8J-y|#9_H)7~`m3@M8SMr;;2wwF7D6kW1ny<^>PS4LOa21t1yq z5!$^-L(%vlw?e9P2R8>wR#@i2`nUWHxg;PH>&S)5k2x9h69xwdMd13wJF;~fTFPuL8!V9AGf^fscn0#X5 zD&a~1cTc`4eoc}A>F43Iu+WFKtk~x-^k=)sXJL{a=A;Ge+)X}Gt8q}HJrdbmowv`z z^MzGCjnRmQrozG$>|A^no*NKbhrL*bflJVE z737&)iW>{9^FH*-;hj%kx9IRkjx=vyP(pL%Rs1;)suQ`TF?p6^QE!wWyCo1s6@UEs=apIcJSe6CxB0O9Gv#~SdAZr-TTY16 zH@rMRCY0d61G@z@fxK*}Hh; z)KTL8y31U+#CZ0eRNotZJH_cYxvcV+8 zD5-Q&1#&)OvsL^aVb|$bpTGZpWdyNO=&r)8mwPUf;)Vwnhn3DYv2#r}CM%5}*>1t* z4DpTRJP4bpLE5o~Ovk6?K{nWR@;ur`x!Ad8MlRqSV@O4++389nSAnc_SkMG=bfTis zrs1Q7gdN<8Wa)K$+!X6aHge>81B0k5_vHT*km^v9VY%asoAcZ9}$G8 zJ=34<&x{&H@sXQd*{S?r1YJf=R(6$3yx3`cce|8h4`!Y|zI4wZIu5fWWN6|r3A$*mFHQQC{ETsC(b`?HnR21+QS7y2hDc>Vooq1`e zUl4>x`sEX;wo_ksRXWALzq>u%D%EBNZKp+|4uQk`mafFD36{Ogn{KA_eR)1*>n?DH z(+q|Z3lCgjkU)Zsq_Y1-|IWwrDb^;t#`jc?=nDIKc{^XVi9EG$!Rr{XV>^X z2@ZhR*_C`cpbKoh#5|*U89U?0_DO1HI;hb(2||(>7>!)QNk5=u#aog2e2oDx-%)hj zM_t&H(IJqd^M18jHpDMrd&*Hip`Ka6GzYqv0UE~ipbf}VKp) zK#KxNq*TBu{tey(<}A`#&A$P2C#kx)Q~hJj^lu>EkYr0Y`#X9&TKe1a8+#94b+ETF za`4HKW4~EiXKw@BUw2Rna?_PIlkmib zTe$U5Gct*3EF%MpZ6kTCI-tE8>56FO^U(_V#Qmp?(%EX7No0afv`s65F;w&c+Zz#<^_WUj z#H_hgX6hqp5ICv!wV7^n1>whQZ|JQ$*>l_Xj~w~_@t%`ay*J*~wCnbD;`Y-gF8lu7 zYu4QT{mXEF*Sgzx&7rx0;0N+N^wz@dgC78RVgb^$wZdv(D=3<*2*a>7(s~(B5+JHz zD~8rba|}vJD#J2i$2)RAhYBIs5YRzEC{vx_S=kbpuuAe?!`+bj@gFfclauTw{x-<| z?wNS{v+@a-?R0AXlCrWT`QlsVoOidQI1@AzeuwrKbGJoOii>EkXGR}lW99TZ4D=Zg z-VE5fM`Qy>URpn<>EfN^HKgQ(ppx4uJc;1npKQ_YU*8 z17Ay)^l4r&a!lAAV}Q=;0>d*c6E+YD9xYV=7sL|1i5b-yGQ;_Wg5Xj$E2aSkiSwSt z{ROtplo?ANbBu&-2bLNI3XqzR3bUN1B<2q-PO5*L={_@f`eF??g5^6eT70zOiJgT; zQ|kjeu`rj3Z%-T;y`sBS_|MbHzTI7GYx{3nC0vX0F;AplgU)Q+l@WstUo#SX+SyZ3 z9ib029y`cr6qcB%xTs(|3#I$k1V|;3sLRRT5_Kt4McG$t^M!fon?7fR*G^8n^@uAs znV)aVN=}Awd|pys=4XV4iI;^2akI-h@jY*IZeDY~;7>;=xC;_C%wCYs2jflse@en8 zaCc6=DLLem*!}zX%@IciR5;o9Kd`8VC^ZQUZDocKi7+SbD-uh?_)#-$6} zHx!EdmUKlOt>IU`)OXW*+Q^VB>q^M7N_in-DlW{;p5iB;#<8lDCqMa$cVBJqN}{Z( zzPU76&=f!U=Lwo1y{bGjXnflnt5fxpe@-xGlU+^O_s0F?EBst_=OuO+($mts;YD@b zBa4bk7w&FvSy5MDaVCdaUmn_g|Nf4-mp(DN^MScyOL9tPZe~sYO=~vX+*<`T1ar&M z1)bMCf7!*)9fP2oxa53b|0Q)kHPU?I)%j$HJ2iY4bMOxKEs-WizzUI0mJ7!n^4UcW z>SKg+76+J3g(l!6}f~@<2U^&KhTPjZd?rVs<#pf1Kj6*PH1Vzu~M9 zm@DVz6o1MnVYeD{iqAZ5i|Y%G=`9cKTFs`*C$?`qQvF194kk?hDBjoiqQJ$$jxzUN|m4#^v%p_SHx6 zsO+*^=v>9586i+*89ruW_XHw_fQ=-hB*tJzZaU;)GY3zN32Mpo@xCMuLg`?V_5YFL!(f<%Prpk6(*Vfh7Z4BDh+6)=tH7y&jI(;AZrJ?9;;?E=}KfN&E z@gIsqaDL^TIS#>@%7GI2KOBc3jfe2n1T8tJvHU|}2u3S-Yw2iy{lKy1^X9_w`<4S& z9@x@=4=}^S4-M6BUS3v}?g_dVtgPR5BY#Wj{7pM{Ro2h*&fncVf25~0`eJx_UG~Mh zF1k3UZkeRZ$!_%|rME2UzI0WBebTo<-q3p^6uW61%r9EwmL^epftVo z*v9TlR|ZbKP#DNek#&Zw#o_$MvP@U7Ral%GUf|z2G_=vbAWSjKZpESNr}9Z?A-&B` zn6t$o@Yt}Iq|a=$*Tfp7&hV)L2xwW$(=tM?gIx@*XaoYr5c}prt5~eOST>e}m<8n* zVzanZD-Y8hDUh!ul#4eB!3Utagv=0Yl8j%dfwY3nae{zcKxqlykjqzPw#R1dEa3`n zeWK;w?aQxRS^mV}uAUDyV5|3;j^(ujH?5jDC|omo<-(Q;xFi?glaAvL$xmXQI=Sab zVm2*a0qyV-;uV-@#48|9n2;fLMg~IadjvEfg#P0J4cJ#I2-U2bL`u~!VX4WDa5Kam) zNlBu_q|0Exk~uM;0V4u6paHR<8M&u~KS<0?==7>(gAJe(?o81S2y1G=_;4^K_`wty zcGw6iWyUk&tC6a4M%B=&jX$*Pu{sk)7sN$W;VyapteFMD?vC9HJ>e{aU`jJsQWv+* zg6~t$%^6(mHyXF3>iMpvQe+m~^W2@7$?sq$=kn%+wfcQVKOn+8=jaE7%yW-^ph!jA*WZGoln1{JdvLcG$aOUr?3Te;s1vVjY!h(R!mCi@fax*^> zJ!Z->TXItQ8}4)DnW9f3azf}y`Q+)3CY$-y>9**o*=0=0vqe+P7XD-Q)Mz$Pjut(L zKWlI+a_1B|f$%#casuHo4ZQ+UK{Sp~3mknsKc~nEYo3r#zB?E7Gmb9*g`GOHA{05H zltWb3d{4H^34OpMeL~~}Pf0TTvOec!0AJ7gaGs;_>lD?!ZhGpk648Rzn*~cLs%hZ z8v$XXo>V7j1=3T^Jicb22#Tnu?9^D81?J85EMXRIg?ur!?%0OyS7zHgR`rIKT)sN+ z#E!o5o+j@TTQ{{{Tp_;g+tIORq_=iSbw<_Jn>Wx3vF~7B)A}a5JFtJ=oQYH#QMS%v zRGi#fnj{zcEG8O{m_Oqjhpeo#itP(%9N1<{Bc%7*Sa`Hdlz6tqIF@m?MRSS@M65*Y zcoi(hSMM3CEHWpovY3D>#Cxr>6pjJdo)V6Muxo0)|DyO(3v>>3t(&&gva`Ho0`{yJ z<9H+nuicvviGfy@Ge%jk@G%6QF%L9W3CT1yKj=sdN+>y@eE7-B+uAOFa(MX3E85$y zcyjpmJm9Kw}1JWxR)paTG`zNbJKGm+3%S30_h^1p?oH6k0~T z>?;KsSe-)zh8SI|l0@@VIU><`TFXPbnQUaw{o6KOQ^lK^Xk`A4Bu9kbl7+tgJzLri zlX&FDrOoxxi1eK)l0?uyLXE$qj`StdMtZtzc&aQ*k+m{muoCGJT!oJ37W(`H-`F%} z6u05rpzH}yY@{Jw5;eIQ32DKSV$$6y^=Xi?kxqm>8w}QWQdkg8N~Bjd(o<6rMyr-{NkBR#&;HLl#LXu)OHf_`GOfF|PaLFGwHe<>)37cud!>dtvR2Bh_1W-n4P&XPQb44vVF@e(9X*#nqYq?#+FhyZvNa-v6-%ak0aZ1&0JRc}3NQ zIiBLC)pI)ctqygB+fz*lTAdYW$}g=g%5j%8uWxC%XlZb6En&JGu`iyHn>i2PGb8qe zhxaf^I>`cA9E&{Y&X6n+u`j@U&n1op(JG5$F$*Z2;Ah6MfMu~pu;&NJ0$?bI5EcdF zy=sJ#1yS;}C>Yp@CSh}%2+UK=OgJil&WsNBG*IkM@>kSqY zNH5EFEZX;RFv+xuv4Z(t@B9MchIISsWKhA2(lKGBX2S&T|GwjKto(y1%f9ot$>WwE zjz-f`-*noEH$d_w|3&;eY|lO)NePtayYq6U>hTmg6ZCi}%HmW#p2Xy-dOTkPTd>cP z3{4AV24`xCXa<~6V3ktzfXbkb<)JiuR3R}Zw3e{iW79lc(TC20Ow%VZ(g`$u5+6Y_ zMPh&_qec<>zor`;+4A!SlWedhzb0o|7uj6$zb2ava(dFsa<=u_=+ig4jK44-`m53K ztK{5k)iG(y&u=RbZb`G*(kAwJ+dZE7dCCao3!imXIGsV~#Ik%e6e;k|la#P1YH-RVUHn*FC}GVANgW* z(_K!Nj!#QUl}QIougfvt6#X~E*1T1G#%Y?k+EMOwmOF*Z)7gCK1TI&iM`_U8Gm_;m zsaeKG7?E&E6%u+-w40{ZvkiNKc66;Y!XyH9I9&x29dEzHR$%LGmA{0&hTzEr#*y=S+6dvnN^`;9yr>H|r!i83gh&lx8 zWn4*0pwT50X0i6dI$6_9Pa`Q7veHRSu>?7rFpCT&u*rtVS&=YPd!-KxP$!3#^!kW_ ztO(F;twt->RE!oXAT4j$HYl@zR5i^?5)y=JY5jfFGjop|dKWPC@q$|?{+#cWe+>8rA*7npIWMg`6hRN#GXUV?~ZV9gcWJkW7qB9w-{>pH!yS*?uIfGUlGUxuL{8j80 zcSme!sfQy=9t7jfU>dox-J;)|P9KbM;7%(O261>QwR75FNOolj_=Se5`pImmo@ z%Ex0UM5!Q}O!8bo)L?)wPpgHBlck#3DdvbJw&6=E%_V~wz{wJa<)UVKW8}HuJY&34fmxkMpSDnrix8OrG z>c`J@UzPjipPV5!)ismt(c27P)WiJ|_7`AH>>uFN*i^z~`(&Hpi>xFykzE!_MX>Y( zG3pAq`NA6RTKu~CPjQ=sr?`Gx*GSiMP5A9ne?$B`+#xZW%a@mMM%lzYCa>ex3EN<< z^-JzC@o(G)=_vP@vfY`+wJ?j@1*bB zz90I2`qA;hhtBB+ZL?;Vbtgfy2$|`VLtgc&hzaa`n>eN_W_keRz+%6~;Bpp}p z1}| z$0%;g%zqzv46k~G*c#rt(}?&uorAl^21eW!ox6I+2HFSuhWiJ!m^oGT!FY_E{r9~7 z-5+y=wF+JGTfBe!r4|ZG)B7;5;)zQF&aJmjYE&Gdh_PHTK>5AcMsq5=Ra3ve&dG+KK7r_y!H9O_g$|)bL{Ym z$JhPpi^o5-;X5B$_}ZU$KK5^K9e8lW`@NcPfB&v;Z|Ht^aP-MbzHn{$&VPCRC*Sz# zPrfi@>ji9prHAN}F-KYZcao7N77|9I+(xBlY`f5{8K z`MbGqRXm&f$J!@9^7_aA``aI0KKxeAb^m?)U%vJfNtqJ=eXVc%EtgFGiqymYY5(qN z`pXqu`D+=M%@&cZIv5|#cto~E9W84YE-srEQK@}k6mix1dxyp-=n{gYO^M<*HM6mz zt*d?crK4j5ySs+A4ZD%GXQY2%gkriCcl8epjSY@nT2g^vO@pIjBbU01Tl$B$4wN7| z+nznU26iLe4f>%%Rt(SUYG2g52f^Kl@|IP!uXa}kgTV@F1T|@7aL?HA2$Cu4)UsH7 zH`W5mLowb$N{}}OQ?c5;zAD5*ylr$NEZO?ny6{Ff5V5{07w0?w}rzS z5z!5esI3X3%G!-cqO3@&tajIjf_O%w0J=V0S&18D4Wm^xRfxe>k5pW#;L2cSJyPr4 z>y68LKmekcp?>Ao(cyr;C98ia2Htg$*+ zg_vystVN3{0obSw;~E4Y?yJM-XJvJm;R$zy78HcLFxrf`X}AOEdSGy)+ZaMs)UJ*0 z5MiEbR)6${p$)waG2F6#6Y`bvP$>Gu1_418YH)8vAi9kRH@2}t3kvA2&?w43e|qe{ zc(^~1L9k-Q@XDb<;#2N=G#>O~OrVT}5N6et@p`Jfc`4(#5^I5t49WXZxDY zE^Xem?&|HksN(&`F=K_Rd|HiTRv!)pV`0qbA43&q@@t$L1}@^L%(! zI7Cs*{_Ux&-#}4cNBWjM!=q!9_mGDhAIraIWMI$74IhET&WHRgiW#k$^vh=bS$@?Zh zI(f(B?UTnReJnQ$ocWK}&3rfg4VpCVA0(8C|J1c#eFZV*EdQ|cKu_2|1gyZI7?Wqo z^+CR(QJnqXKMmXQ>iG!wTRuX6x!=lyDvm7^LZ~s zExQo4Oms``tS7}n$+fn%)$1NNw7HLZ=i$FzZ|9bAxo!N=)-CRFuFQS(XfFZ;w{7Y7 zj!SL5{Y%#1p*IWnTh@+?K4k0lB5<%&=(P@eZZ3sKA5?xu0s+j_L_Le#SVH=~wek0do> zCG>K&h!sDVdpF{k+pNSbqo`&1?wl+$B6zb1SSEaspF>8Vq>uz1E}pcQq1i+lARJt@ zak7D&{ufgCCv3+MWd+X33|xy_-T(Z9*Y!Y9UZvfz@9ubOC*JKi8s?5MO2X zQr;u#nO=`wkT=#WYMm#E86#O$%b3|CmNmm!2Fzwu%S9Wg8C<+?S*fe2qC8)h z^?irIT3A_@<0^2M=4DyRY|R)T?yeyFE)}Gj^)27_(OSBv;8@ z9ZBbzZ+@FKJ(a8EE1AYMq1f+-UTiYP2FeVu6oT?D*=PY6wzn)c1oUudT$tV(v>&Qx z=BJEMofVn38S^OMgRZl4{rTmEMMc$CzGOYILSNkiP!9$K;c9_uRd4$@K?E z8>2r-x7PYU*Pqjx#Xl6@x_NWW>Wzqul;tlLgq+=<*agia{Kv^Jf|66Qe?KuJmIL7= z#|oT)b`>jwSzep-n;8qN00kDtDbzqxRG)0`cJm@A|Wt|MPX z6u)lOw3sQ>U(#XYG2$3C_<>MHAMIn&pdud70wy1uxj0B*lu4b12m}wfKu3*6*CxO% zeSSe91$!dD|B}NZtD!rf8_yib=p4IWj{f11N20&~+V0(7<1-$4gm=EYJNjVV;GMl& zPYl-84W8KAd*@)C@WXqfZ+v59l_ zN2y=ci1?(Fa?lb#cjrv+)37!xP`yu6FX4Tfsh3h;&fWWTq;V?PnVd(@?hhn^?!BH| zXk8L_fR?z(+@is1JLU$udi$pjcIeWx>=Tcq9U2HPo>P_Wv#tvc@7-Io`>QuEpLfld zFJIfA&L6gxbxJvr1CQ_Vmb;8s?{&FdS;Ms*MQQVH`0mji&)l%=wSmpP&f0unXB$qc zKaqcqL2`1J&0_CPI7u*Px6UwUKaC8t+NxVgcP|1m05O9#BkBUE2c*Dxaf1ty23<7u zMQAcjkJQIM9essgms{OYRM=XTlT+1NSkzISE2W-#OG@Rl5tuJ02Z8zuTSM8|A+Rxl z+aLXcv`X@DnOr%a5piVUoQ|kwUKqStchZtTNFrX93fDV#% zNe)rtRGTM(ITvLS%W+09mBu4aY$$XC|>=W>b+ z&fJck_2H#Q`|Dfw-ru)$$p2z~ZAG!oyUbrUza}@MtO;k`RW287-HROauYc+Cy)WOo zEKn33kuFco@MT2j7v<$I*uQGoo(|@i5#JQVVvG)4E;1`9cs{gS$@igZ+e4$`Ni{%& znP$^jte~oq(U*{sp`4VWF?7VA;Kf2Qe;`2*I-$PGK3q5|$OInE}SOHSYnJV8EO!D7I5dL=@=x>CO9}cIMfWC3F2vE9R9I zOBptEz%`(lmq#Mi$da+pI zrnr|Bm{z%JluS4)n3*r;VG;x?imHc6TIT%mylmSAB*Dfxz9i6!KrnP6i*FDuC#h{9 zU(c9&SnDuE3U;-XWD1z(cin7LY(JpVms+)2uJl4jYx2zIwCC&qVXK6lgWg$Ie3wEU#RnkMIzFUoGlj1*8 z(|^{K?ai?yRo|HOknwIdC3Chy^Vr5rF+C8TivBh_1Vs1^x0v&iliilv4duCilT!1X z(Te(A;qb0{{$HKoBg7p!-8#v{RdBaQQY!pYtT3pZ&f+s#VJt?nJuz9cqCiKU7HQBj zwNz9z!_I=z*g{BYY#E(tXMyf9f9Z*K71R34GoyjHoy9wzpu8i+W-#TYU9Ah`9`#h{ zE;Hq%8l0&^az*Z+qF*^}%QhT0TJ(Bz^6hC=Z%C=R8PSTG{>sX}F#oDE4=4)M^jC%Y zYWaW7$UXH|Mz$b(+w;90-iZk`6YgxIpA^4>)xLvY7D0T+mbroQk|IxDw##mXg+&M7 z!QxC17jJWd$%KQ(B(VK9coIN}M-dwZF>dWes{xk~M9G%N8?Z0b6DjNU4&?;WfTAMj zSd;=z1^D9Di8hIOS)}3YoLUZlrY6CGJZ20Jhk__;Mrnqu$ddCd2(A@iM#}c)dOf%( zcpMdse$s`GG_-${L(Jg`^v7$Jz_aA`lc3Q}4<2!@1{b-W zYn7kp1YHCg!4a-nXyCRva@qBkX(081!iZ z_zeOg0KJG2Xunk8Yf2{||5>^s#rU3cK__=6{!1_-=Zl$sd061)N% z?WGwyq+(_iIjL4RFg6Uh0i=wfbjqbb^x^#w%Ah*?SlSTAnDP_8Y2K2Cx>7S~fzgwj zwQiWzOPHb289+U5?qa;798_aIt|P21qbN;jE7eYY-N(j)MrAL9j*rq-)Y;GaLZ$3y zwQWT%s&yaIG(F&c)I;S`Z)x1(JyqJg9qB`?p9=1JS-S{(XRe#dB0i;122uL~+!G&j zb1PKp>0>pH;w|Cpf==!Qo!kpLxo78t({)hai*L@h3Vbj+x$)i1DmLe7PA6(`2C)}v z#N1!axB&5^5%82UE|EvO0YR$~tx?3CMi}Rv-seONon7xX-lq4~xpgP($NpJ+s{eZ| zmax;6s>LI-YTrJuXx|#&hxV!ro@HD}Wsiz~;i z9vo^J8XeSLKx=nobgXSh?})o9WSpT!$u!@VO;@8^*sFqssw!hDmK7^T_70GGrJ_Tp zlvS~MuzzgFC{qH2q9Z9gzQ3O_1_(vR*!_7HR!fSH3XD;^Ij3tKbV1KnX}opk*`gX! z<4k}FK`#`~XJ}n*9m`x@2{lX&h|mE=(z?WVTAF%&|E-%=kXq>(S~q*#CuAoTztNlY38w?nVqUEJOf3WjQe^-z!v2CHl8ODdN1 zZXXzR7gv^4tQ>^`e(~tw?%|=nk>P#YhKI*W63Zhc*Qr{dq00LDxZ)?NSa%H#j=3wA zj12cJ9~g6Q8yxB%85kYjJJL7c-U{B4HNA@K{=+KDhD{8tBRm)e60EMRPVmW8Dv>^1ZuyNBk?>mMb|~ zzEuMwql3dkP?-({gOv#h#K7F>9kr%nHIP04l(8rDT4_Hi43F;V?Hd^B9ojxXjc$Sl zda&8u)QNx1siavyJr97vLKv2|ZtDZLO*H}tI=2Lii}F~bJl3d>b;@I%`dF_#)~kz13>H)nO$ytfng6uU5NXt#lt3rJ`0PbF2EO zV53^aMzw+sT$IcTHmX%@)F{}%g{9UgZN^1;RN7plwi$i~X^e1DQk6E>sBNxM+Kh{m zs-Uh$MO}^3W?WcmSiu!8%A-kTXQ;-aJ~^@i1Y!%DrlD5(nS z!Yb;*N;7a#Qk4M>s{>OXN2R~D zYJY2${^FvfD*dfh`&+B@7Z)W}>2Iyt-&&==xG1Sge{0qL*8YF(TZ>Z@=N7*mJ95QR zrh~ndhoHqr)vK@}kX<2ARG_wET9i`cRUm`{A~cbb1W2y8GFTO&Qr;o>glY__fbs}| z`aqFagn*>HL!>rJz>;7{2+7@K7j3Jz_aC^~nVkK;v){?@ch2|iIg^=#@P!4UMfl=S zzBq(0ED$Y%8HZv9jhHbmJ}6(%h#7vtq98#dW{eAft_4k)0cc5U#0+auZ-7S3@LCik zXv7Q;QEz}o%J*@^N6jhHbmOD7aGVTRi$5X_)4Mz9uT1e#(5EbUm(7^B}| zHpK|Qp&zNm8`lrQRb2<5wE`Hy@dl<$&dQ+$D?&ESLV$)zaxAp02> zrp@4sXkmd25s<#9H++$e1PerqY$RV4l`nD@U}4hwA?FAdrVOz3nzt~=zVhDpL(Uj1 zkd+7~KNOQ6Viy*O7TK>$ndPNj%%AMSaYEx`a=9srFMpu z`pZZCc9{;S^OmVpFr{5%CXGK7`=X#oNrnpscpds>VZMI7 z?;&C!T5p(!1V0P&*Y>L6Ue+?Nsf}D9H;kLx%i3rw=6_X3!0(#hUf0UFdl%f}7L9{k zV?h^?gpDF$iA4At0|3#kP!t9r0WKt?7u|^f1ja;TiLP!@vF=c`yGs-f2gQIfSP&#e z6G?EZlBo&Kh(BNC%1NX(jNw)$TXbvIjQqPJ} zzucd1%@+(G52e^0>QH=9I9HE1+*_?=&y|2fRhmY-0qy;b?1(ws-_sLz02t%FBe!xae(0fWQQMbO))Gq&OT zUCB=dRke1#VrQwp+-CY&vHx$^R9Erhn!0mAJv>|HZh@eD#Cx}>n9UJD!VVhgS<|Fk zQ&?%uCa7z&MKq~2;{##a@h5U2oz9OK# zCkqGYAp+IxGVpyxu(KlBVIl3pmd5i=shHhwL4{GLPZzpEh1D8LfIWv_fE}+^nogQ%8c7^dd{;5r{TQQB-+KqriGlt z-=}(f3`{pVVxdxE4$7qf@GzUA@`*+phBC4(>IqDUpr*t5)jaWuvFP zehHNUNj5SYo5be3CH#9`16CfCPq%k3I;!Kek5=fmXSQo?k{3_bF*f{g^G$!R%mD2k zM@Es?(E74p4{SKV6@_r~++&lq-Si08NbujBW@|Uf>;|m!zOaQ=175AyTl$WOF77K0 zw5mwBg$*dGkT~Pcb??Eg6nD*RvFlNfzg7Ot-SdYl8cOB*&gvbckhT2Lt{{10a3w#z zaG-z6!YzHD*=XO9y2Im&M*CCEHE)+m!*ep#TopbTA4(x5b}vjz*qcX-7%71FN8T#? z%)T?M3JR})Rd;FT7~zUCtmHI-H%b`W`#2=NJjrLqZLIED23JkV(oNVma~QNe+J2u} zddnyfJ}yW;vN86^oGvH%NYL5b$!yIaYR-fs~|u0%9p7rRq4najI+EP1`_+iP~w z3O0*+OXoAS7t+GMv5nlzB;yzl^U8x%g*@@()86(-Jw?k+Z@z^aH0LdJh4J@a$tP*j z)Vj1SO4f7nw^=OS}J>|&_d=cQx)&ttgEj}66zRq^c5lkL9_hhHt`I3jt(lcaLt=P{}C^7mvZuPJ9I z%_IA_w@2>_K(-TjCXKRcMk;J#sg-YdwPnw{I7+{I!la#y0Sj2l6}hs!jN`J)246#m zYes>U@#ciS(0cy;jTH09iT!(J9qhe}&e}*4`5$vFzcPCa=S@#o8|PH;L~)lI%0_Nq z(f##A!L0w2SM9xa%{jyWumA1=ptE_K;UTwgs#CYX4djLf>GvCUny#4r`pSo+Nm(oU<{qD>m6ZGPdb^JKd!VE*eyYFIwg zP;suBnBvf|&S1Dw9lfXD@P=h8|K@8dKDgwGA|IxbV@dGePdEs|8jD4OpZR|Pd|if{ literal 0 HcmV?d00001 diff --git a/Samples/TransPDFTestArabic/GO/TransPDF_test_arabic.go b/Samples/TransPDFTestArabic/GO/TransPDF_test_arabic.go new file mode 100644 index 00000000..2a40292b --- /dev/null +++ b/Samples/TransPDFTestArabic/GO/TransPDF_test_arabic.go @@ -0,0 +1,73 @@ +//--------------------------------------------------------------------------------------- +// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +// Consult LICENSE.txt regarding license information. +//--------------------------------------------------------------------------------------- + +package main +import ( + "testing" + "flag" + . "github.com/pdftron/pdftron-go/v2" +) + +var licenseKey string +var modulePath string + +func init() { + flag.StringVar(&licenseKey, "license", "", "License key for Apryse SDK") + flag.StringVar(&modulePath, "modulePath", "", "Path for downloaded modules") +} + +//--------------------------------------------------------------------------------------- +// The following sample illustrates how to extract xlf from a PDF document for translation. +// It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +//--------------------------------------------------------------------------------------- + +// Relative path to the folder containing test files. +var inputPath = "../TestFiles/" +var outputPath = "../TestFiles/Output/" + +//--------------------------------------------------------------------------------------- + +func TestTransPDFArabic(t *testing.T) { + + // The first step in every application using PDFNet is to initialize the + // library and set the path to common PDF resources. The library is usually + // initialized only once, but calling Initialize() multiple times is also fine. + PDFNetInitialize(licenseKey) + + // Open a PDF document to translate + doc := NewPDFDoc(inputPath + "translation-test.pdf") + options := NewTransPDFOptions() + + // Set the source language in the options + options.SetSourceLanguage("en") + + // Set the number of pages to process in each batch + options.SetBatchSize(20) + + // Optionally, subset the pages to process + // This PDF only has a single page, but you can specify a subset of pages like this + // options.SetPages("-2,5-6,9,11-") + + // Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + // options.SetFlipPageContentsForBiDirectionalTranslations(true); + + // Extract the xlf to file and field the PDF for translation + TransPDFExtractXLIFF(doc, outputPath + "translation-test-arabic.xlf", options) + + // Save the fielded PDF + doc.Save(outputPath + "translation-test-arabic-fielded.pdf", uint(SDFDocE_linearized)) + + // The extracted xlf can be translated in a system of your choice. + // In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf + + // Perform the translation using the pre-prepared translated xliff + TransPDFApplyXLIFF(doc, inputPath + "translation-test-(en_to_ar).xlf", options) + + // Save the translated PDF + doc.Save(outputPath + "translation-test-arabic.pdf", uint(SDFDocE_linearized)) + doc.Close() + + PDFNetTerminate() +} diff --git a/Samples/TransPDFTestArabic/PHP/RunTest.bat b/Samples/TransPDFTestArabic/PHP/RunTest.bat new file mode 100644 index 00000000..8117a2b9 --- /dev/null +++ b/Samples/TransPDFTestArabic/PHP/RunTest.bat @@ -0,0 +1,6 @@ +@echo off +setlocal +set TEST_NAME=TransPDFTestArabic +set PATH=..\..\..\PDFNetC\Lib;%PATH% +php.exe %TEST_NAME%.php +endlocal diff --git a/Samples/TransPDFTestArabic/PHP/RunTest.sh b/Samples/TransPDFTestArabic/PHP/RunTest.sh new file mode 100644 index 00000000..1c32cff3 --- /dev/null +++ b/Samples/TransPDFTestArabic/PHP/RunTest.sh @@ -0,0 +1,4 @@ +#!/bin/sh +TEST_NAME=TransPDFTestArabic +export LD_LIBRARY_PATH=../../../PDFNetC/Lib +php -d extension="../../../PDFNetC/Lib/PDFNetPHP.so" $TEST_NAME.php diff --git a/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php b/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php new file mode 100644 index 00000000..9d466e3c --- /dev/null +++ b/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php @@ -0,0 +1,72 @@ +SetSourceLanguage("en"); + + // Set the number of pages to process in each batch + $options->SetBatchSize(20); + + // Optionally, subset the pages to process + // This PDF only has a single page, but you can specify a subset of pages like this + // $options->SetPages("-2,5-6,9,11-"); + + // Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + // $options->SetFlipPageContentsForBiDirectionalTranslations(true); + + // Extract the xlf to file and field the PDF for translation + TransPDF::ExtractXLIFF($doc, $output_path."translation-test.xlf", $options); + + // Save the fielded PDF + $doc->Save($output_path."translation-test-fielded.pdf", SDFDoc::e_linearized); + + // The extracted xlf can be translated in a system of your choice. + // In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf + + // Perform the translation using the pre-prepared translated xliff + TransPDF::ApplyXLIFF($doc, $input_path."translation-test-(en_to_ar).xlf", $options); + + // Save the translated PDF + $doc->Save($output_path."translation-test-arabic.pdf", SDFDoc::e_linearized); + $doc->Close(); + + } + catch (Exception $e) { + echo(nl2br("Unable to translate PDF document, error: " . $e->getMessage() . "\n")); + } + + PDFNet::Terminate(); +} + +main(); +?> diff --git a/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py new file mode 100644 index 00000000..66f83ee0 --- /dev/null +++ b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py @@ -0,0 +1,73 @@ +#--------------------------------------------------------------------------------------- +# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +# Consult LICENSE.txt regarding license information. +#--------------------------------------------------------------------------------------- + +import site +site.addsitedir("../../../PDFNetC/Lib") +import sys +from PDFNetPython import * + +import platform + +sys.path.append("../../LicenseKey/PYTHON") +from LicenseKey import * + +# --------------------------------------------------------------------------------------- +# The following sample illustrates how to extract xlf from a PDF document for translation. +# It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +# -------------------------------------------------------------------------------------- + +# Relative path to the folder containing the test files. +input_path = "../../TestFiles/" +output_path = "../../TestFiles/Output/" + +def main(): + + # The first step in every application using PDFNet is to initialize the + # library and set the path to common PDF resources. The library is usually + # initialized only once, but calling Initialize() multiple times is also fine. + PDFNet.Initialize(LicenseKey) + + try: + # Open a PDF document to translate + doc = PDFDoc(input_path + "translation-test.pdf") + options = TransPDFOptions() + + # Set the source language in the options + options.SetSourceLanguage("en") + + # Set the number of pages to process in each batch + options.SetBatchSize(20) + + # Optionally, subset the pages to process + # This PDF only has a single page, but you can specify a subset of pages like this + # options.SetPages("-2,5-6,9,11-") + + # Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + # options.SetFlipPageContentsForBiDirectionalTranslations(true) + + # Extract the xlf to file and field the PDF for translation + TransPDF.ExtractXLIFF(doc, output_path + "translation-test.xlf", options) + + # Save the fielded PDF + doc.Save(output_path + "translation-test-fielded.pdf", SDFDoc.e_linearized) + + # The extracted xlf can be translated in a system of your choice. + # In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf + + # Perform the translation using the pre-prepared translated xliff + TransPDF.ApplyXLIFF(doc, input_path + "translation-test-(en_to_ar).xlf", options) + + # Save the translated PDF + doc.Save(output_path + "translation-test-arabic.pdf", SDFDoc.e_linearized) + doc.Close() + except Exception as e: + print("Unable to translate PDF document, error: " + str(e)) + + PDFNet.Terminate() + + +if __name__ == '__main__': + main() + diff --git a/Samples/TransPDFTestArabic/RUBY/RunTest.bat b/Samples/TransPDFTestArabic/RUBY/RunTest.bat new file mode 100644 index 00000000..71ac13dd --- /dev/null +++ b/Samples/TransPDFTestArabic/RUBY/RunTest.bat @@ -0,0 +1,6 @@ +@echo off +setlocal +set TEST_NAME=TransPDFTestArabic +SET PATH=..\..\..\PDFNetC\Lib;%PATH% +ruby.exe %TEST_NAME%.rb +endlocal diff --git a/Samples/TransPDFTestArabic/RUBY/RunTest.sh b/Samples/TransPDFTestArabic/RUBY/RunTest.sh new file mode 100644 index 00000000..4523748e --- /dev/null +++ b/Samples/TransPDFTestArabic/RUBY/RunTest.sh @@ -0,0 +1,4 @@ +#!/bin/sh +TEST_NAME=TransPDFTestArabic +export LD_LIBRARY_PATH=../../../PDFNetC/Lib +ruby $TEST_NAME.rb diff --git a/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb b/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb new file mode 100644 index 00000000..6606fe49 --- /dev/null +++ b/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb @@ -0,0 +1,70 @@ +#--------------------------------------------------------------------------------------- +# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +# Consult LICENSE.txt regarding license information. +#--------------------------------------------------------------------------------------- + +require '../../../PDFNetC/Lib/PDFNetRuby' +include PDFNetRuby +require '../../LicenseKey/RUBY/LicenseKey' + +$stdout.sync = true + +# --------------------------------------------------------------------------------------- +# The following sample illustrates how to extract xlf from a PDF document for translation. +# It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +# -------------------------------------------------------------------------------------- + +# Relative path to the folder containing test files. +$input_path = "../../TestFiles/" +$output_path = "../../TestFiles/Output/" + +def main() + # The first step in every application using PDFNet is to initialize the + # library and set the path to common PDF resources. The library is usually + # initialized only once, but calling Initialize() multiple times is also fine. + PDFNet.Initialize(PDFTronLicense.Key) + + begin + + # Open a PDF document to translate + doc = PDFDoc.new($input_path + "translation-test.pdf") + options = TransPDFOptions.new + + # Set the source language in the options + options.SetSourceLanguage("en") + + # Set the number of pages to process in each batch + options.SetBatchSize(20) + + # Optionally, subset the pages to process + # This PDF only has a single page, but you can specify a subset of pages like this + # options.SetPages("-2,5-6,9,11-") + + # Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + # options.SetFlipPageContentsForBiDirectionalTranslations(true) + + # Extract the xlf to file and field the PDF for translation + TransPDF.ExtractXLIFF(doc, $output_path + "translation-test.xlf", options) + + # Save the fielded PDF + doc.Save($output_path + "translation-test-fielded.pdf", SDFDoc::E_linearized) + + # The extracted xlf can be translated in a system of your choice. + # In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf + + # Perform the translation using the pre-prepared translated xliff + TransPDF.ApplyXLIFF(doc, $input_path + "translation-test-(en_to_ar).xlf", options) + + # Save the translated PDF + doc.Save($output_path + "translation-test-arabic.pdf", SDFDoc::E_linearized) + doc.Close + + rescue => error + puts "Unable to translate PDF document, error: " + error.message + + end + + PDFNet.Terminate +end + +main() From 5e2289208c5c54b5df8d612efccb5a9521c965f4 Mon Sep 17 00:00:00 2001 From: mrmartinclark <75736799+mrmartinclark@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:07:10 +0100 Subject: [PATCH 3/6] Added Samples hebrew translation. --- .../PHP/TransPDFTestArabic.php | 4 +- .../PYTHON/TransPDFTestArabic.py | 4 +- .../RUBY/TransPDFTestArabic.rb | 4 +- .../GO/TransPDF_test_hebrew.go | 73 +++++++++++++++++++ Samples/TransPDFTestHebrew/PHP/RunTest.bat | 6 ++ Samples/TransPDFTestHebrew/PHP/RunTest.sh | 4 + .../PHP/TransPDFTestHebrew.php | 72 ++++++++++++++++++ .../PYTHON/TransPDFTestHebrew.py | 73 +++++++++++++++++++ Samples/TransPDFTestHebrew/RUBY/RunTest.bat | 6 ++ Samples/TransPDFTestHebrew/RUBY/RunTest.sh | 4 + .../RUBY/TransPDFTestHebrew.rb | 70 ++++++++++++++++++ 11 files changed, 314 insertions(+), 6 deletions(-) create mode 100644 Samples/TransPDFTestHebrew/GO/TransPDF_test_hebrew.go create mode 100644 Samples/TransPDFTestHebrew/PHP/RunTest.bat create mode 100644 Samples/TransPDFTestHebrew/PHP/RunTest.sh create mode 100644 Samples/TransPDFTestHebrew/PHP/TransPDFTestHebrew.php create mode 100644 Samples/TransPDFTestHebrew/PYTHON/TransPDFTestHebrew.py create mode 100644 Samples/TransPDFTestHebrew/RUBY/RunTest.bat create mode 100644 Samples/TransPDFTestHebrew/RUBY/RunTest.sh create mode 100644 Samples/TransPDFTestHebrew/RUBY/TransPDFTestHebrew.rb diff --git a/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php b/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php index 9d466e3c..ce30241b 100644 --- a/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php +++ b/Samples/TransPDFTestArabic/PHP/TransPDFTestArabic.php @@ -45,10 +45,10 @@ function main() // $options->SetFlipPageContentsForBiDirectionalTranslations(true); // Extract the xlf to file and field the PDF for translation - TransPDF::ExtractXLIFF($doc, $output_path."translation-test.xlf", $options); + TransPDF::ExtractXLIFF($doc, $output_path."translation-test-arabic.xlf", $options); // Save the fielded PDF - $doc->Save($output_path."translation-test-fielded.pdf", SDFDoc::e_linearized); + $doc->Save($output_path."translation-test-arabic-fielded.pdf", SDFDoc::e_linearized); // The extracted xlf can be translated in a system of your choice. // In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf diff --git a/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py index 66f83ee0..661d608f 100644 --- a/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py +++ b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py @@ -48,10 +48,10 @@ def main(): # options.SetFlipPageContentsForBiDirectionalTranslations(true) # Extract the xlf to file and field the PDF for translation - TransPDF.ExtractXLIFF(doc, output_path + "translation-test.xlf", options) + TransPDF.ExtractXLIFF(doc, output_path + "translation-test-arabic.xlf", options) # Save the fielded PDF - doc.Save(output_path + "translation-test-fielded.pdf", SDFDoc.e_linearized) + doc.Save(output_path + "translation-test-arabic-fielded.pdf", SDFDoc.e_linearized) # The extracted xlf can be translated in a system of your choice. # In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf diff --git a/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb b/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb index 6606fe49..016f7cd9 100644 --- a/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb +++ b/Samples/TransPDFTestArabic/RUBY/TransPDFTestArabic.rb @@ -44,10 +44,10 @@ def main() # options.SetFlipPageContentsForBiDirectionalTranslations(true) # Extract the xlf to file and field the PDF for translation - TransPDF.ExtractXLIFF(doc, $output_path + "translation-test.xlf", options) + TransPDF.ExtractXLIFF(doc, $output_path + "translation-test-arabic.xlf", options) # Save the fielded PDF - doc.Save($output_path + "translation-test-fielded.pdf", SDFDoc::E_linearized) + doc.Save($output_path + "translation-test-arabic-fielded.pdf", SDFDoc::E_linearized) # The extracted xlf can be translated in a system of your choice. # In this sample a pre-prepared translated file is used - translation-test-(en_to_ar).xlf diff --git a/Samples/TransPDFTestHebrew/GO/TransPDF_test_hebrew.go b/Samples/TransPDFTestHebrew/GO/TransPDF_test_hebrew.go new file mode 100644 index 00000000..89942dc1 --- /dev/null +++ b/Samples/TransPDFTestHebrew/GO/TransPDF_test_hebrew.go @@ -0,0 +1,73 @@ +//--------------------------------------------------------------------------------------- +// Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +// Consult LICENSE.txt regarding license information. +//--------------------------------------------------------------------------------------- + +package main +import ( + "testing" + "flag" + . "github.com/pdftron/pdftron-go/v2" +) + +var licenseKey string +var modulePath string + +func init() { + flag.StringVar(&licenseKey, "license", "", "License key for Apryse SDK") + flag.StringVar(&modulePath, "modulePath", "", "Path for downloaded modules") +} + +//--------------------------------------------------------------------------------------- +// The following sample illustrates how to extract xlf from a PDF document for translation. +// It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +//--------------------------------------------------------------------------------------- + +// Relative path to the folder containing test files. +var inputPath = "../TestFiles/" +var outputPath = "../TestFiles/Output/" + +//--------------------------------------------------------------------------------------- + +func TestTransPDFHebrew(t *testing.T) { + + // The first step in every application using PDFNet is to initialize the + // library and set the path to common PDF resources. The library is usually + // initialized only once, but calling Initialize() multiple times is also fine. + PDFNetInitialize(licenseKey) + + // Open a PDF document to translate + doc := NewPDFDoc(inputPath + "translation-test.pdf") + options := NewTransPDFOptions() + + // Set the source language in the options + options.SetSourceLanguage("en") + + // Set the number of pages to process in each batch + options.SetBatchSize(20) + + // Optionally, subset the pages to process + // This PDF only has a single page, but you can specify a subset of pages like this + // options.SetPages("-2,5-6,9,11-") + + // Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + // options.SetFlipPageContentsForBiDirectionalTranslations(true) + + // Extract the xlf to file and field the PDF for translation + TransPDFExtractXLIFF(doc, outputPath + "translation-test-hebrew.xlf", options) + + // Save the fielded PDF + doc.Save(outputPath + "translation-test-hebrew-fielded.pdf", uint(SDFDocE_linearized)) + + // The extracted xlf can be translated in a system of your choice. + // In this sample a pre-prepared translated file is used - translation-test-(en_to_he).xlf + + // Perform the translation using the pre-prepared translated xliff + TransPDFApplyXLIFF(doc, inputPath + "translation-test-(en_to_he).xlf", options) + + // Save the translated PDF + doc.Save(outputPath + "translation-test-hebrew.pdf", uint(SDFDocE_linearized)) + doc.Close() + + PDFNetTerminate() +} diff --git a/Samples/TransPDFTestHebrew/PHP/RunTest.bat b/Samples/TransPDFTestHebrew/PHP/RunTest.bat new file mode 100644 index 00000000..c5a27232 --- /dev/null +++ b/Samples/TransPDFTestHebrew/PHP/RunTest.bat @@ -0,0 +1,6 @@ +@echo off +setlocal +set TEST_NAME=TransPDFTestHebrew +set PATH=..\..\..\PDFNetC\Lib;%PATH% +php.exe %TEST_NAME%.php +endlocal diff --git a/Samples/TransPDFTestHebrew/PHP/RunTest.sh b/Samples/TransPDFTestHebrew/PHP/RunTest.sh new file mode 100644 index 00000000..3b2c945b --- /dev/null +++ b/Samples/TransPDFTestHebrew/PHP/RunTest.sh @@ -0,0 +1,4 @@ +#!/bin/sh +TEST_NAME=TransPDFTestHebrew +export LD_LIBRARY_PATH=../../../PDFNetC/Lib +php -d extension="../../../PDFNetC/Lib/PDFNetPHP.so" $TEST_NAME.php diff --git a/Samples/TransPDFTestHebrew/PHP/TransPDFTestHebrew.php b/Samples/TransPDFTestHebrew/PHP/TransPDFTestHebrew.php new file mode 100644 index 00000000..3db3b9c7 --- /dev/null +++ b/Samples/TransPDFTestHebrew/PHP/TransPDFTestHebrew.php @@ -0,0 +1,72 @@ +SetSourceLanguage("en"); + + // Set the number of pages to process in each batch + $options->SetBatchSize(20); + + // Optionally, subset the pages to process + // This PDF only has a single page, but you can specify a subset of pages like this + // $options->SetPages("-2,5-6,9,11-"); + + // Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + // $options->SetFlipPageContentsForBiDirectionalTranslations(true); + + // Extract the xlf to file and field the PDF for translation + TransPDF::ExtractXLIFF($doc, $output_path."translation-test-hebrew.xlf", $options); + + // Save the fielded PDF + $doc->Save($output_path."translation-test-hebrew-fielded.pdf", SDFDoc::e_linearized); + + // The extracted xlf can be translated in a system of your choice. + // In this sample a pre-prepared translated file is used - translation-test-(en_to_he).xlf + + // Perform the translation using the pre-prepared translated xliff + TransPDF::ApplyXLIFF($doc, $input_path."translation-test-(en_to_he).xlf", $options); + + // Save the translated PDF + $doc->Save($output_path."translation-test-hebrew.pdf", SDFDoc::e_linearized); + $doc->Close(); + + } + catch (Exception $e) { + echo(nl2br("Unable to translate PDF document, error: " . $e->getMessage() . "\n")); + } + + PDFNet::Terminate(); +} + +main(); +?> diff --git a/Samples/TransPDFTestHebrew/PYTHON/TransPDFTestHebrew.py b/Samples/TransPDFTestHebrew/PYTHON/TransPDFTestHebrew.py new file mode 100644 index 00000000..d038b268 --- /dev/null +++ b/Samples/TransPDFTestHebrew/PYTHON/TransPDFTestHebrew.py @@ -0,0 +1,73 @@ +#--------------------------------------------------------------------------------------- +# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +# Consult LICENSE.txt regarding license information. +#--------------------------------------------------------------------------------------- + +import site +site.addsitedir("../../../PDFNetC/Lib") +import sys +from PDFNetPython import * + +import platform + +sys.path.append("../../LicenseKey/PYTHON") +from LicenseKey import * + +# --------------------------------------------------------------------------------------- +# The following sample illustrates how to extract xlf from a PDF document for translation. +# It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +# -------------------------------------------------------------------------------------- + +# Relative path to the folder containing the test files. +input_path = "../../TestFiles/" +output_path = "../../TestFiles/Output/" + +def main(): + + # The first step in every application using PDFNet is to initialize the + # library and set the path to common PDF resources. The library is usually + # initialized only once, but calling Initialize() multiple times is also fine. + PDFNet.Initialize(LicenseKey) + + try: + # Open a PDF document to translate + doc = PDFDoc(input_path + "translation-test.pdf") + options = TransPDFOptions() + + # Set the source language in the options + options.SetSourceLanguage("en") + + # Set the number of pages to process in each batch + options.SetBatchSize(20) + + # Optionally, subset the pages to process + # This PDF only has a single page, but you can specify a subset of pages like this + # options.SetPages("-2,5-6,9,11-") + + # Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + # options.SetFlipPageContentsForBiDirectionalTranslations(true) + + # Extract the xlf to file and field the PDF for translation + TransPDF.ExtractXLIFF(doc, output_path + "translation-test-hebrew.xlf", options) + + # Save the fielded PDF + doc.Save(output_path + "translation-test-hebrew-fielded.pdf", SDFDoc.e_linearized) + + # The extracted xlf can be translated in a system of your choice. + # In this sample a pre-prepared translated file is used - translation-test-(en_to_he).xlf + + # Perform the translation using the pre-prepared translated xliff + TransPDF.ApplyXLIFF(doc, input_path + "translation-test-(en_to_he).xlf", options) + + # Save the translated PDF + doc.Save(output_path + "translation-test-hebrew.pdf", SDFDoc.e_linearized) + doc.Close() + except Exception as e: + print("Unable to translate PDF document, error: " + str(e)) + + PDFNet.Terminate() + + +if __name__ == '__main__': + main() + diff --git a/Samples/TransPDFTestHebrew/RUBY/RunTest.bat b/Samples/TransPDFTestHebrew/RUBY/RunTest.bat new file mode 100644 index 00000000..47ca8af9 --- /dev/null +++ b/Samples/TransPDFTestHebrew/RUBY/RunTest.bat @@ -0,0 +1,6 @@ +@echo off +setlocal +set TEST_NAME=TransPDFTestHebrew +SET PATH=..\..\..\PDFNetC\Lib;%PATH% +ruby.exe %TEST_NAME%.rb +endlocal diff --git a/Samples/TransPDFTestHebrew/RUBY/RunTest.sh b/Samples/TransPDFTestHebrew/RUBY/RunTest.sh new file mode 100644 index 00000000..dc58df9e --- /dev/null +++ b/Samples/TransPDFTestHebrew/RUBY/RunTest.sh @@ -0,0 +1,4 @@ +#!/bin/sh +TEST_NAME=TransPDFTestHebrew +export LD_LIBRARY_PATH=../../../PDFNetC/Lib +ruby $TEST_NAME.rb diff --git a/Samples/TransPDFTestHebrew/RUBY/TransPDFTestHebrew.rb b/Samples/TransPDFTestHebrew/RUBY/TransPDFTestHebrew.rb new file mode 100644 index 00000000..88489acc --- /dev/null +++ b/Samples/TransPDFTestHebrew/RUBY/TransPDFTestHebrew.rb @@ -0,0 +1,70 @@ +#--------------------------------------------------------------------------------------- +# Copyright (c) 2001-2025 by Apryse Software Inc. All Rights Reserved. +# Consult LICENSE.txt regarding license information. +#--------------------------------------------------------------------------------------- + +require '../../../PDFNetC/Lib/PDFNetRuby' +include PDFNetRuby +require '../../LicenseKey/RUBY/LicenseKey' + +$stdout.sync = true + +# --------------------------------------------------------------------------------------- +# The following sample illustrates how to extract xlf from a PDF document for translation. +# It then applies a pre-prepared translated xlf file to the PDF to produce a translated PDF. +# -------------------------------------------------------------------------------------- + +# Relative path to the folder containing test files. +$input_path = "../../TestFiles/" +$output_path = "../../TestFiles/Output/" + +def main() + # The first step in every application using PDFNet is to initialize the + # library and set the path to common PDF resources. The library is usually + # initialized only once, but calling Initialize() multiple times is also fine. + PDFNet.Initialize(PDFTronLicense.Key) + + begin + + # Open a PDF document to translate + doc = PDFDoc.new($input_path + "translation-test.pdf") + options = TransPDFOptions.new + + # Set the source language in the options + options.SetSourceLanguage("en") + + # Set the number of pages to process in each batch + options.SetBatchSize(20) + + # Optionally, subset the pages to process + # This PDF only has a single page, but you can specify a subset of pages like this + # options.SetPages("-2,5-6,9,11-") + + # Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. + # options.SetFlipPageContentsForBiDirectionalTranslations(true) + + # Extract the xlf to file and field the PDF for translation + TransPDF.ExtractXLIFF(doc, $output_path + "translation-test-hebrew.xlf", options) + + # Save the fielded PDF + doc.Save($output_path + "translation-test-hebrew-fielded.pdf", SDFDoc::E_linearized) + + # The extracted xlf can be translated in a system of your choice. + # In this sample a pre-prepared translated file is used - translation-test-(en_to_he).xlf + + # Perform the translation using the pre-prepared translated xliff + TransPDF.ApplyXLIFF(doc, $input_path + "translation-test-(en_to_he).xlf", options) + + # Save the translated PDF + doc.Save($output_path + "translation-test-hebrew.pdf", SDFDoc::E_linearized) + doc.Close + + rescue => error + puts "Unable to translate PDF document, error: " + error.message + + end + + PDFNet.Terminate +end + +main() From b6d4f620263e7bbe8be8b542d69ad2e8979cf6a5 Mon Sep 17 00:00:00 2001 From: mrmartinclark <75736799+mrmartinclark@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:28:55 +0100 Subject: [PATCH 4/6] Copilot suggested changes --- Samples/TransPDFTest/GO/TransPDF_test.go | 2 +- Samples/TransPDFTest/PYTHON/TransPDFTest.py | 2 +- Samples/TransPDFTest/RUBY/RunTest.sh | 2 +- .../PYTHON/TransPDFTestArabic.py | 2 +- jenkinsfiles/build_alpine_go.groovy | 16 ---------------- 5 files changed, 4 insertions(+), 20 deletions(-) diff --git a/Samples/TransPDFTest/GO/TransPDF_test.go b/Samples/TransPDFTest/GO/TransPDF_test.go index 3e81be74..f89f69e4 100644 --- a/Samples/TransPDFTest/GO/TransPDF_test.go +++ b/Samples/TransPDFTest/GO/TransPDF_test.go @@ -66,7 +66,7 @@ func TestTransPDF(t *testing.T) { TransPDFApplyXLIFF(doc, inputPath + "find-replace-test_(en_to_fr).xlf", options) // Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. - //TransPDF::ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr)-2.xlf", options) + // TransPDFApplyXLIFF(doc, inputPath + "find-replace-test_(en_to_fr)-2.xlf", options) // Save the translated PDF doc.Save(outputPath + "find-replace-test-fr.pdf", uint(SDFDocE_linearized)) diff --git a/Samples/TransPDFTest/PYTHON/TransPDFTest.py b/Samples/TransPDFTest/PYTHON/TransPDFTest.py index 061914c5..34a8fffd 100644 --- a/Samples/TransPDFTest/PYTHON/TransPDFTest.py +++ b/Samples/TransPDFTest/PYTHON/TransPDFTest.py @@ -60,7 +60,7 @@ def main(): TransPDF.ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr).xlf", options) # Comment out the above line and uncomment the below line to perform the translation using XLIFF 2. - #TransPDF::ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr)-2.xlf", options) + #TransPDF.ApplyXLIFF(doc, input_path + "find-replace-test_(en_to_fr)-2.xlf", options) # Save the translated PDF doc.Save(output_path + "find-replace-test-fr.pdf", SDFDoc.e_linearized) diff --git a/Samples/TransPDFTest/RUBY/RunTest.sh b/Samples/TransPDFTest/RUBY/RunTest.sh index 4523748e..27b65a4c 100755 --- a/Samples/TransPDFTest/RUBY/RunTest.sh +++ b/Samples/TransPDFTest/RUBY/RunTest.sh @@ -1,4 +1,4 @@ #!/bin/sh -TEST_NAME=TransPDFTestArabic +TEST_NAME=TransPDFTest export LD_LIBRARY_PATH=../../../PDFNetC/Lib ruby $TEST_NAME.rb diff --git a/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py index 661d608f..61362ec3 100644 --- a/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py +++ b/Samples/TransPDFTestArabic/PYTHON/TransPDFTestArabic.py @@ -45,7 +45,7 @@ def main(): # options.SetPages("-2,5-6,9,11-") # Optionally, flip the text boxes, vector artwork and images on the to page top retain continuity. - # options.SetFlipPageContentsForBiDirectionalTranslations(true) + # options.SetFlipPageContentsForBiDirectionalTranslations(true) # Extract the xlf to file and field the PDF for translation TransPDF.ExtractXLIFF(doc, output_path + "translation-test-arabic.xlf", options) diff --git a/jenkinsfiles/build_alpine_go.groovy b/jenkinsfiles/build_alpine_go.groovy index a35426fe..85b986d5 100644 --- a/jenkinsfiles/build_alpine_go.groovy +++ b/jenkinsfiles/build_alpine_go.groovy @@ -62,23 +62,7 @@ pipeline { dir('build/PDFTronGo/pdftron/samples') { sh ''' rm -rf TransPDFTest - ./runall_go.sh - ''' - } - } - - withCredentials([string(credentialsId: 'jenkins/core-sdk-key', variable: 'ENV_LICENSE_KEY')]) { - dir('build/PDFTronGo/pdftron/samples') { - sh ''' rm -rf TransPDFTestArabic - ./runall_go.sh - ''' - } - } - - withCredentials([string(credentialsId: 'jenkins/core-sdk-key', variable: 'ENV_LICENSE_KEY')]) { - dir('build/PDFTronGo/pdftron/samples') { - sh ''' rm -rf TransPDFTestHebrew ./runall_go.sh ''' From 698523c9a4c0eb833203b48849afb0013f131d24 Mon Sep 17 00:00:00 2001 From: mrmartinclark <75736799+mrmartinclark@users.noreply.github.com> Date: Mon, 1 Jun 2026 13:44:18 +0100 Subject: [PATCH 5/6] More copilot changes. --- Samples/TestFiles/translation-test-(en_to_he).xlf | 2 +- Samples/TransPDFTest/PHP/TransPDFTest.php | 2 +- Samples/TransPDFTest/PYTHON/TransPDFTest.py | 2 +- Samples/TransPDFTest/RUBY/TransPDFTest.rb | 2 +- .../GO/{TransPDF_test_arabic.go => TransPDFArabic_test.go} | 0 .../GO/{TransPDF_test_hebrew.go => TransPDFHebrew_test.go} | 0 6 files changed, 4 insertions(+), 4 deletions(-) rename Samples/TransPDFTestArabic/GO/{TransPDF_test_arabic.go => TransPDFArabic_test.go} (100%) rename Samples/TransPDFTestHebrew/GO/{TransPDF_test_hebrew.go => TransPDFHebrew_test.go} (100%) diff --git a/Samples/TestFiles/translation-test-(en_to_he).xlf b/Samples/TestFiles/translation-test-(en_to_he).xlf index 4aa9ee20..73004513 100644 --- a/Samples/TestFiles/translation-test-(en_to_he).xlf +++ b/Samples/TestFiles/translation-test-(en_to_he).xlf @@ -36,7 +36,7 @@ --> According to market research conducted by Stax Inc., the average Net Promoter Score (NPS) for the top five PDF SDK vendors is 35%. And 70% of customers express interest in switching despite the high costs. -לפיעל פי מחקר שוק שערכה Stax Inc., ציון ה-Net Promoter Score (NPS) הממוצע עבור חמשת ספקי PDF SDK המובילים הוא 35%. ו-70% מהלקוחות מביעים עניין במעבר למרות העלויות הגבוהות. +לפי מחקר שוק שערכה Stax Inc., ציון ה-Net Promoter Score (NPS) הממוצע עבור חמשת ספקי PDF SDK המובילים הוא 35%. ו-70% מהלקוחות מביעים עניין במעבר למרות העלויות הגבוהות.