'text/plain', 'txt' => 'text/plain', 'css' => 'text/css', 'gif' => 'image/gif', 'htm' => 'text/html', 'html' => 'text/html', 'ico' => 'image/x-ico', 'jpg' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'js' => 'application/x-javascript', 'png' => 'image/png', 'xml' => 'text/xml', ); function phar_rewrites($mimes) { $d = 'phar://'.__FILE__.'/PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/'; $r = $_SERVER['REQUEST_URI']; if ($r != '/' && file_exists($d . $r)) { $info = pathinfo($d . $r); if (isset($mimes[$info['extension']])) { header('Content-type:'.$mimes[$info['extension']]); } return $d . $r; } return $d . 'index.php'; } try { Phar::mapPhar(); } catch (Exception $e) { echo "Cannot process PEAR2_SimpleChannelFrontend phar: "; echo $e->getMessage(), " "; exit -1; } $file = phar_rewrites($mimes); include $file; __HALT_COMPILER(); ?> ?]ys:112:"PEAR2_SimpleChannelFrontend-0.1.0/.xmlregistry/packages/pear2.php.net/PEAR2_SimpleChannelFrontend/0.1.0-info.xml";pPEAR2_SimpleChannelFrontend-0.1.0/.xmlregistry/packages/pear2.php.net/PEAR2_SimpleChannelFrontend/0.1.0-info.xmlJ/KJ: package.xml-"/K-"#PPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Categories.php/KcvOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Exception.phpE/KEAӆNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Internet.php/K . JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Main.phpk/KkNjJPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/News.phpC/KC_fMPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Package.php-/K-. |QPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/PackageList.php/KTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/PackageRelease.php/KW.MPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/Support.phpG/KG\GTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/TemplateMapper.php/Ky_PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/SimpleChannelFrontend/UnregisteredViewException.php/K+aPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/config.sample.php/K[PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/960.css/KA[PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/all.cssZ/KZ MwVePEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/images/header.png/KR#]PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/reset.css/K*?nu[PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/scf.cssp/Kp\PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/css/text.css/K߶YPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/index.php/K[_PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/sample.htaccess/K8+.lPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/Categories.tpl.php/KrvuPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/InstallInstructions.tpl.php/K fPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/Main.tpl.phpP/KPW`cfPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/News.tpl.php /K i%iPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/Package.tpl.php/K(mPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/PackageList.tpl.php/KnO۶pPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/PackageRelease.tpl.phpP/KPڸiPEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/Support.tpl.php/Kkh={PEAR2_SimpleChannelFrontend-0.1.0/www/PEAR2_SimpleChannelFrontend/pear2.php.net/templates/UnregisteredViewException.tpl.php`/K`f`8PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Autoload.php/Kv ;PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/MultiErrors.php/KGMEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/MultiErrors/Exception.phpN/KNg9PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Exception.php//K/P)rYPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_HTTP_Request/pear2.php.net/examples/examples//KdPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_HTTP_Request/pear2.php.net/examples/examples/adapter.phpr/Kr`PEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_HTTP_Request/pear2.php.net/examples/examples/get.php6/K6L۶aPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_HTTP_Request/pear2.php.net/examples/examples/head.phpO/KO&²!aPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_HTTP_Request/pear2.php.net/examples/examples/post.phpq/Kq gAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter//KIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter/Curl.php/K> OPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter/Filesystem.php/ /K/ ϶IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter/Http.phpY /KY a̟(NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter/Phpsocket.php*/K*?o~NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter/Phpstream.php/K_˶DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Adapter.phpw/Kw(EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/allfiles.php/KPvFPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Exception.phpK/KKrBTDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Headers.php/K~նEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Listener.php /K "EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Response.phpO/KOt@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request/Uri.php/K0H䁶<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/HTTP/Request.php/K/K>3UoPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_2.phpt/K,=oPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_3.phpt/K[?oPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_4.phpt/KŶoPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_5.phpt/KpoPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_6.phpt/KIoPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_7.phptg/Kg ,oPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_8.phptR/KR>=oPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_9.phpt /K &ppPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_10.phptS/KSypPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_11.phpt /K иpPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_12.phpt/KL pPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_13.phpt/KMS˔pPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_14.phpt/K1pPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_15.phpt4/K4?'HpPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_16.phpt/K9ѶpPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_17.phpt^/K^CpPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_parse_18.phptb/KbyItPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_webrequest_1.phpt/KtPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_webrequest_2.phptV/KVF׶tPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/console_commandline_webrequest_3.phpt/K.;3WPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/test.xmlX/KX T\PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Console_CommandLine/pear2.php.net/tests.inc.phpG./KG.٧RPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels//KaPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels/doc.php.net.xml7/K77Q\bPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels/pear.php.net.xml/KdHcPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels/pear2.php.net.xml/KwbPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels/pecl.php.net.xmlp/Kpr[PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/default_channels/__uri.xml/K"OPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts//KePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AAACertificateServices/K$5<]PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ABA.ECOMRootCAX/KX6cPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AddTrustClass1CARoot/K#åePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AddTrustExternalCARoot /K icPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AddTrustPublicCARoot/KFA{fPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AddTrustQualifiedCARoot/K=wPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AmericaOnlineRootCertificationAuthority1@/K@@wPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AmericaOnlineRootCertificationAuthority2/KwPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AOLTimeWarnerRootCertificationAuthority1/KgwPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AOLTimeWarnerRootCertificationAuthority2\/K\SPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/AutoridaddeCertificacionFirmaprofesionalCIFA626340688/K8BMiѶfPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/BaltimoreCyberTrustRoot/KAG^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/beTRUSTedRootCA\/K\GɶvPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/beTRUSTedRootCA-BaltimoreImplementation/KM*tPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/beTRUSTedRootCA-EntrustImplementation/K&'pPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/beTRUSTedRootCA-RSAImplementation/KLWPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/blah.phpg/Kg+ ePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/CACertSigningAuthority2 /K2 }QWPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/CertumCAr/KrݶePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ChambersofCommerceRoot/K*^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Class2PrimaryCA(/K(tkPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/COMODOCertificationAuthority/KaQɶfPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigiCertAssuredIDRootCA\/K\cPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigiCertGlobalRootCAP/KPRlPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigiCertHighAssuranceEVRootCAn/Kn^D^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigiNotarRootCA/KpPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigitalSignatureTrustCo.GlobalCA1/KڹpPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DigitalSignatureTrustCo.GlobalCA3/KʭZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DSTACESCAX6/K[ZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DSTRootCAX1/K7/ZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DSTRootCAX2/K UZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/DSTRootCAX3/K!*vPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Entrust.netCertificationAuthority(2048)@/K@ކïvPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Entrust.netClientCertificationAuthority/KPrwPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Entrust.netClientCertificationAuthority2v/KvH|PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Entrust.netSecureServerCertificationAuthority/K}PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Entrust.netSecureServerCertificationAuthority2/Kw6pPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/EntrustRootCertificationAuthority/Km#^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/EquifaxSecureCA/KQ:1iPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/EquifaxSecureeBusinessCA-1/K0qhPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/EquifaxSecureeBusinessCA2/Kq磶oPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/EquifaxSecureGlobaleBusinessCA-1/K:lPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/FreeSSLCertificationAuthority@/K@a_PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GeoTrustGlobalCA/Kpm`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GeoTrustGlobalCA2/K7tPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GeoTrustPrimaryCertificationAuthority /K bPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GeoTrustUniversalCA/K`cPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GeoTrustUniversalCA2/K5-IdPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GlobalChambersignRoot/KՋYPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GlobalSign`/K`dȶZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GlobalSign2/Kz"mPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GlobalSignExtendedValidationCA/K_PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GlobalSignRootCA/KA6T^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GoDaddyClass2CA/KE^MrPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GoDaddySecureCertificationAuthority/KɟZVPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GPRoot2/KݹfPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GTECyberTrustGlobalRootz/Kzi`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/GTECyberTrustRoot/K0FѶtPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCAChainedCAsCertificationAuthority2 /K2 A pPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCACLASE1CertificationAuthority" /K" ipPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCACLASE3CertificationAuthority" /K" DqPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCACLASEA1CertificationAuthority2 /K2 qPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCACLASEA3CertificationAuthority2 /K2 N vPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSCATimestampingCertificationAuthority /K -X\PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/IPSSERVIDORES/K=vPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/NetLockExpressz(ClassC)Tanusitvanykiado/K/ExPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/NetLockKozjegyzoi(ClassA)Tanusitvanykiado* /K* cPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/NetLockMinositettKozjegyzoi(ClassQA)Tanusitvanykiado /K PtPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/NetLockUzleti(ClassB)Tanusitvanykiado/K 騶sPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/NetworkSolutionsCertificateAuthority/Kͽ^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/QuoVadisRootCA2/Kfo^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/QuoVadisRootCA3X /KX qPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/QuoVadisRootCertificationAuthority@/K@)Ѷ`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/RSASecurity1024v3~/K~=F`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/RSASecurity2048v3/K2]#hPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SecureCertificateServices/Kp]PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SecureGlobalCA`/K`\PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SecureTrustCA\/K\>jPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SecurityCommunicationRootCA/K>]PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SoneraClass1CA/K-(]PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SoneraClass2CA/KzWĶhPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/StaatderNederlandenRootCA`/K`e1`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/StarfieldClass2CA/KsmPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/StartComCertificationAuthority /K R3^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SwisscomRootCA1L/KLdaPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SwissSignGoldCA-G2/K ePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SwissSignPlatinumCA-G2*/K*6scPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/SwissSignSilverCA-G2"/K"YPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TaiwanGRCA/K=RmPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TCTrustCenter,Germany,Class2CA/K2[8mPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TCTrustCenter,Germany,Class3CA/Kd`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TDCInternetRootCA/KXPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TDCOCESCAD/KD|ZdPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawtePersonalBasicCA/K1gPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawtePersonalFreemailCA/KDRfPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawtePersonalPremiumCA/K9IdPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawtePremiumServerCA/KTTbPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/thawtePrimaryRootCA/Kl@U]PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawteServerCAz/Kz,ѶZPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawteSGCCA/KEcPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/ThawteTimestampingCA/K5(iPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TrustedCertificateServices/KeݶXPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TURKTRUST/K2ٶYPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/TURKTRUST2/Kڲ ^PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/UTN-DATACorpSGC@/K@(yPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/UTN-USERFirst-ClientAuthenticationandEmail/KePEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/UTN-USERFirst-Hardware`/K`ypPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/UTN-USERFirst-NetworkApplicationsH/KHcPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/UTN-USERFirst-ObjectL/KLն[PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/valicert.com</K<;! \PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/valicert.com2</K<WH\\PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/valicert.com3</K<viPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/Verisign-RSASecureServerCAH/KHص\PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass1PublicPrimaryCertificationAuthorityV/KVSMWPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass1PublicPrimaryCertificationAuthority-G2b/Kb"e7PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignClass1PublicPrimaryCertificationAuthority-G3/K{[PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass2PublicPrimaryCertificationAuthorityP/KP۶PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass2PublicPrimaryCertificationAuthority-G2f/KfzԶPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignClass2PublicPrimaryCertificationAuthority-G3/KHU$PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass3PublicPrimaryCertificationAuthorityP/KP-PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass3PublicPrimaryCertificationAuthority-G2b/KbbPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignClass3PublicPrimaryCertificationAuthority-G3/K{uPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignClass3PublicPrimaryCertificationAuthority-G5/K^&3PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VerisignClass4PublicPrimaryCertificationAuthority-G2b/Kb-նPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignClass4PublicPrimaryCertificationAuthority-G3/KnnPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VeriSignTimeStampingAuthorityCAz/Kz|v>`PEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/VisaeCommerceRoot@/K@lL]qPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/WellsFargoRootCertificateAuthority/K]BpPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/x509rootcerts/XRampGlobalCertificationAuthority/KlFVPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/built-in-commands.xmlA/KA)>TMPPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/channel-1.0.xsdP/KPrneVPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/customcommand-2.0.xsd@/K@SPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/customrole-2.0.xsd /K aSPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/customtask-2.0.xsd/K5C]VPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/developercommands.xmlv./Kv. ZPPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/package-2.0.xsdW/KW նPPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/package-2.1.xsdZ/KZMhPPEAR2_SimpleChannelFrontend-0.1.0/data/PEAR2_Pyrus/pear2.php.net/scscommands.xml/KJ?)PEAR2_SimpleChannelFrontend-0.1.0/script//K.PEAR2_SimpleChannelFrontend-0.1.0/script/pyrus/KQ}HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/AtomicFileTransaction//KUPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/AtomicFileTransaction/Exception.php/K /:PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel//KGPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/Exception.php/KKވEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/IMirror.php/KZnNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/Remotecategories.phpW /KW lBLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/Remotecategory.phpl/Kl_o3KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/Remotepackage.php/KL0GLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel/Remotepackages.php?/K?萶EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/Parser//KKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/Parser/v1.php/K,עUSPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1/Servers/Protocols//K[PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1/Servers/Protocols/REST.php/KoMNVPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1/Servers/Protocols.php/K0RKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1/Mirror.php/KBLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1/Servers.php/K7KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/Exception.phpT/KTkm0DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile/v1.php;/K;%3xrIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Mirror//KTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Mirror/Sqlite3.php/K[ʹPPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Mirror/Xml.php/K8JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Base.php1/K1f'MPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Channel.php/KOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Exception.php/Kp*жTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/ParseException.php/KIɶKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Pear1.phpc$/Kc$ :RҶMPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Sqlite3.phpE/KEʎIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry/Xml.php^/K^FpǶ9PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Config//KFPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Config/Exception.php/K@ %EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Config/Snapshot.php/K+=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Dependency//KJPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Dependency/Exception.php/K JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Dependency/Validator.phpp/KpUf6PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER//KCPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/BitString.php& /K& QCPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/BMPString.php[/K[5ӶAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Boolean.phpV/KV\m@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Choice.php /K O"EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Constructed.phpO/KOٶDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Enumerated.php /K  5϶CPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Exception.php/Kc}BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/External.php/KSIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/GeneralizedTime.php/Kd[CPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/IA5String.php/K$APEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Integer.phpR /KR >PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Null.php/Kh^hGPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/NumericString.php/K+JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/ObjectIdentifier.php /K u9CXEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/OCSPRequest.phpM/KMQRݶEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/OctetString.php/KZ@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Parser.php/K!p:IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/PrintableString.php/K@ސ4@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Schema.php[!/K[!1n FPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/SchemaChoice.php/KUijBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Sequence.php/K[4=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/Set.php/Kd@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/String.php/KOIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/UniversalString.php/KAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/UTCTime.php6/K6xDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/UTF8String.php/KiGPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER/VisibleString.phpd/Kd@PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DirectedGraph//KMPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DirectedGraph/Exception.php/KfJPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DirectedGraph/Vertex.php /K rAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role//KHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Cfg.php /K h=HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Cfg.xml/K#~KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Common.php'&/K'&UERPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customcommand.php/KRPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customcommand.xml8/K8m۶OPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customrole.php/Kv߶OPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customrole.xml2/K2JOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customtask.php/K}OPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Customtask.xml2/K2jEjIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Data.php/KTIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Data.xml/K# HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Doc.php/K+HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Doc.xml/K&r NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Exception.php/KbHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Ext.php/KB <@HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Ext.xml/K!%HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Php.php/KrbHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Php.xml/K@vKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Script.php/K}KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Script.xml/KHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Src.php/K)uyHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Src.xml/Ko*E&IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Test.php/KtIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Test.xml/KBζHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Www.php/KT HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role/Www.xml/K_=2IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Exception.php/KBd@DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer/Role.php{!/K{!iCQBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Creator//KOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Creator/Exception.php/KNRPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Creator/TaskIterator.php]/K]}j꧶IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Dependency/Set//KVPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Dependency/Set/Exception.php*/K*NζXPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Dependency/Set/PackageTree.phpX/KXҶLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Dependency/Set.php&/K&G߶?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Phar//KLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Phar/Exception.php/KaG>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Tar//KKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Tar/Exception.php/KhѲ>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Zip//KKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Zip/Exception.php/K6TvBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Base.phpU/KUDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Cloner.php,/K,EPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Creator.phpp@/Kp@S߲GPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Exception.php/KQX̶FPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/ICreator.phpc/Kc݊жPPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/InstalledException.php /K ѤBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Phar.phpw/Kwؾ/hDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Remote.php3/K3rc*APEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Tar.php+/K+=ovAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Xml.php/KEMAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package/Zip.php /K WrEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/Parser//KKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/Parser/v2.php/K.8LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Compatible//KYPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Compatible/Exception.php)/K)\ODQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Configureoption//K^PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Configureoption/Exception.php/K8NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies//KUPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies/Dep.phpH/KHYe[PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies/Exception.php)/K)qdLWPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies/Group.php/KIYPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies/Package.phpK/KK^KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Developer//KXPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Developer/Exception.php"/K"6茦GPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Files//KTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Files/Exception.php/KHIOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Files/File.php /K 4IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/License//KVPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/License/Exception.php /K ]h6IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release//KZPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release/BinaryPackage.php /K \PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release/ConfigureOption.php/KgݶVPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release/Exception.php/KWh]PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release/InstallCondition.php./K.4NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/UsesRoleTask//K[PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/UsesRoleTask/Exception.php-/K-C1)SPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/BundledPackage.phpx /Kx tOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Compatible.php""/K""^ZTPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Configureoption.php/K>oQQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Dependencies.php{1/K{1fWmNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Developer.php,/K,90JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Files.php /K g)϶LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/License.php/K~LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Release.php</K<WPSPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/SimpleProperty.phpY /KY hӵQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/UsesRoleTask.php/K9i?NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2/Validator.phpd/Kda0IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator//KQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/File.php/KSڶ^PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/FileAttribsFilter.phpG/KGW YPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/FileContents.php /K ̶^PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/FileContentsMulti.phpS/KSʀcPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/FileInstallationFilter.php/Kqb:TPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/FileTag.php(/K(]_aPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/MinimalPackageFilter.php/K>`PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/PackagingFilterBase.php{/K{hjb)^PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/PackagingIterator.php/KwqʶePEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2Iterator/ScriptFileFilterIterator.php*/K*<KPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/Exception.php/K5LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/IValidator.php/K)6DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile/v2.php/K]"b<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PECLBuild//KIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PECLBuild/Exception.php/KS^egAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PluginRegistry//KNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PluginRegistry/Exception.php/Kc˪_CPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Package//KKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Package/Base.phpZ/KZ#WAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Pear1//KQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Pear1/DependencyDB.phpa</Ka<\"LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Pear1/Package.phpm/Km CPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Sqlite3//KNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Sqlite3/Creator.php@/K@e@NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Sqlite3/Package.php/KGn?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Xml//KJPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Xml/Package.php/KbTCPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Base.php/K HPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Exception.php/KC9DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Pear1.phpc/Kc"FPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Sqlite3.phpR/KRm}8BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry/Xml.php%8/K%8N7PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST//K=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST/10.phpp/Kp@PR=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST/11.php&/K&mL\=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST/13.php(/K(2oDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST/Exception.php/KaPAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend//KLPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend/Command.php_/K_i MPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend/Commands.php/KFSl޶NPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend/Exception.php/KTCMPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend/Renderer.phpI /KI LAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception//KPPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception/InvalidTask.php/Kt9ZUPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception/MissingAttribute.php/KQPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception/NoAttributes.php/KxξXPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception/WrongAttributeValue.php/KrQ'TPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Postinstallscript/Paramgroup//K]PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Postinstallscript/Paramgroup/Param.php$/K$џluWPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Postinstallscript/Paramgroup.phpV9/KV9Là?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Replace//KEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Replace/rw.php/K?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Unixeol//KEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Unixeol/rw.php/KBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Windowseol//KHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Windowseol/rw.php/K1APEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Common.php"/K"UZĶDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Exception.php/K*ֶHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/MultipleProxy.php/Ky\LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Postinstallscript.php*H/K*H ]4BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Replace.php/K}BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Unixeol.php\ /K\ MնEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Task/Windowseol.php[ /K[ W;PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Validate//KHPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Validate/Exception.phpS/KS>ۀZ<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Validator//KDPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Validator/PECL.phpx/Kx<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLParser//KIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLParser/Exception.php/K!z<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLWriter//KIPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLWriter/Exception.php/KWKPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/AtomicFileTransaction.php_/K_>'c=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Channel.phpA/KA!ضAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelFile.php /K PEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ChannelRegistry.phpN/KNh\<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Config.php/KWP9PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DER.php\2/K\2VHNCPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DirectedGraph.php/KNPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/DownloadProgressListener.php5 /K5 'u?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Exception.php/KGPFPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/FileTransactions.php\$/K\$!CPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/HTTPException.php/KW@>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IChannel.phpR/KRBPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IChannelFile.php/K׮fƶFPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IChannelRegistry.php/KC,նFPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IFileTransaction.phpu/KuM{sն:PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ILog.php/Kf*?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Installer.phpQ/KQ~ADF>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IPackage.php/K{{BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IPackageFile.php/KH[m?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/IRegistry.php/K!Ny<PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Logger.php/K@:PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Main.php/KD=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/OSGuess.phpN+/KN+B&e=PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Package.php/KپAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PackageFile.php/KdC?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PECLBuild.phpSF/KSF"DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/PluginRegistry.php/K>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Registry.phpM%/KM%A.:PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/REST.php_)/K_)^DPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptFrontend.php /K G BPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/ScriptRunner.php'/K'RAPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Uninstaller.php/Kgib>PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/Validate.phpP/KPlnҶ?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLParser.php!/K!Ik?PEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Pyrus/XMLWriter.php$/K$%-̶oPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball//KPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball/BaseballPlayer.tpl.php/K PEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball/BaseballTeam.tpl.php/KxPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball/index.php</K<PEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball/ListItem.tpl.php1/K1PEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/baseball/examples/baseball/PartialSeason.tpl.phpA/KAcfTqqPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/templates/examples/templates//KPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/templates/examples/templates/MyTemplate.tpl.phpi/KiPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/templates/examples/templates/stdClass.tpl.phpS/KS:dPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/templates/examples/templates/StringView.tpl.phpN/KN͟]PEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/examples//KfPEAR2_SimpleChannelFrontend-0.1.0/doc/PEAR2_Templates_Savant/pear2.php.net/examples/examples/basic.phpP/KP9IPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/ObjectProxy//KXPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/ObjectProxy/ArrayAccess.php;/K;!XPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/ObjectProxy/Traversable.php/KƶRPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/BasicFastCompiler.php/K VPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/ClassToTemplateMapper.php /K RPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/CompilerException.phpn/KnٓH}RPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/CompilerInterface.phpo/Ko23JPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/Exception.phpD/KD`{9VPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/FastCompilerInterface.phpg/Kg sNOPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/FilterAbstract.php/KSܶEPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/Main.php[/K[PPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/MapperInterface.php`/K`W(LPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/ObjectProxy.phpA/KA_RPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/TemplateException.phpn/Kn?YPEAR2_SimpleChannelFrontend-0.1.0/php/pear2/Templates/Savant/UnexpectedValueException.php/K VSPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape//KePEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape/echostring.tpl.php/K"^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape/Foo.tpl.php/K Ķ^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape/object.phptg/Kg8ϥ^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape/raw.tpl.php'/K'"t^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/escape/string.phpt/K9LSPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render//K]PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/array.phpt/Kk!EնePEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/echostring.tpl.php/KucPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/fastcompile.phpt/KV: ^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/Foo.tpl.php>/K>^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/object.phpt[/K[CY5^PEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/render/string.phpt/K\'ضbPEAR2_SimpleChannelFrontend-0.1.0/test/PEAR2_Templates_Savant/pear2.php.net/test_framework.php.inc/K8F PEAR2_SimpleChannelFrontend pear2.php.net A simple PEAR channel frontend that does not require a database. This package provides a simple frontend to a PEAR channel by directly using the PEAR channel files. To use, place the PEAR2_SimpleChannelFrontend-0.1.0.phar in the root of your channel server as index.php, and add an .htaccess file with the following: <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] </IfModule> For a more customized interface, you can create a config.inc.php file, or install the package and use the files in the www_dir as a starting point for a fully customized PEAR channel. Brett Bieber saltybeagle saltybeagle@php.net yes 2009-12-20 0.1.0 0.1.0 alpha alpha New BSD License Package PEAR2_SimpleChannelFrontend release notes for version 0.1.0. Basic features: * Customizable News and Support pages * Package pages with download links * Category listing Package PEAR2_SimpleChannelFrontend API release notes for version 0.1.0. 5.2.0 2.0.0a1 PEAR2_Pyrus pear2.php.net PEAR2_Templates_Savant pear2.php.net PEAR2_SimpleChannelFrontend pear2.php.net A simple PEAR channel frontend that does not require a database. This package provides a simple frontend to a PEAR channel by directly using the PEAR channel files. To use, place the PEAR2_SimpleChannelFrontend-0.1.0.phar in the root of your channel server as index.php, and add an .htaccess file with the following: <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] </IfModule> For a more customized interface, you can create a config.inc.php file, or install the package and use the files in the www_dir as a starting point for a fully customized PEAR channel. Brett Bieber saltybeagle saltybeagle@php.net yes 2009-12-20 0.1.0 0.1.0 alpha alpha New BSD License Package PEAR2_SimpleChannelFrontend release notes for version 0.1.0. Basic features: * Customizable News and Support pages * Package pages with download links * Category listing Package PEAR2_SimpleChannelFrontend API release notes for version 0.1.0. 5.2.0 1.4.8 adapter = new \pear2\HTTP\Request\Adapter\Filesystem($this); if ($url) { $this->url = $url; } } static function addDirectory($dir, $urlbase) { \pear2\HTTP\Request\Adapter\Filesystem::addDirectory($dir, $urlbase); } } * @copyright 2009 Your Name * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.php.net/repository/pear2/PEAR2_SimpleChannelFrontend */ /** * Main class for PEAR2_SimpleChannelFrontend * * @category Yourcategory * @package PEAR2_SimpleChannelFrontend * @author Your Name * @copyright 2009 Your Name * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.php.net/repository/pear2/PEAR2_SimpleChannelFrontend */ namespace pear2\SimpleChannelFrontend; class Main { /** * The channel object * @var Channel */ static public $channel; public $page_title = '{page_title}'; public $page_content; protected $options = array('view' => 'news'); protected static $view_map = array('news' => 'pear2\SimpleChannelFrontend\News', 'packages' => 'pear2\SimpleChannelFrontend\PackageList', 'package' => 'pear2\SimpleChannelFrontend\Package', 'release' => 'pear2\SimpleChannelFrontend\PackageRelease', 'categories' => 'pear2\SimpleChannelFrontend\Categories', 'support' => 'pear2\SimpleChannelFrontend\Support'); public static $url = ''; /** * Constructor * * @param \pear2\Pyrus\ChannelFile $channel The channel object * @param array $options Associative array of options */ function __construct(\pear2\Pyrus\IChannelFile $channel, $options = array()) { static::setChannel($channel); $this->options = array_merge($this->options, $options); try { $this->run(); } catch(Exception $e) { $this->page_content = $e; } } /** * Set the channel file for this frontend. * * @param \pear2\Pyrus\IChanelFile $channel The channel object * * @return void */ public static function setChannel(\pear2\Pyrus\IChannelFile $channel) { \pear2\Pyrus\Main::$downloadClass = __NAMESPACE__ . '\\Internet'; \pear2\Pyrus\Config::current()->cache_dir = '/tmp'; static::$channel = \pear2\Pyrus\Config::current()->channelregistry['pear2.php.net']; $base_directory = dirname($channel->path); $rest = str_replace('http://' . $channel->name, '', $channel->protocols->rest['REST1.0']->baseurl); Internet::addDirectory($base_directory . '/get', 'http://' . $channel->name . '/get/'); Internet::addDirectory($base_directory . $rest, $channel->protocols->rest['REST1.0']->baseurl); static::$channel->fromArray($channel->getArray()); } /** * Determine which view to instantiate and set as the page content * * @return mixed */ function run() { if (!array_key_exists($this->options['view'], static::$view_map)) { throw new UnregisteredViewException('No view, or incorrect view specified.'); } $class = static::$view_map[$this->options['view']]; $options = array_merge($this->options, array('frontend'=>$this)); $this->page_content = new $class($options); } /** * Register a new view for the channel. * * @param string $route The route used to identify this model and view * @param string $class Class to instantiate when this view is requested. * * @return Main */ function registerView($route, $classname) { static::$view_map[$route] = $classname; return $this; } /** * Get the URL to a specific view * * @param mixed $class What class to return a route for * * @return string The url */ public static function getURL($class = null) { static $default_view; if (empty($default_view)) { $main = new \ReflectionClass(__CLASS__); $properties = $main->getDefaultProperties(); $default_view = $properties['options']['view']; } $url = static::$url; if ($class) { if (is_object($class)) { $class = get_class($class); } $route = array_keys(static::$view_map, $class); if (!count($route)) { throw new UnregisteredViewException('The view for that object is not registered'); } if ($route[0] != $default_view) { $url .= '?view=' . $route[0]; } } return $url; } /** * Called after the page is rendered to perform any necessary replacements. * * @param string $html The rendered template. * * @return string Filtered html */ public function postRender($html) { $html = str_replace('{page_title}', $this->page_title, $html); return $html; } } _package = $options['frontend']::$channel->remotepackage[$options['package']]; } function __get($var) { return $this->_package->$var; } function __call($method, $args) { return call_user_func_array(array($this->_package, $method), $args); } function getIterator() { return $this->_package; } } _package = $options['frontend']::$channel->remotepackage[$options['package']]; try { $this->_package->setRawVersion( null, array('release' => $options['packageVersion']) ); } catch (\Exception $e) { throw new UnregisteredViewException($e->getMessage()); } } function __get($var) { return $this->_package->$var; } function __call($method, $args) { return call_user_func_array(array($this->_package, $method), $args); } } 6p':K7[p:Z!ڡ>`5:uWg_;wkn`EB-ca@JVo5 xD|ꏀ>4xfS@ o ÉPG;,$OA1(,ש#4q㳁+JqV iؚ+u,@a"+蚆ەV(d $h %PEE M, Jd.Jբmuɝ:u X0rإG1G+JhRt. XzQ)iEcS(~ݠY;f0fЈjRxS(eɋJni˚5J`Ay/JI[!*&g*Ե$_(h):\(lޠQ(¨KE%ЩKʡx|8v;3lE.Lt(^eTz,]{Ow /X,eYnQJGFmJJt\)1(N>S٦]*Tt()T kwgKt&94O9)TfFm>t'(1 _!P>i${SH+W()ʪܠtz,G^嫙{JZɄ(L|-}NIBa3OOQNe{9T'R㉕ J NX +ta̒vrUca IIqJBOXm)ѩ.=d%%C9a9BNgXvڱza9j0P3 'nzyHJ] *=!lKTNx&ѵ3  * J!PA06 M&a0#/uuIˏeI{.kSׁ<2x@Gʢ6"*CyTaaO&%ڽN()ay‹SԜAڴf%üa!N"t[aoy*3oR87OMf񦓡2̧[m<* $/%pǥ>K}`k~$'a`=Ifi4x< Ox DFmLIENDB`html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:'';content:none}:focus{outline:0}ins{text-decoration:none}del{text-decoration:line-through}table{border-collapse:collapse;border-spacing:0}body{ background:url(images/header.png) #006500 repeat-x; } body a { text-decoration:none; border-bottom:1px dotted; } .header { color:#ECECEC; text-shadow:black; font-size:150%; height:114px; } .header a, .header a:link { padding:5px; color:#ECECEC; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; text-decoration: none; text-shadow: #000000; border-bottom:none; } .header a:hover { background-color: rgba(0, 0, 0, 0.2); } .header h1 { font-size:2em; } ul.navigation li { list-style:none; display:inline; } ul.package-info { list-style-type: none; } .content { margin-top:3em; -moz-border-radius:5px; -webkit-border-radius:5px; border-radius:5px; overflow:auto; background-color:#EBECDA; color:#444; } ol.instructions { -moz-border-radius:10px; -webkit-border-radius:10px; border-radius:10px; padding:10px; background-color:rgba(0, 0, 0, 0.8); color:#FFF; font-size:120%; line-height:2em; font-family:"andale mono", monaco, "courier new", courier; } .releases { position: absolute; float: right; background-color: #00BB00; color: #FFF; } .releases h3 { font-family: Georgia,Palatino,"Times New Roman",Times,serif; font-size: 150%; background-color: #006500; color: #FFF; padding-left: 10px; margin-bottom: 5px; } .releases ul, .releases li { list-style-image: none; list-style-position: outside; list-style-type: none; margin-left: 2px; } .releases ul, .release-notes { padding-left: 10px; } .releases li, .release-notes { padding-bottom: 5px; } .releases li a { color: #000; } .releases .download { float: right; margin-right: 5px; } ol.instructions a, ol.instructions a:link { color:#FFF; } .footer { margin:10px; font-size:85%; color:#CCC; } body{font:13px/1.5 'Helvetica Neue',Arial,'Liberation Sans',FreeSans,sans-serif}a:focus{outline:1px dotted}hr{border:0 #ccc solid;border-top-width:1px;clear:both;height:0}h1{font-size:25px}h2{font-size:23px}h3{font-size:21px}h4{font-size:19px}h5{font-size:17px}h6{font-size:15px}ol{list-style:decimal}ul{list-style:disc}li{margin-left:30px}p,dl,hr,h1,h2,h3,h4,h5,h6,ol,ul,pre,table,address,fieldset{margin-bottom:20px}name.'/'; } else { echo 'You must place this file in your channel server, or provide a config.inc.php file.'; exit(); } $options = $_GET; preg_match('/\/(?[0-9a-z_]+)(-(?[0-9ab.]+))?$/i', $_SERVER['REQUEST_URI'], $matches); if (isset($matches['package'])) { $options['view'] = 'package'; $options['package'] = $matches['package']; if (isset($matches['version'])) { $options['packageVersion'] = $matches['version']; $options['view'] = 'release'; } } $frontend = new pear2\SimpleChannelFrontend\Main($channel, $options); $savant = new pear2\Templates\Savant\Main(); $savant->setClassToTemplateMapper(new pear2\SimpleChannelFrontend\TemplateMapper); $savant->setTemplatePath(array(__DIR__ . '/templates')); $savant->setEscape('htmlspecialchars'); $savant->addFilters(array($frontend, 'postRender')); echo $savant->render($frontend); ?> RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] context->page_title = 'Categories | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

Categories

'; } ?>

Installation

  1. $>php pyrus.phar channel-discover name; ?>
  2. $>php pyrus.phar install
<?php echo $context->page_title; ?>
render($context->page_content); ?>
context->page_title = 'News | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

Latest News

Welcome to the next generation of PEAR channels.

  1. Download the new PEAR installer:
    pyrus.phar
  2. Discover this channel:
    $>php pyrus.phar channel-discover name; ?>
  3. Install packages:
    $>php pyrus.phar install alias; ?>/package
    where package is the name of the package to install.

Users can get started by reading the introduction.

Download

Download pyrus.phar

This website provides packages to install using the pyrus package installer. With pyrus you can install all the packages available on this channel, as well as any PEAR compatible package from a large number of repositories.

context->page_title = $context->name.' | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

Package :: name; ?>

summary; ?>

', true)", $context->description); echo nl2br($description); ?>

render($context->channel . '/' . $context->name . '-' . $context->version['release'], 'InstallInstructions.tpl.php'); ?>

Releases

context->page_title = 'Packages | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

Available Packages

context->page_title = $context->name.' | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

name; ?>-version['release']; ?>

  • Version: version['release']; ?>
  • Stability: stability['release']; ?>
  • Released on: date; ?>
  • License: license['name']; ?>
render($context->channel . '/' . $context->name . '-' . $context->version['release'], 'InstallInstructions.tpl.php'); ?>

Release Notes

notes); ?>
context->page_title = 'Support | '.pear2\SimpleChannelFrontend\Main::$channel->name; ?>

Support

WHOAH Nelly.

That view doesn't exist!

getTrace(); if (isset($trace[2]) && isset($trace[2]['function']) && in_array($trace[2]['function'], array('class_exists', 'interface_exists'))) { return false; } if (isset($trace[1]) && isset($trace[1]['function']) && in_array($trace[1]['function'], array('class_exists', 'interface_exists'))) { return false; } die ((string) $e); } /** * return the array of paths PEAR2 autoload has registered * * @return array */ static function getPaths() { return self::$paths; } } } Autoload::initialize(dirname(__DIR__)); * $multi = new \pear2\MultiErrors(); * $multi->E_WARNING[] = new Exception('test'); * $multi->E_ERROR[] = new Exception('test 2'); * foreach ($multi as $error) { * echo $error; * } * foreach ($multi->E_WARNING as $error) { * echo $error; * } * foreach ($multi->E_ERROR as $error) { * echo $error; * } * if (count($multi->E_ERROR)) { * throw new \pear2\Exception('Failure to do something', $multi); * } * * @copyright 2007 Gregory Beaver * @package \pear2\MultiErrors * @license http://www.php.net/license/3_0.txt PHP License */ namespace pear2; class MultiErrors extends \Exception implements \Iterator, \Countable, \ArrayAccess { private $_allowedLevels = array('E_NOTICE' => 0, 'E_WARNING' => 1, 'E_ERROR' => 2); /** * Errors are stored in the order that they are declared * @var array */ private $_errors = array(); /** * To allow $this->E_WARNING[] = new BlahException; * * @var int */ private $_requestedLevel = false; /** * Internal PEAR2_MultiError objects for error levels * @var array */ private $_subMulti = array(); /** * Parent \pear2\MultiErrors for an error level tracker * * @var \pear2\MultiErrors */ private $_parent; public function __construct($mylevel = false, array $allowed = array('E_NOTICE', 'E_WARNING', 'E_ERROR'), MultiErrors $parent = null) { foreach ($allowed as $level) { if (!is_string($level) || strpos($level, 'E_') !== 0) { throw new MultiErrors\Exception('Invalid level ' . (string) $level); } } $this->_allowedLevels = array_flip($allowed); $this->_requestedLevel = $mylevel; if ($mylevel) { $this->_parent = $parent; } parent::__construct('multiple errors found'); } public function current() { return current($this->_errors); } public function key() { return key($this->_errors); } public function next() { return next($this->_errors); } public function rewind() { return reset($this->_errors); } public function valid() { return false !== current($this->_errors); } /** * Merge in errors from an existing \pear2\MultiErrors * * This also merges in any new error levels not supported in this instance. * @param \pear2\MultiErrors $error */ public function merge(MultiErrors $error) { foreach ($error->levels as $level) { if (!isset($this->_allowedLevels[$level])) { $this->_allowedLevels[$level] = 1; } foreach ($error->$level as $e) { $this->{$level}[] = $e; } } } public function count() { return count($this->_errors); } public function offsetExists($offset) { return isset($this->_errors[$offset]); } public function offsetGet ($offset) { if (isset($this->_errors[$offset])) { return $this->_errors[$offset]; } return null; } public function offsetSet ($offset, $value) { if ($offset === null && !$this->_requestedLevel && $value instanceof self) { $this->merge($value); return; } if (!($value instanceof \Exception)) { throw new MultiErrors\Exception('offsetSet: $value is not an Exception object'); } if ($this->_requestedLevel) { if ($offset === null) { // called with $a->E_BLAH[] = new Exception('hi'); $offset = count($this->_errors); } if (!is_int($offset)) { throw new MultiErrors\Exception('offsetSet: $offset is not an integer'); } $this->_errors[$offset] = $value; $this->_parent[$this->_requestedLevel . '-' . $offset] = $value; } else { if (!is_string($offset)) { throw new MultiErrors\Exception('Cannot add an error directly ' . 'to a pear2\MultiErrors with $a[] = new Exception, use an ' . ' E_* constant like $a->E_WARNING[] = new Exception'); } $offset = explode('-', $offset); $level = $offset[0]; $offset = $offset[1]; // this is called when the "$this->_parent[] = $value" line is executed. if (!isset($this->_subMulti[$level]) || $this->_subMulti[$level][$offset] !== $value) { // must be in a child or it'll throw off the whole thingy throw new MultiErrors\Exception('Cannot add an error directly ' . 'to a pear2\MultiErrors with $a[] = new Exception, use an ' . ' E_* constant like $a->E_WARNING[] = new Exception'); } $this->_errors[] = $value; } } public function offsetUnset ($offset) { if (isset($this->_errors[$offset])) { unset($this->_errors[$offset]); } } public function __get($level) { if ($level === 'levels') { return array_keys($this->_allowedLevels); } if (!count($this->_allowedLevels)) { throw new MultiErrors\Exception('Cannot nest requests ' . '(like $multi->E_WARNING->E_ERROR[] = new Exception(\'\');)'); } if (isset($this->_allowedLevels[$level])) { if (!isset($this->_subMulti[$level])) { $this->_subMulti[$level] = new self($level, array(), $this); } return $this->_subMulti[$level]; } throw new MultiErrors\Exception('Requested error level must be one of ' . implode(', ', array_keys($this->_allowedLevels))); } public function toArray() { return $this->_errors; } } ?> * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2007 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version CVS: $Id: Exception.php,v 1.28 2007/05/07 01:58:54 cellog Exp $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1.0 */ /** * Base PEAR2_Exception Class * * 1) Features: * * - Nestable exceptions (throw new PEAR2_Exception($msg, $prev_exception)) * - Definable triggers, shot when exceptions occur * - Pretty and informative error messages * - Added more context info available (like class, method or cause) * - cause can be a PEAR2_Exception or an array of mixed * PEAR2_Exceptions or a \pear2\MultiErrors * - callbacks for specific exception classes and their children * * 2) Ideas: * * - Maybe a way to define a 'template' for the output * * 3) Inherited properties from PHP Exception Class: * * protected $message * protected $code * protected $line * protected $file * private $trace * * 4) Inherited methods from PHP Exception Class: * * __clone * __construct * getMessage * getCode * getFile * getLine * getTraceSafe * getTraceSafeAsString * __toString * * 5) Usage example * * * class PEAR2_MyPackage_Exception extends PEAR2_Exception {} * class Test { * function foo() * { * throw new PEAR2_MyPackage_Exception('Error Message', ERROR_CODE); * } * } * * function myLogger($pear2_exception) * { * echo $pear2_exception->getMessage(); * } * // each time a exception is thrown the 'myLogger' will be called * // (its use is completely optional) * PEAR2_Exception::addObserver('myLogger'); * $test = new Test; * try { * $test->foo(); * } catch (PEAR2_Exception $e) { * print $e; * } * * * @category pear * @package PEAR * @author Tomas V.V.Cox * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2007 The PHP Group * @license http://www.php.net/license/3_0.txt PHP License 3.0 * @version Release: @package_version@ * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1.0 * */ namespace pear2; abstract class Exception extends \Exception { public static $htmlError = false; const OBSERVER_PRINT = -2; const OBSERVER_TRIGGER = -4; const OBSERVER_DIE = -8; private static $_observers = array(); private static $_uniqueid = 0; private $_trace; /** * Supported signatures: * - PEAR2_Exception(string $message); * - PEAR2_Exception(string $message, int $code); * - PEAR2_Exception(string $message, Exception $cause); * - PEAR2_Exception(string $message, Exception $cause, int $code); * - PEAR2_Exception(string $message, pear2\MultiErrors $cause); * - PEAR2_Exception(string $message, pear2\MultiErrors $cause, int $code); * @param string exception message * @param int|Exception|pear2\MultiErrors|null exception cause * @param int|null exception code or null */ public function __construct($message, $p2 = null, $p3 = null) { if (is_int($p2)) { $code = $p2; $cause = null; } elseif (is_object($p2)) { if (!($p2 instanceof \Exception)) { throw new \Exception('exception cause must be Exception, or pear2\MultiErrors'); } $code = $p3; $cause = $p2; } else { $code = null; $cause = null; } if (!is_string($message)) { throw new \Exception('exception message must be a string, was ' . gettype($message)); } parent::__construct($message, $code, $cause); $this->signal(); } /** * @param mixed $callback - A valid php callback, see php func is_callable() * - A PEAR2_Exception::OBSERVER_* constant * - An array(const PEAR2_Exception::OBSERVER_*, * mixed $options) * @param string $label The name of the observer. Use this if you want * to remove it later with removeObserver() */ public static function addObserver($callback, $label = 'default') { self::$_observers[$label] = $callback; } public static function removeObserver($label = 'default') { unset(self::$_observers[$label]); } /** * @return int unique identifier for an observer */ public static function getUniqueId() { return self::$_uniqueid++; } private function signal() { foreach (self::$_observers as $func) { if (is_callable($func)) { call_user_func($func, $this); continue; } settype($func, 'array'); switch ($func[0]) { case self::OBSERVER_PRINT : $f = (isset($func[1])) ? $func[1] : '%s'; printf($f, $this->getMessage()); break; case self::OBSERVER_TRIGGER : $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; trigger_error($this->getMessage(), $f); break; case self::OBSERVER_DIE : $f = (isset($func[1])) ? $func[1] : '%s'; die(printf($f, $this->getMessage())); break; default: trigger_error('invalid observer type', E_USER_WARNING); } } } /** * Returns the exception that caused this exception to be thrown * @access public * @return Exception|array The context of the exception */ public function getCause() { return $this->getPrevious(); } /** * Function must be public to call on caused exceptions * @param array */ public function getCauseMessage(&$causes) { $trace = $this->getTraceSafe(); $cause = array('class' => get_class($this), 'message' => $this->message, 'file' => 'unknown', 'line' => 'unknown'); if (isset($trace[0])) { if (isset($trace[0]['file'])) { $cause['file'] = $trace[0]['file']; $cause['line'] = $trace[0]['line']; } } $causes[] = $cause; if ($this->getPrevious() instanceof self) { $this->getPrevious()->getCauseMessage($causes); } elseif ($this->getPrevious() instanceof \pear2\MultiErrors) { foreach ($this->getPrevious() as $cause) { if ($cause instanceof self) { $cause->getCauseMessage($causes); } elseif ($cause instanceof \Exception) { $causes[] = array('class' => get_class($cause), 'message' => $cause->getMessage(), 'file' => $cause->getFile(), 'line' => $cause->getLine()); } } } elseif ($this->getPrevious() instanceof \Exception) { $causes[] = array('class' => get_class($this->getPrevious()), 'message' => $this->getPrevious()->getMessage(), 'file' => $this->getPrevious()->getFile(), 'line' => $this->getPrevious()->getLine()); } } public function getTraceSafe() { if (!isset($this->_trace)) { $this->_trace = $this->getTrace(); if (empty($this->_trace)) { $backtrace = debug_backtrace(); $this->_trace = array($backtrace[count($backtrace)-1]); } } return $this->_trace; } public function getErrorClass() { $trace = $this->getTraceSafe(); return $trace[0]['class']; } public function getErrorMethod() { $trace = $this->getTraceSafe(); return $trace[0]['function']; } public function __toString() { if (self::$htmlError) { return $this->toHtml(); } return $this->toText(); } public function toHtml() { $trace = $this->getTraceSafe(); $causes = array(); $this->getCauseMessage($causes); $html = '' . "\n"; foreach ($causes as $i => $cause) { $html .= '\n"; } $html .= '' . "\n" . '' . '' . '' . "\n"; foreach ($trace as $k => $v) { $html .= '' . '' . '' . "\n"; } $html .= '' . '' . '' . "\n" . '
' . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' . 'on line ' . $cause['line'] . '' . "
Exception trace
#FunctionLocation
' . $k . ''; if (!empty($v['class'])) { $html .= $v['class'] . $v['type']; } $html .= $v['function']; $args = array(); if (!empty($v['args'])) { foreach ($v['args'] as $arg) { if (is_null($arg)) $args[] = 'null'; elseif (is_array($arg)) $args[] = 'Array'; elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; elseif (is_int($arg) || is_double($arg)) $args[] = $arg; else { $arg = (string)$arg; $str = htmlspecialchars(substr($arg, 0, 16)); if (strlen($arg) > 16) $str .= '…'; $args[] = "'" . $str . "'"; } } } $html .= '(' . implode(', ',$args) . ')' . '' . (isset($v['file']) ? $v['file'] : 'unknown') . ':' . (isset($v['line']) ? $v['line'] : 'unknown') . '
' . ($k+1) . '{main} 
'; return $html; } public function toText() { $causes = array(); $this->getCauseMessage($causes); $causeMsg = ''; foreach ($causes as $i => $cause) { $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' . $cause['message'] . ' in ' . $cause['file'] . ' on line ' . $cause['line'] . "\n"; } return $causeMsg . $this->getTraceAsString(); } } ?> true, 'Phpsocket' => false, 'Http' => false, ); foreach($adapters as $adapter => $status) { if (!$status) { continue; } $class = 'pear2\HTTP\Request\Adapter\\'.$adapter; $request = new pear2\HTTP\Request($url,new $class); $response = $request->sendRequest(); echo "$adapter adapter\n"; var_dump($response->code); var_dump($response->headers); var_dump($response->cookies); var_dump(strlen($response->body)); } sendRequest(); var_dump($response->code); var_dump($response->headers); var_dump(strlen($response->body)); verb = 'HEAD'; $response = $request->sendRequest(); var_dump($response->code); var_dump($response->headers); var_dump(strlen($response->body)); body = array('test1'=>'value1','test2'=>'value2'); $response = $request->sendRequest(); var_dump($response->code); var_dump($response->headers); var_dump($response->body); _setupRequest(); return $this->_sendRequest(); } public function requestToFile($file) { $this->_setupRequest(); $this->fp = fopen($file,'w'); curl_setopt($this->curl,CURLOPT_FILE,$this->fp); return $this->_sendRequest(); } /** * @todo error checking * @implement put */ protected function _setupRequest() { $this->curl = curl_init($this->uri->url); // check error here // request timeout //curl_setopt($this->curl,CURLOPT_CONNECTTIMEOUT,$this->requestTimeout); curl_setopt($this->curl,CURLOPT_TIMEOUT,$this->requestTimeout); // progress callback if (count($this->_listeners) > 0) { curl_setopt($this->curl, CURLOPT_PROGRESSFUNCTION, array($this, 'progressCallback')); curl_setopt($this->curl, CURLOPT_NOPROGRESS, false); } // follow redirects ??? // curl_setopt($this->curl,CURLOPT_FOLLOWLOCATION,???); // set http version (currently we are only letting you force 1.0 otherwise we let curl auto determine switch(strtolower($this->httpVersion)) { case 'http/1.0': curl_setopt($this->curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_0); break; case 'http/1.1': default: curl_setopt($this->curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_NONE); break; } // http verb if (strtoupper($this->verb) == 'PUT') { throw new Exception("HTTP put not implmented for Curl yet"); } curl_setopt($this->curl,CURLOPT_CUSTOMREQUEST,$this->verb); // headers curl_setopt($this->curl,CURLOPT_HTTPHEADER,$this->headers); // general stuff curl_setopt($this->curl,CURLOPT_BINARYTRANSFER,true); curl_setopt($this->curl,CURLOPT_RETURNTRANSFER,true); if (!is_null($this->proxy)) { curl_setopt($this->curl, CURLOPT_PROXY, $this->proxy->url); } // setup a callback to handle header info curl_setopt($this->curl,CURLOPT_HEADERFUNCTION,array($this,'_headerCallback')); // post data if (!empty($this->body)) { curl_setopt($this->curl,CURLOPT_POSTFIELDS,$this->body); } } protected function _sendRequest() { $body = curl_exec($this->curl); $this->sentFilesize = false; if ($this->fp !== false) { fclose($this->fp); } $details = $this->uri->toArray(); $details['code'] = curl_getinfo($this->curl,CURLINFO_HTTP_CODE); //$details['httpVersion'] = $response->getHttpVersion(); $headers = new Request\Headers($this->headers); $cookies = array(); return new Request\Response($details, $body, $headers, $cookies); } protected function _headerCallback($curl,$data) { $this->processHeader(trim($data)); return strlen($data); } function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) { $code = curl_getinfo($this->curl, CURLINFO_HTTP_CODE); if ($code > 200) { return; } if (!$this->sentFilesize) { $this->sentFilesize = true; $this->_notify('connect'); $content_type = curl_getinfo($this->curl, CURLINFO_CONTENT_TYPE); if ($content_type) { $this->_notify('mime-type', $content_type); } $this->_notify('filesize', $dltotal); } $this->_notify('downloadprogress', $dlnow); } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ * pear2\HTTP\Request\Adapter\Filesystem::addDirectory( * '/var/www/html/pear2.php.net', * 'http://pear2.php.net/'); * * * @param string $dir A local directory filename * @param string $urlbase The base url to map this directory to * * @return void */ static function addDirectory($dir, $urlbase) { static::$requestMap[$urlbase] = realpath($dir); } /** * Send the request * * This function retrieves a file from the local filesystem which matches * the requested URL. If the uri does not match a urlbase set using the * addDirectory method, an exception is thrown. * * @throws Exception */ public function sendRequest() { $uri = $this->uri->url; $actualfile = false; foreach (static::$requestMap as $urlbase => $dir) { if (strpos($uri, $urlbase) === 0) { $actualfile = $dir . DIRECTORY_SEPARATOR . substr($uri, strlen($urlbase)); break; } } if (!$actualfile) { throw new Request\Exception('URL ' . $uri . ' is not in the request map, setup is needed'); } $details = $this->uri->toArray(); if (!file_exists($actualfile)) { $details['code'] = '404'; $body = ''; } else { $body = file_get_contents($actualfile); $details['code'] = '200'; } // $this->verb is GET/POST/etc. // $this->uri is pear2\HTTP\Request\Uri // $this->headers is array of headers // $this->body is request body $details['httpVersion'] = 'HTTP/1.1'; $cookies = array(); $headers = array(); if ($details['code'] == '200') { $headers['content-disposition'] = 'filename="' . basename($actualfile) . '"'; $headers['content-length'] = strlen($body); $headers['etag'] = md5($body); $headers['last-modified'] = date('Y-m-d H:i', filemtime($actualfile)); $info = pathinfo($actualfile); switch ($info['extension']) { case 'xml' : $headers['content-type'] = 'text/xml'; break; case 'txt' : $headers['content-type'] = 'text/plain'; break; default : $headers['content-type'] = 'application/octet-stream'; } } return new Request\Response($details, $body, $headers, $cookies); } } $this->requestTimeout, ); // if we have any listeners register an onprogress callback if (count($this->_listeners) > 0) { $options['onprogress'] = array($this,'_onprogress'); } $tmp = 'HTTP_METH_'.strtoupper($this->verb); if (defined($tmp)) { $method = constant($tmp); } else { $method = HTTP_METH_GET; } $this->request = $request = new \HttpRequest($this->uri->url, $method, $options); $request->setHeaders($this->headers); if ($this->body) { $request->setRawPostData($this->body); } $request->send(); $response = $request->getResponseMessage(); $body = $response->getBody(); $details = $this->uri->toArray(); $details['code'] = $request->getResponseCode(); $details['httpVersion'] = $response->getHttpVersion(); $headers = new Request\Headers($response->getHeaders()); $cookies = $request->getResponseCookies(); return new Request\Response($details, $body, $headers, $cookies); } /** * Progress handler maps callback progress to listeners * @todo implement progress callback * @todo this doesn't want to be part of the public api but has to be public to be called as a callback */ public function _onprogress($status) { $dltotal = $status['dltotal']; $dlnow = $status['dlnow']; // pecl http kind of sucks, no way to get the http response code until after the // callback completes... $this->_notify('filesize', $dltotal); $this->_notify('downloadprogress', $dlnow); } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ _handle = $handle; } public function readLine() { $line = ''; while(!$this->eof()) { $line .= @fgets($this->_handle, $this->lineLength); if (substr($line, -1) == "\n") { return rtrim($line, "\r\n"); } } return false; } public function read($size) { if ($this->eof()) { return false; } return @fread($this->_handle,$size); } public function write($payload) { return fwrite($this->_handle,$payload,strlen($payload)); } public function eof() { return feof($this->_handle); } } /** * A class which represents an Http Reponse * Handles parsing cookies and headers * * Based on PEAR HTTP_Response * * @version $Revision: 1.52 $ */ class Phpsocket extends Request\Adapter { /** * Used by _readChunked(): remaining length of the current chunk * @var string */ private $_chunkLength = 0; /** * Bytes left to read from message-body * @var null|int */ private $_toRead = null; /** * Raw Response to be parsed */ private $_stream; public function sendRequest() { $payload = $this->_buildHeaders($this->uri->path,$this->uri->host,$this->headers,strlen($this->body)); $payload .= $this->body; $this->body = ''; $errno = 0; $errstr = ''; $handle = @fsockopen($this->uri->host, $this->uri->port, $errno, $errstr, 30); if (!is_resource($handle)) { throw new Request\Exception("Couldn't connection to host using Phpsocket Adapter, fsockopen errors($errstr,$errno)"); } stream_set_timeout($handle,10); $this->_stream = new Phpsocket_Socket($handle); $this->_stream->write($payload); $this->parse(); $details['code'] = $this->code; $details['httpVersion'] = $this->httpVersion; $response = new Request\Response( $details,$this->body,new Request\Headers($this->headers),$this->cookies); return $response; } /** * Parse a HTTP response * * This extracts response code, headers, cookies and decodes body if it * was encoded in some way * * @access public * @param bool Whether to store response body in object property, set * this to false if downloading a LARGE file and using a Listener. * This is assumed to be true if body is gzip-encoded. * @param bool Whether the response can actually have a message-body. * Will be set to false for HEAD requests. * @throws Exception * @return boolean true on success */ public function parse($saveBody = true, $canHaveBody = true) { do { $line = $this->_stream->readLine(); $code = $this->parseResponseCode($line); $this->httpVersion = 'HTTP/' . $code['httpVersion']; $this->code = $code['code']; while ('' !== ($header = $this->_stream->readLine())) { $this->processHeader($header); } } while ($this->code == 100); // RFC 2616, section 4.4: // 1. Any response message which "MUST NOT" include a message-body ... // is always terminated by the first empty line after the header fields // 3. ... If a message is received with both a // Transfer-Encoding header field and a Content-Length header field, // the latter MUST be ignored. $canHaveBody = $canHaveBody && $this->code >= 200 && $this->code != 204 && $this->code != 304; // If response body is present, read it and decode $chunked = isset($this->headers['transfer-encoding']) && ('chunked' == $this->headers['transfer-encoding']); $gzipped = isset($this->headers['content-encoding']) && ('gzip' == $this->headers['content-encoding']); $hasBody = false; if ($canHaveBody && ($chunked || !isset($this->headers['content-length']) || 0 != $this->headers['content-length'])) { if ($chunked || !isset($this->headers['content-length'])) { $this->_toRead = null; } else { $this->_toRead = $this->headers['content-length']; } while (!$this->_stream->eof() && (is_null($this->_toRead) || $this->_toRead > 0)) { if ($chunked) { $data = $this->_readChunked(); } elseif (is_null($this->_toRead)) { $data = $this->_stream->read(4096); } else { $data = $this->_stream->read(min(4096, $this->_toRead)); $this->_toRead -= strlen($data); } if ($data == '') { break; } else { $hasBody = true; if ($saveBody || $gzipped) { $this->body .= $data; } } } } if ($hasBody) { // Uncompress the body if needed if ($gzipped) { $body = $this->_decodeGzip($this->body); // FIXME: PEAR::isError?!?!?! if (PEAR::isError($body)) { return $body; } $this->body = $body; } } return true; } /** * Read a part of response body encoded with chunked Transfer-Encoding * * @access private * @return string */ private function _readChunked() { // at start of the next chunk? if (0 == $this->_chunkLength) { $line = $this->_stream->readLine(); if (preg_match('/^([0-9a-f]+)/i', $line, $matches)) { $this->_chunkLength = hexdec($matches[1]); // Chunk with zero length indicates the end if (0 == $this->_chunkLength) { $this->_stream->readLine(); // make this an eof() return ''; } } else { return ''; } } $data = $this->_stream->read($this->_chunkLength); $this->_chunkLength -= strlen($data); if (0 == $this->_chunkLength) { $this->_stream->readLine(); // Trailing CRLF } return $data; } /** * Decodes the message-body encoded by gzip * * The real decoding work is done by gzinflate() built-in function, this * method only parses the header and checks data for compliance with * RFC 1952 * * @access private * @param string gzip-encoded data * @return string decoded data */ private function _decodeGzip($data) { $length = strlen($data); // If it doesn't look like gzip-encoded data, don't bother if ($length < 18 || strcmp(substr($data, 0, 2), "\x1f\x8b")) { return $data; } $method = ord(substr($data, 2, 1)); if ($method != 8) { throw new Request\Exception('_decodeGzip(): unknown compression method'); } $flags = ord(substr($data, 3, 1)); if ($flags & 224) { throw new Request\Exception('_decodeGzip(): reserved bits are set'); } // header is 10 bytes minimum. may be longer, though. $headerLength = 10; // extra fields, need to skip 'em if ($flags & 4) { if ($length - $headerLength - 2 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $extraLength = unpack('v', substr($data, 10, 2)); if ($length - $headerLength - 2 - $extraLength[1] < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $headerLength += $extraLength[1] + 2; } // file name, need to skip that if ($flags & 8) { if ($length - $headerLength - 1 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $filenameLength = strpos(substr($data, $headerLength), chr(0)); if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $headerLength += $filenameLength + 1; } // comment, need to skip that also if ($flags & 16) { if ($length - $headerLength - 1 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $commentLength = strpos(substr($data, $headerLength), chr(0)); if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $headerLength += $commentLength + 1; } // have a CRC for header. let's check if ($flags & 1) { if ($length - $headerLength - 2 < 8) { throw new Request\Exception('_decodeGzip(): data too short'); } $crcReal = 0xffff & crc32(substr($data, 0, $headerLength)); $crcStored = unpack('v', substr($data, $headerLength, 2)); if ($crcReal != $crcStored[1]) { throw new Request\Exception('_decodeGzip(): header CRC check failed'); } $headerLength += 2; } // unpacked data CRC and size at the end of encoded data $tmp = unpack('V2', substr($data, -8)); $dataCrc = $tmp[1]; $dataSize = $tmp[2]; // finally, call the gzinflate() function $unpacked = @gzinflate(substr($data, $headerLength, -8), $dataSize); if (false === $unpacked) { throw new Request\Exception('_decodeGzip(): gzinflate() call failed'); } elseif ($dataSize != strlen($unpacked)) { throw new Request\Exception('_decodeGzip(): data size check failed'); } elseif ($dataCrc != crc32($unpacked)) { throw new Request\Exception('_decodeGzip(): data CRC check failed'); } return $unpacked; } private function _buildHeaders($path, $host, $headers,$bodySize) { $httpRequest = "$this->verb $path $this->httpVersion\r\n"; $httpRequest .= "Host: $host\r\n"; foreach($headers as $key => $value) { $httpRequest .= "$key: $value\r\n"; } if ($bodySize > 0) { $httpRequest .= "Content-Length:".$bodySize."\r\n"; } $httpRequest .= "\r\n"; return $httpRequest; } } // End class PEAR2_HTTP_Response /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> proxy)) { $proxyurl = $this->proxy->url; } $info = array( $this->uri->protocol => array( 'method' => $this->verb, 'content' => $this->body, 'header' => $this->buildHeaderString(), 'proxy' => $proxyurl, 'ignore_errors' => true, 'max_redirects' => 3, ) ); // create context with proper junk $ctx = stream_context_create( $info ); if (count($this->_listeners)) { stream_context_set_params($ctx, array('notification' => array($this, 'streamNotifyCallback'))); } $fp = fopen($this->uri->url, 'rb', false, $ctx); if (!is_resource($fp)) { throw new Request\Exception('Url ' . $this->uri->url . ' could not be opened (PhpStream Adapter)'); } else { restore_error_handler(); } stream_set_timeout($fp, $this->requestTimeout); $body = stream_get_contents($fp); if ($body === false) { throw new Request\Exception( 'Url ' . $this->uri->url . ' did not return a response' ); } $meta = stream_get_meta_data($fp); fclose($fp); $headers = $meta['wrapper_data']; $details = $this->uri->toArray(); $tmp = $this->parseResponseCode($headers[0]); $details['code'] = $tmp['code']; $details['httpVersion'] = $tmp['httpVersion']; $cookies = array(); $this->headers = $this->cookies = array(); foreach($headers as $line) { $this->processHeader($line); } return new Request\Response( $details,$body,new Request\Headers($this->headers),$this->cookies); } /** * Build header String * * This method builds the header string * to be passed to the request. * * @return string $out The headers */ private function buildHeaderString() { $out = ''; foreach($this->headers as $header => $value) { $out .= "$header: $value\r\n"; } return $out; } /** * This has to be public to be used as a callback but its actually private */ public function _errorHandler($errno,$errstr) { $this->_phpErrorStr = $errstr; } public function streamNotifyCallback($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max) { switch($notification_code) { case STREAM_NOTIFY_RESOLVE: case STREAM_NOTIFY_AUTH_REQUIRED: case STREAM_NOTIFY_FAILURE: case STREAM_NOTIFY_AUTH_RESULT: /* Ignore */ break; case STREAM_NOTIFY_COMPLETED: $this->_notify('disconnect'); break; case STREAM_NOTIFY_REDIRECTED: $this->_notify('redirect', $message); break; case STREAM_NOTIFY_CONNECT: $this->_notify('connect'); break; case STREAM_NOTIFY_FILE_SIZE_IS: $this->_notify('filesize', $bytes_max); break; case STREAM_NOTIFY_MIME_TYPE_IS: $this->_notify('mime-type', $message); break; case STREAM_NOTIFY_PROGRESS: $this->_notify('downloadprogress', $bytes_transferred); break; } } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> Header value * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.5 * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.3 */ public $headers = array(); /** * Value to send as the body of the message, you need to handle the encoding * @var string * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.3 */ public $body; /** * How long to wait until a request times out * @float seconds */ public $requestTimeout = 100; /** * Full uri of the proxy server * @var pear2\HTTP\Request\Uri */ public $proxy = null; /** * HTTP Return code * @var string * @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html */ public $code = 0; /** * Listeners from the parent */ protected $_listeners = array(); /** * Parsed cookies * @var array */ public $cookies = array(); /** * @todo i don't like this approach */ public function setListeners($listeners) { $this->_listeners = $listeners; } /** * Send the specified request */ public function sendRequest() { } /** * Send a request storing the results to a file and return a response class with no body * * Base Adapter contains a non efficient baseline method */ public function requestToFile($file) { $response = $this->sendRequest(); file_put_contents($file,$response->body); unset($response->body); return $response; } protected function parseResponseCode($line) { if (sscanf($line, 'HTTP/%s %s', $http_version, $returncode) != 2) { throw new Request\Exception('Malformed response.'); } else { return array('code' => intval($returncode), 'httpVersion' => $http_version); } } /** * Processes the response header * * @access private * @param string HTTP header */ protected function processHeader($header) { if (strpos($header, ':') === false) { return; } list($headername, $headervalue) = explode(':', $header, 2); if (strstr($headername,'-')) { list($p1,$p2) = explode('-',$headername); $headername = ucfirst(strtolower($p1)).'-'.ucfirst(strtolower($p2)); } else { $headername = ucfirst($headername); } $headervalue = ltrim($headervalue); if ('set-cookie' != $headername) { if (isset($this->headers[$headername])) { $this->headers[$headername] .= ',' . $headervalue; } else { $this->headers[$headername] = $headervalue; } } else { $this->cookies[] = $this->parseCookie($headervalue); } } /** * Parse a Set-Cookie header to fill $cookies array * * @access private * @param string value of Set-Cookie header */ protected function parseCookie($headervalue) { $cookie = array( 'expires' => null, 'domain' => null, 'path' => null, 'secure' => false ); // Only a name=value pair if (!strpos($headervalue, ';')) { $pos = strpos($headervalue, '='); $cookie['name'] = trim(substr($headervalue, 0, $pos)); $cookie['value'] = trim(substr($headervalue, $pos + 1)); // Some optional parameters are supplied } else { $elements = explode(';', $headervalue); $pos = strpos($elements[0], '='); $cookie['name'] = trim(substr($elements[0], 0, $pos)); $cookie['value'] = trim(substr($elements[0], $pos + 1)); for ($i = 1; $i < count($elements); $i++) { if (false === strpos($elements[$i], '=')) { $elName = trim($elements[$i]); $elValue = null; } else { list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); } $elName = strtolower($elName); if ($elName == 'secure') { $cookie['secure'] = true; } elseif ($elName == 'expires') { $cookie['expires'] = str_replace('"', '', $elValue); } elseif ($elName == 'path' || $elName == 'domain') { $cookie[$elName] = urldecode($elValue); } else { $cookie[$elName] = $elValue; } } } return $cookie; } protected function _notify($event, $data = null) { if (!empty($this->_listeners)) { foreach (array_keys($this->_listeners) as $id) { $this->_listeners[$id]->update($this, $event, $data); } } } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ fields = $fields; } /** * Magic getter for object access */ public function __get($key) { if (is_null($this->camelCase)) { $this->camelCaseFields(); } if (isset($this->camelCase[$key])) { return $this->camelCase[$key]; } return null; } /** * Magic setter for object access * * @todo set $this->fields and $this->lowerCase */ public function __set($key,$value) { $this->camelCase[$key] = $value; } /** * Magic isset for object access */ public function __isset($key) { if (is_null($this->camelCase)) { $this->camelCaseFields(); } return isset($this->camelCase[$key]); } /** * Magic unset for object access */ public function __unset($key) { if (is_null($this->camelCase)) { $this->camelCaseFields(); } unset($this->camelCase[$key]); } /** * ArrayAccess Implementation */ public function offsetExists($key) { if (is_null($this->lowerCase)) { $this->lowerCaseFields(); } $key = strtolower($key); return isset($this->lowerCase[$key]); } /** * ArrayAccess Implementation */ public function offsetGet($key) { if (is_null($this->lowerCase)) { $this->lowerCaseFields(); } $key = strtolower($key); if (isset($this->lowerCase[$key])) { return $this->lowerCase[$key]; } return null; } /** * ArrayAccess Implementation */ public function offsetSet($key,$value) { $key = strtolower($key); $this->lowerCase[$key] = $value; } /** * ArrayAccess Implementation */ public function offsetUnset($key) { if (is_null($this->lowerCase)) { $this->lowerCaseFields(); } $key = strtolower($key); unset($this->lowerCase[$key]); } /** * Return the number of headers * Countable interface implmentation */ public function count() { return count($this->fields); } /** * Iterator Implmentation */ public function current() { return current($this->{$this->iterationStyle}); } /** * Iterator Implementation */ public function key() { return key($this->{$this->iterationStyle}); } /** * Iterator Implmentation */ public function next() { return next($this->{$this->iterationStyle}); } /** * Iterator Implmentation */ public function rewind() { if (is_null($this->{$this->iterationStyle})) { $m = $this->iterationStyle."Fields"; $this->$m(); } reset($this->{$this->iterationStyle}); } /** * Iterator Implmentation */ public function valid() { return (boolean) current($this->{$this->iterationStyle}); } /** * Make all keys lower case */ protected function lowerCaseFields() { $fields = array(); foreach($this->fields as $k => $v) { $fields[strtolower($k)] = $v; } $this->lowerCase = $fields; } /** * Make all keys camel case, removing dashes */ protected function camelCaseFields() { $fields = array(); foreach($this->fields as $k => $v) { $pieces = explode('-',$k); $pieces = array_map('ucfirst',$pieces); $fields[implode('',$pieces)] = $v; } $this->camelCase = $fields; } } * @copyright 2002-2007 Richard Heyes * @license http://opensource.org/licenses/bsd-license.php New BSD License */ /** * Listener for PEAR2_HTTP_Request and PEAR2_HTTP_Response objects * * This class implements the Observer part of a Subject-Observer * design pattern. * * @category HTTP * @package HTTP_Request * @author Alexey Borzov * @version Release: @package_version@ */ namespace pear2\HTTP\Request; class Listener { /** * A listener's identifier * * @var string */ private $_id; /** * A current log of the activities */ private $_log = array( 'notifications' => array(), 'extraData' => array(), ); /** * Constructor, sets the object's identifier * * @access public */ public function __construct() { $this->_id = md5(sha1('http_request_') . time()); } /** * Returns the listener's identifier * * @access public * @return string */ public function getId() { return $this->_id; } /** * This method is called when Listener is notified of an event * * @access public * @param object an object the listener is attached to Is that even used? * @param string Event name - connect|sentRequest|disconnect|gotHeaders|gzTick|tick|gotBody * @param mixed Additional data * @abstract */ public function update($subject, $event, $data = null) { $this->_log[$this->_id]['notifications'][] = "Notified of event: '$event'\n"; if ($data !== null) { $tmpMessage = "Additional data: "; $tmpMessage .= print_r($data, true); $this->_log[$this->_id]['extraData'][] = $tmpMessage; } } } ?> body * @see $this->headers * @see $this->cookies */ public function __construct($details, $body, $headers, $cookies) { foreach($details as $name => $value) { $this->$name = $value; } $this->body = $body; $this->headers = $headers; $this->cookies = $cookies; } /** * Return the body of the response */ public function __toString() { return $this->body; } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> 'uri', 'querystring' => 'query', 'anchor' => 'fragment', 'protocol' => 'scheme', ); protected $schemes = array( 'http' => 80, 'https'=> 443, ); public function __construct($uri) { $this->pieces = parse_url($uri); $this->pieces['uri'] = $uri; if (!isset($this->pieces['port'])) { if (isset($this->schemes[$this->pieces['scheme']])) { $this->pieces['port'] = $this->schemes[$this->pieces['scheme']]; } else { $this->pieces['port'] = 80; } } } public function __get($key) { if (isset($this->map[$key])) { $key = $this->map[$key]; } if (isset($this->pieces[$key])) { return $this->pieces[$key]; } return null; } public function toArray() { return $this->pieces; } } adapter->$name)) { return $this->adapter->$name; } } /** * Magic to set items that are actually stored in the adapter * * @param string $name name of var to set * @param mixed $value to give to var */ public function __set($name, $value) { switch($name) { case 'verb': $this->adapter->verb = strtoupper($value); break; case 'uri': case 'url': $this->adapter->uri = new Request\Uri($value); break; case 'body': case 'content': if (is_array($value)) { $this->adapter->body = http_build_query($value); $this->setHeader('Content-Type','application/x-www-form-urlencoded'); if ($this->adapter->verb == 'GET') { $this->adapter->verb = 'POST'; } } else { $this->adapter->body = $value; } break; case 'requestTimeout': $this->adapter->$name = (int)$value; break; case 'proxy': $this->adapter->$name = new Request\Uri($value); break; default: $this->adapter->$name = $value; break; } } /** * sets up the adapter * * @param string $url URL for this request * @param pear2\HTTP\Request\Adapter $instance The adapter to use */ public function __construct($url = null, $instance = null) { if (!is_null($instance) && $instance instanceof Request\Adapter) { $this->adapter = $instance; } elseif (extension_loaded('curl')) { $this->adapter = new Request\Adapter\Curl; } elseif (extension_loaded('http')) { $this->adapter = new Request\Adapter\Http; } elseif (ini_get('allow_url_fopen') == true) { $this->adapter = new Request\Adapter\Phpstream; } else { $this->adapter = new Request\Adapter\Phpsocket; } $this->adapter->setListeners($this->_listeners); if ($url) { $this->url = $url; } } /** * asks for a response class from the adapter * * @return pear2\HTTP\Request\Response */ public function sendRequest() { $response = $this->adapter->sendRequest(); return $response; } /** * Sends a request storing the output to a file * * @param string $file File to store too * @return pear2\HTTP\Request\Response with no body */ public function requestToFile($file) { $response = $this->adapter->requestToFile($file); return $response; } /** * Setter for request headers * * @see $this->adapter->headers */ public function setHeader($header, $value) { $this->adapter->headers[$header] = $value; } /** * Attach a listener * * This method adds a listener to the list of listeners that are * notified of the object's events. * * Events sent by the HTTP\Request Object * - 'connect' : On connection to server * - 'sentRequest' : After the request was sent to server * - 'disconnect' : Upon server disconnection * * Events sent by the HTTP\Response object * - 'gotHeaders' : After receiving response header * - 'tick' : On receiving part of response * - 'gzTick' : On receiving a gzip-encoded part * - 'gotBody' : Upon receiving body of the message * * * @param pear2\HTTP\Request\Listener $listener The listener object * @return boolean Whether object is a listener or not */ public function attach(Request\Listener $listener) { $this->_listeners[$listener->getId()] = $listener; $this->adapter->setListeners($this->_listeners); return true; } /** * Detach a listener * * This method will detach the listener that was set * to a request. * * @param pear2\HTTP\Request\Listener $listener The listener * @return bool true */ public function detach(Request\Listener $listener) { if (isset($this->_listeners[$listener->getId()])) { $this->_listeners[$listener->getId()] = null; } $this->adapter->setListeners($this->_listeners); return true; } /** * Notify * * This method notifies all registered listeners of * the event that just happened. * * @param string $event The event name * @param mixed $data Additional data * @see pear2\HTTP\Request->attach() * @return void */ protected function _notify($event, $data = null) { if (!empty($this->_listeners)) { foreach (array_keys($this->_listeners) as $id) { $this->_listeners[$id]->update($this, $event, $data); } } } /** * Get the class name of the adapter that is being used */ public function getAdapterName() { return get_class($this->adapter); } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ ?> --TEST-- pear2\HTTP\Request\Adapter\HTTP - Test of an HTTP Get request uses test001.html --SKIPIF-- --FILE-- --FILE-- --FILE-- --EXPECT-- string(5) "Test " bool(true) verb = 'GET'; $response = $http->sendRequest(); // make sure we got the correct body back var_dump($response->body); // check that the content-length header is correct if (isset($response->headers['Content-Length'])) { var_dump($response->headers['Content-Length'] == 5); } /* Expects Should Be: string(5) "Test " bool(true) */ verb = 'GET'; $response = $http->sendRequest(); // compare md5sum of the body if ('3e4c6173971d58992d2f87f7045619f8' === md5($response->body)) { echo "good\n"; } else { echo $response->body; } verb = 'POST'; $http->body = "Test\n"; $response = $http->sendRequest(); // make sure we got the correct body back var_dump($response->body); // check that the content-length header is correct if (isset($response->headers['Content-Length'])) { var_dump($response->headers['Content-Length'] == 5); } /* Expects Should Be: string(5) "Test " bool(true) */ dd if=/dev/zero of=2meg.bin bs=1024 count=2048 Test bXc 1DP.g$a L BPloduLDD$ \t230g 2, $"%"1"YM[MzyDDD0>E}E+@F 7hoD.XDDDa @sprW  _E|a1x PDDDb QDg A :`XL/^XEz:KDҞaq9W;qZ&m2/fX\}+C{^}C^=a?DonKW)DD$<z&sRc쉈aq#pO`p*ƺa1xLX|6y9}@2,z >>t䃠HWWmAk#|Tdm:ZD$P D("o6) b+DD$0b/.JcmAs=+"`XOl9@@!""q0'uGw.gH3,l{06}DҀah^?0CS695^?{ܖ. @0,}n@ؿ_wwaQFtD׈Z IKS1 /ƞ.g"8 /u3'(π|ۤb80'm J>ɤSGÀӉ1@V .Wm.\OjmbOŮL i!1hBtI 7=mt;5 0,23splӱằ.dUDԲx"]I媳HJ{6ٛW$a 0Z=Gҹ"" `XE"de:wBDC@^dF =D<`Xt~\Mz{'h&"""1D=h ""-ErG{?1 !+ #I8&!DE>*jsK?)#B$O bO\$/"D6Chפ3>3оI֍;Ă":m7O 9m7"fW=8ִ1~OF>~f8 0#K]Ym&K簤t6KK?2((DDI:ff8mbt8!9gLUVwpddʫ86yE!3,N" Y=k¾2 DG|y~T~56)׷A!"rbKKyiѨ z_}/w#ݯu[!iSfa,Ei&" [p?ٜ . Z7N Ʀ}rsŐ1&%\Q[ƚ݋)޽K(޳-VCe ѲQ;Z䶦Mti֛.йYozeH?xTٴ[BtkׂRH\8-#W,>ٛ2{4V%ԛbH(vQp=[ڻ2μ>!Yk(D$bObM% ypܿKjj^l{^7ukۆ㻝I/# O/GY jLM(D$ ;)㶑gWZR:7W>_CӮ"&A?;?{A8dV*7B!"eXDزq|ȯjo}ўݕۙ\$}[fls8t?nIѪygsT0Mj"HE7seR'5]'ë-ju2Yiu$mtd6SQS^56BMVb"8E0o#LqoNckynCT׉ o>X  QP8Q<~f%g!֪J^ZO/}ջuB[t3uߖ%{Єȴ//M{ .OJk&"[}!j-s䤙tJr5{Ìky{Ϳt"j/RY%ArqHF(?vRd8# cS  bx?Qwүֹf5SƦ,"lXtJrSsA|~h|t¡Mnr|8T7 mq,t@HH,τm7UwLDRaX4{1NOX}[ "jt`&C3IY 9 <;W"%+TvKJF" <4Fu \]BDVN$%m@ClvFO6>y^nv D#lMc5Tkk.! m~f"r "Xg@x9B#so l_#@B7x$!Ris)qS6 I)'ى.䰶=MosW;bFB%)ðlClnV6M <sx*k+t+"0tOdLDR% [sD6$R"34GEprN$/R[|ʽafn$2°8QŖi\0ziVZGy%|1QH*h|ȃ;ώyӊUUp{SSRbK0hX Ov%"kőD07]%ɒوBDB(z8nb7OpaĢ["[Yx>;K!]nu$+K#(Dė ~B}f}׉?8#uR(Dįnm1H*}&ZpΐEp^1, {xTЉ?0YV|i7qg_1S_fXMƁ"+Hx?aדn zu=hu^F"w\6nΤ~?~o|D?E {(DOz3_I㬦TΐWDV!"`XLL.:&7mKl-_%~wQ3,Z&iG@F=_O/#Ύc0 I*" xpcԉ=6]t$ 1'X8'd8wN? %ȃ)D$yB\괘aOYNKOh+XJRDL!"IaX\ FY'Rf!u0$aqXi gs\7of7u$%l62,~ @t8džu:+NDoKje$8 L1 u8Ǔ6D꙲Y8IUHpMOp9@2m'ulVlɓTӰ蘈)DS "|vGwGԻh:y2Qg “}jTԖu%%侈 fDWޭ־M$4bX 8@B޼'eNA?âQ+  < tx8+rc6.r8bX {;y3D"z7DP!3,rk#uhƓrZNIbX41ISR2o$h"<͢N!~ۖ򵮗ΚK E;q&p.q[&;ÝMZf"=â3p:d Auɫɞ 4] LۤΫ(DҔa8hp #OV"u<|:B$op J|5>I âp5~ r[wWr =~}{صU_VOIy")w\aGˁۏYɪ] X{l=L$Èy@t>0㉌u>]{ӵy_*jR{W'YsOaTV?~ tWW$Sy:C$JD$ʰ #_=""A3tdSOX霉ȡpB)"LtßǦywH<7J!385K=""yB'bq6p{)PDJ3 3,BDui&T$~tJDH?ݯ#Ѫq{6H&[}&juEK3mtp))giGVzH5GF5{^]fvR t&'/K-s2hwŐ0¡C z[~;Uu4 D/^ 3GTvy Fѭy_ep?.'sɿf> aQw?c瑓b 9-)ޭ$^a& Y\Yuhׅ\i.yV)ۗ34DUl{yA2,}l:Qp&JUSǞX"Z"8D0ng`.**y:sLgE+4(;&@i"E=WbRrZf2;>AD|nvV![k:۫c4qTR"YmLc^GݯHjLmE3n^Ngh6geY)~ r`A!=g21Kp(2}&-~<]  iIC1,^߶IG:9tQV־kcODR"rЊy@Hx to"{)ke)5k&D1% l4v=\`Bİ^]v&yxz:WmxnCڵWuLLĶ} 04a : z\vv(MD$i&W%~ DNuО-%l(⑹vR}mD %㠁R&=tdKw|Ɵf߄]."ePp)"(qaML㬼䏎b/V&mRt^&|vh8-r3$}vļ;ye_mDD:pʆHlSn;<0 e6NjȽ3eoN}=D̶MV$)"COb pu_''#7im[{g\ô/!"d<%C$w,sXxhBuGOLvUnGD T/$)" /,sp<8ͤHy^u=WS_ 9o&{Y â=/ í2ǿ{ 6]_AHCT+2!bXd*{<2񝤼HX95x&4VaMS%4 @D@"w0&)"ʼnxU.TƷ!bXŴț({iB۰ij.klӰ7S|OQ\zwTBV~힥 qkZ?Uȗ3,\7:_Cջrڡ!/"n[B~P2ZӲr2syt뚰/is%K lKV)?D~ p$4@)(IR6"㨏i~ok|11,ZQY~ѝ'wOSW6]÷r9nB4G!![>}վADRI+1,tZNF(ߌyFM$B 'Dע6G7ٛpDS"Gow' K>BOeH)DiM|ADD(D L'ex"l,dH:YMrZ{%5E$ڤSc-J8~h0YXDE!r9W7la,"ɒcX4K&u&0dj. u"g!r!yUdR|â;c~ZϚtO:8үO. u".eun˓-VH. u"^Ҭ덩b"lN9Ys> 5"l N䅈t?DD|$-f#qaGgѺq{b< [ӡDz89h^@l.[a+"~1.o8ۓl.[a+"~10$)Dܿrv?+k؊z"<\_J=/٢KY"? +؛T"ol.+pHsGh&"">uR_Dp6\orDDė"_fXdioғh&"">5İen<3|,,Ǜ)ج*"~Fq!H]C-Uu"WCڰ354DEaHzqOLCTDL!%Ñ{*DD:ߝ~Od99D*t9KD- jÙD4 c f7B3IبH(v'"")@3g!z:KDRf"1Ξ0p?C֋"n&s",npf"1NL$+i&STi&(D(DD$h&l&Ed(DDب$Dܧ"|P"5ծ7B7E$(DbHy^{"""1Bzh)"~Db|7iVSD.FEprrf"w V.i"6(b&Γ%ED\iԸ? gѼ{L!B4D"̃@\]S&u@Eb&/"")!pOhw#!BӉrf"""Hy^"7u"w 0i`{fY""1tKZ Z G)| Ҭ5()!ՃHri 2ۤ&h7DM%dg%_ج\`&гa"O!vYV ݥ{"""_|6i{ݕTw1=[a*"~ =Y"c N=hXCUDH3X,s1 诡*"~W,tr;mOKEDğ4E@C^Ûzf"_f}-)v8 U#DKZzz8Zkh&58B0C:p?ZKZ"3km3U>,!«0FCVDdiP(Dl~[QVFl9h؊_(Dx?! n1`B[|KJx0q"˂07Bd2ݓ u6ύEmEUֽ/""bmR9ۤ ,W3" d pg&2͓ƍy$B Ȑhݸ$B ]]Y~B, aI>.mX#Dl{4p\]#Of{3G76/rDchYCYD8kf}sz] ۤꤌk_ c~ gIAo`]Қ%KZ"pm7yh,c%4t.iHbt5DlR,0m틞4OAta-"KZӋ_ kI~:4ԋ)r Vj7OŝsZjxז&ӡH想Iv;4=C"'3W_ 9ہ灍N e6]Yuݠ["I-2"c<ŃnE6zȷINH];lgWDD͛ɪtDڂBr14P]Wɨճo,-˦5׹ z1`X$[{Z_M""_m2[ݐMvO8)!Rϟi=6ώyHDD^uAT2߬{qR` O+yJe3I9 w QI beO;+%ƒHӺbE~NK7ܙoq03ykn܁FIED M6:-~Aemu=4vm:;hG ӼQk xJ"n><vOVyģHZz6R7/{0є[U{\|FHzه8Zۤi9y;>;7#>M??7O>8/ӊ6񯓗L#H$v?d"%E4 8I9{v!QWØZ"=2.d7&oBz8)gqlFv9֍;xZ.g4Di1peI i_:)~tu Wgh$wL4F8)gW62a bDx[*Ո WmSBg"]eBwk,Ј MqkG?!*{qnr'"*zuwo"2 Ҋ-4vx^z-5DR&"jӾ'_/g}MvGʺ=R讓4DR- :DleV}[; c_fdS4DRόn8x_PL4rT6Fw~e0,.ue"86)QW<_6.jI7BNF#G& !`(3~ĺ?ՄOLֆF]JH]BTVpn#ߡg4DBdХL&5V%7 {Fytn[#N,-uC|R͸"sZ]ߋޭHHg5n`Ѷ"> 8S/.g}n`}Vy])=_]XDJ-p q&B$Y@Ӳp;'jW9O I;mgRq&memڷAǻ!~Y<9i&{j$,us)Z`I  q\ lۿ1OB F<쒏q`FHm RzقB휖zB2B?eYM޵0fD܏lmG꒔" vZC5Kϖ{#+؞簫r;+v"z6=)El'n7cdx:' PQ] eboPR[%ET+JXTPHW`Ӳ#u|-NqVw*aM1cd" "&Jɧ5SYʏLHK'LIVF{`np_`B6&;8oط>ޖS?MP^E+z&ÀFn780F ozX6]*9@"8Brkz{MF83mnƙM+Y\FȡYhUWx'p!y1FyˊY{!'8p(]eptq ls7OM")n/YV C @7۰o,g%VRf)ٿA#W.Vb6DJ28hF.cKZ6PIv>\DXm&""klQSP[<7\{1+63멄B.! 3` :˜ӒdYݐ8"  4v̕泭b#J(Iulڝ/bEl.+H_&W7$VC4ʇ] ظwJN7f5^].K()bkA!\Bn%,-qN'+#;) B j,NbVl֨tmr!9&DJX[P L\z[sY1sLgLh$imkո=^J&Y}zJŸJɒV!PRIJB;l o2k!M'mPm N{)JYkFٓU)BZW־ѝ2mRۗՄ1N0s[S#]92D7,-CO */064 '#ťRP/A0K()ÂB*w<3'8#l*[&m+_y H()B*>R;k#+##ۏHڻ$_ӂz]@` ԖkK+p_>DJYPH90nG0w{۳'&b,akI~D0,#nOz<ǽ[_tgڵ@'_Nvu?i&%%E-(R~>9o۶IGN9MYm&u 'V.u)D YKZ}wZ$VBM>VgDaxZȯF=RP缗g:( Bd"h&rJ8PP@oܷɫ[~tm' W3{T|I"d"69@t yO]{****MK":v.xmJ lVWBۤ <1^q y$amRV'Xܴ86L?EOg9TRDCIdyq5򿑝À6C =u361gt`qx>I7]dX <г@nC xv^N8Q xPBeE.pp_.|n8>4jmyM>&g "1,FO=%h;NQ72,L$:[i^z.q)D6*$i/" ćĂ6YNTB7pw||iIe qaE4PI%D??IFBDrequestToFile($temp); echo md5_file($temp)."\n"; unlink($temp); ?> --EXPECT-- b2d1236c286a3c0704224fe4105eca49 --TEST-- Test of object access for pear2\HTTP\Request\Headers --FILE-- 'text/html', 'ETag' => 'EADAF124D', 'content-length'=> '10' ); $headers = new pear2\HTTP\Request\Headers($in); var_dump($headers->ContentType); var_dump($headers->ETag); var_dump($headers->Etag); var_dump($headers->ContentLength); var_dump($headers->blah); var_dump(isset($headers->ContentType)); var_dump(isset($headers->blah)); unset($headers->ContentType); var_dump(isset($headers->ContentType)); ?> --EXPECT-- string(9) "text/html" string(9) "EADAF124D" NULL string(2) "10" NULL bool(true) bool(false) bool(false) --TEST-- Test of arrau access for pear2\HTTP\Request\Headers --FILE-- 'text/html', 'ETag' => 'EADAF124D', 'content-length'=> '10' ); $headers = new pear2\HTTP\Request\Headers($in); var_dump($headers['content-type']); var_dump($headers['Content-Type']); var_dump($headers['content-Type']); var_dump($headers['content-length']); var_dump($headers['ETag']); var_dump($headers['etag']); var_dump($headers['blah']); var_dump(isset($headers['content-type'])); var_dump(isset($headers['content-type'])); unset($headers['content-type']); var_dump(isset($headers['content-type'])); ?> --EXPECT-- string(9) "text/html" string(9) "text/html" string(9) "text/html" string(2) "10" string(9) "EADAF124D" string(9) "EADAF124D" NULL bool(true) bool(true) bool(false) --TEST-- Test of count functionality in pear2\HTTP\Request\Headers --FILE-- 'text/html', 'ETag' => 'EADAF124D', 'content-length'=> '10' ); $headers = new pear2\HTTP\Request\Headers($in); var_dump(count($headers)); ?> --EXPECT-- int(3) --TEST-- Test of iterator in pear2\HTTP\Request\Headers --FILE-- 'text/html', 'ETag' => 'EADAF124D', 'content-length'=> '10' ); $headers = new pear2\HTTP\Request\Headers($in); foreach($headers as $k => $v) { echo "$k: $v\n"; } $headers->iterationStyle = pear2\HTTP\Request\Headers::CAMEL_CASE; foreach($headers as $k => $v) { echo "$k: $v\n"; } $headers->iterationStyle = pear2\HTTP\Request\Headers::ORIGINAL_CASE; foreach($headers as $k => $v) { echo "$k: $v\n"; } ?> --EXPECT-- content-type: text/html etag: EADAF124D content-length: 10 ContentType: text/html ETag: EADAF124D ContentLength: 10 Content-Type: text/html ETag: EADAF124D content-length: 10 true 1 on yes false 0 off no * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ // uncomment this when package won't be in the SandBox anymore // $basedir = __DIR__ . '/../..'; $basedir = __DIR__ . '/../../..'; // Include PEAR2 autoload require_once $basedir . '/autoload.php'; // create the parser $parser = new PEAR2_Console_CommandLine(array( 'description' => 'zip given files using the php zip module.', 'version' => '1.0.0' )); // add an option to make the program verbose $parser->addOption('verbose', array( 'short_name' => '-v', 'long_name' => '--verbose', 'action' => 'StoreTrue', 'description' => 'turn on verbose output' )); // add an option to delete original files after zipping $parser->addOption('delete', array( 'short_name' => '-d', 'long_name' => '--delete', 'action' => 'StoreString', 'description' => 'delete original files after zip operation', 'choices' => array('foo', 'bar'), 'add_list_option' => true )); // add the files argument, the user can specify one or several files $parser->addArgument('files', array( 'multiple' => true, 'description' => 'list of files to zip separated by spaces' )); // add the zip file name argument $parser->addArgument('zipfile', array('description' => 'zip file name')); // run the parser try { $result = $parser->parse(); // write your program here... print_r($result->options); print_r($result->args); } catch (Exception $exc) { $parser->displayError($exc->getMessage()); } ?> * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ // uncomment this when package won't be in the SandBox anymore // $basedir = __DIR__ . '/../..'; $basedir = __DIR__ . '/../../..'; // Include PEAR2 autoload require_once $basedir . '/autoload.php'; // create the parser from xml file $xmlfile = __DIR__ . DIRECTORY_SEPARATOR . 'ex2.xml'; $parser = PEAR2_Console_CommandLine::fromXmlFile($xmlfile); // run the parser try { $result = $parser->parse(); // write your program here... print_r($result->options); print_r($result->args); } catch (Exception $exc) { $parser->displayError($exc->getMessage()); } ?> zip given files using the php zip module. 1.0.0 a list of files to zip together true path to the zip file to generate * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the Callback action. * * The result option array entry value is set to the return value of the * callback defined in the option. * * There are two steps to defining a callback option: * - define the option itself using the callback action * - write the callback; this is a function (or method) that takes five * arguments, as described below. * * All callbacks are called as follows: * * callable_func( * $value, // the value of the option * $option_instance, // the option instance * $result_instance, // the result instance * $parser_instance, // the parser instance * $params // an array of params as specified in the option * ); * * and *must* return the option value. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_Callback extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The value of the option * @param array $params An optional array of parameters * * @return string */ public function execute($value = false, $params = array()) { $this->setResult(call_user_func($this->option->callback, $value, $this->option, $this->result, $this->parser, $params)); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the Version action. * * The execute methode add 1 to the value of the result option array entry. * The value is incremented each time the option is found, for example * with an option defined like that: * * * $parser->addOption( * 'verbose', * array( * 'short_name' => '-v', * 'action' => 'Counter' * ) * ); * * If the user type: * * $ script.php -v -v -v * * or: * * $ script.php -vvv * * the verbose variable will be set to to 3. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_Counter extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An optional array of parameters * * @return string */ public function execute($value = false, $params = array()) { $result = $this->getResult(); if ($result === null) { $result = 0; } $this->setResult(++$result); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the Help action, a special action that displays the * help message, telling the user how to use the program. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_Help extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An optional array of parameters * * @return string */ public function execute($value = false, $params = array()) { return $this->parser->displayUsage(); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the Password action, a special action that allow the * user to specify the password on the commandline or to be prompted for * entering it. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_Password extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string */ public function execute($value = false, $params = array()) { $this->setResult(empty($value) ? $this->_promptPassword() : $value); } // }}} // _promptPassword() {{{ /** * Prompts the password to the user without echoing it. * * @return string * @todo not echo-ing the password does not work on windows is there a way * to make this work ? */ private function _promptPassword() { if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { fwrite(STDOUT, $this->parser->message_provider->get('PASSWORD_PROMPT_ECHO')); @flock(STDIN, LOCK_EX); $passwd = fgets(STDIN); @flock(STDIN, LOCK_UN); } else { fwrite(STDOUT, $this->parser->message_provider->get('PASSWORD_PROMPT')); // disable echoing system('stty -echo'); @flock(STDIN, LOCK_EX); $passwd = fgets(STDIN); @flock(STDIN, LOCK_UN); system('stty echo'); } return trim($passwd); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreArray action. * * The execute method appends the value of the option entered by the user to * the result option array entry. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreArray extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An optional array of parameters * * @return string */ public function execute($value = false, $params = array()) { $result = $this->getResult(); if (null === $result) { $result = array(); } $result[] = $value; $this->setResult($result); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreFalse action. * * The execute method store the boolean 'false' in the corrsponding result * option array entry (the value is true if the option is not present in the * command line entered by the user). * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreFalse extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string */ public function execute($value = false, $params = array()) { $this->setResult(false); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreFloat action. * * The execute method store the value of the option entered by the user as a * float in the result option array entry, if the value passed is not a float * an Exception is raised. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreFloat extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string * @throws PEAR2_Console_CommandLine_Exception */ public function execute($value=false, $params=array()) { if (!is_numeric($value)) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_TYPE_ERROR', array( 'name' => $this->option->name, 'type' => 'float', 'value' => $value ), $this->parser ); } $this->setResult((float)$value); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreInt action. * * The execute method store the value of the option entered by the user as an * integer in the result option array entry, if the value passed is not an * integer an Exception is raised. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreInt extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string * @throws PEAR2_Console_CommandLine_Exception */ public function execute($value = false, $params = array()) { if (!is_numeric($value)) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_TYPE_ERROR', array( 'name' => $this->option->name, 'type' => 'int', 'value' => $value ), $this->parser ); } $this->setResult((int)$value); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreString action. * * The execute method store the value of the option entered by the user as a * string in the result option array entry. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreString extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string */ public function execute($value = false, $params = array()) { $this->setResult((string)$value); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the StoreTrue action. * * The execute method store the boolean 'true' in the corrsponding result * option array entry (the value is false if the option is not present in the * command line entered by the user). * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_StoreTrue extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string */ public function execute($value = false, $params = array()) { $this->setResult(true); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent the Version action, a special action that displays the * version string of the program. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Action_Version extends PEAR2_Console_CommandLine_Action { // execute() {{{ /** * Executes the action with the value entered by the user. * * @param mixed $value The option value * @param array $params An array of optional parameters * * @return string */ public function execute($value = false, $params = array()) { return $this->parser->displayVersion(); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Lightweight class that manages messages used by PEAR2_Console_CommandLine package, * allowing the developper to customize these messages, for example to * internationalize a command line frontend. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_MessageProvider_Default implements PEAR2_Console_CommandLine_MessageProvider { // Properties {{{ /** * Associative array of messages * * @var array $messages */ protected $messages = array( 'OPTION_VALUE_REQUIRED' => 'Option "{$name}" requires a value.', 'OPTION_VALUE_UNEXPECTED' => 'Option "{$name}" does not expect a value (got "{$value}").', 'OPTION_VALUE_NOT_VALID' => 'Option "{$name}" must be one of the following: "{$choices}" (got "{$value}").', 'OPTION_VALUE_TYPE_ERROR' => 'Option "{$name}" requires a value of type {$type} (got "{$value}").', 'OPTION_AMBIGUOUS' => 'Ambiguous option "{$name}", can be one of the following: {$matches}.', 'OPTION_UNKNOWN' => 'Unknown option "{$name}".', 'ARGUMENT_REQUIRED' => 'You must provide at least {$argnum} argument{$plural}.', 'PROG_HELP_LINE' => 'Type "{$progname} --help" to get help.', 'PROG_VERSION_LINE' => '{$progname} version {$version}.', 'COMMAND_HELP_LINE' => 'Type "{$progname} --help" to get help on specific command.', 'USAGE_WORD' => 'Usage', 'OPTION_WORD' => 'Options', 'ARGUMENT_WORD' => 'Arguments', 'COMMAND_WORD' => 'Commands', 'PASSWORD_PROMPT' => 'Password: ', 'PASSWORD_PROMPT_ECHO' => 'Password (warning: will echo): ', 'INVALID_CUSTOM_INSTANCE' => 'Instance does not implement the required interface', 'LIST_OPTION_MESSAGE' => 'lists valid choices for option {$name}', 'LIST_DISPLAYED_MESSAGE' => 'Valid choices are: ', ); // }}} // get() {{{ /** * Retrieve the given string identifier corresponding message. * * @param string $code The string identifier of the message * @param array $vars An array of template variables * * @return string */ public function get($code, $vars = array()) { if (!isset($this->messages[$code])) { return 'UNKNOWN'; } $tmpkeys = array_keys($vars); $keys = array(); foreach ($tmpkeys as $key) { $keys[] = '{$' . $key . '}'; } return str_replace($keys, array_values($vars), $this->messages[$code]); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * PEAR2_Console_CommandLine default Outputter. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Outputter_Default implements PEAR2_Console_CommandLine_Outputter { // stdout() {{{ /** * Writes the message $msg to STDOUT. * * @param string $msg The message to output * * @return void */ public function stdout($msg) { if (defined('STDOUT')) { fwrite(STDOUT, $msg); } else { echo $msg; } } // }}} // stderr() {{{ /** * Writes the message $msg to STDERR. * * @param string $msg The message to output * * @return void */ public function stderr($msg) { if (defined('STDERR')) { fwrite(STDERR, $msg); } else { echo $msg; } } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ /** * PEAR2_Console_CommandLine default renderer. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Renderer_Default implements PEAR2_Console_CommandLine_Renderer { // Properties {{{ /** * Integer that define the max width of the help text. * * @var integer $line_width Line width */ public $line_width = 75; /** * Integer that define the max width of the help text. * * @var integer $line_width Line width */ public $options_on_different_lines = false; /** * An instance of PEAR2_Console_CommandLine. * * @var PEAR2_Console_CommandLine $parser The parser */ public $parser = false; // }}} // __construct() {{{ /** * Constructor. * * @param object $parser A PEAR2_Console_CommandLine instance * * @return void */ public function __construct($parser = false) { $this->parser = $parser; } // }}} // usage() {{{ /** * Returns the full usage message. * * @return string The usage message */ public function usage() { $ret = ''; if (!empty($this->parser->description)) { $ret .= $this->description() . "\n\n"; } $ret .= $this->usageLine() . "\n"; if (count($this->parser->commands) > 0) { $ret .= $this->commandUsageLine() . "\n"; } if (count($this->parser->options) > 0) { $ret .= "\n" . $this->optionList() . "\n"; } if (count($this->parser->args) > 0) { $ret .= "\n" . $this->argumentList() . "\n"; } if (count($this->parser->commands) > 0) { $ret .= "\n" . $this->commandList() . "\n"; } $ret .= "\n"; return $ret; } // }}} // error() {{{ /** * Returns a formatted error message. * * @param string $error The error message to format * * @return string The error string */ public function error($error) { $ret = 'Error: ' . $error . "\n"; if ($this->parser->add_help_option) { $name = $this->name(); $ret .= $this->wrap($this->parser->message_provider->get('PROG_HELP_LINE', array('progname' => $name))) . "\n"; if (count($this->parser->commands) > 0) { $ret .= $this->wrap($this->parser->message_provider->get('COMMAND_HELP_LINE', array('progname' => $name))) . "\n"; } } return $ret; } // }}} // version() {{{ /** * Returns the program version string. * * @return string The version string */ public function version() { return $this->parser->message_provider->get('PROG_VERSION_LINE', array( 'progname' => $this->name(), 'version' => $this->parser->version )) . "\n"; } // }}} // name() {{{ /** * Returns the full name of the program or the sub command * * @return string The name of the program */ protected function name() { $name = ''; $parent = $this->parser->parent; while ($parent) { $name .= $parent->name . ' '; if (count($parent->options) > 0) { $name .= '[' . strtolower($this->parser->message_provider->get('OPTION_WORD', array('plural' => 's'))) . '] '; } $parent = $parent->parent; } $name .= $this->parser->name; return $this->wrap($name); } // }}} // description() {{{ /** * Returns the command line description message. * * @return string The description message */ protected function description() { return $this->wrap($this->parser->description); } // }}} // usageLine() {{{ /** * Returns the command line usage message * * @return string the usage message */ protected function usageLine() { $usage = $this->parser->message_provider->get('USAGE_WORD') . ":\n"; $ret = $usage . ' ' . $this->name(); if (count($this->parser->options) > 0) { $ret .= ' [' . strtolower($this->parser->message_provider->get('OPTION_WORD')) . ']'; } if (count($this->parser->args) > 0) { foreach ($this->parser->args as $name=>$arg) { $ret .= ' <' . $arg->help_name . ($arg->multiple?'...':'') . '>'; } } return $this->columnWrap($ret, 2); } // }}} // commandUsageLine() {{{ /** * Returns the command line usage message for subcommands. * * @return string The usage line */ protected function commandUsageLine() { if (count($this->parser->commands) == 0) { return ''; } $ret = ' ' . $this->name(); if (count($this->parser->options) > 0) { $ret .= ' [' . strtolower($this->parser->message_provider->get('OPTION_WORD')) . ']'; } //XXX $ret .= " [options] [args]"; return $this->columnWrap($ret, 2); } // }}} // argumentList() {{{ /** * Render the arguments list that will be displayed to the user, you can * override this method if you want to change the look of the list. * * @return string The formatted argument list */ protected function argumentList() { $col = 0; $args = array(); foreach ($this->parser->args as $arg) { $argstr = ' ' . $arg->toString(); $args[] = array($argstr, $arg->description); $ln = strlen($argstr); if ($col < $ln) { $col = $ln; } } $ret = $this->parser->message_provider->get('ARGUMENT_WORD') . ":"; foreach ($args as $arg) { $text = str_pad($arg[0], $col) . ' ' . $arg[1]; $ret .= "\n" . $this->columnWrap($text, $col+2); } return $ret; } // }}} // optionList() {{{ /** * Render the options list that will be displayed to the user, you can * override this method if you want to change the look of the list. * * @return string The formatted option list */ protected function optionList() { $col = 0; $options = array(); foreach ($this->parser->options as $option) { $delim = $this->options_on_different_lines ? "\n" : ', '; $optstr = $option->toString($delim); $lines = explode("\n", $optstr); $lines[0] = ' ' . $lines[0]; if (count($lines) > 1) { $lines[1] = ' ' . $lines[1]; $ln = strlen($lines[1]); } else { $ln = strlen($lines[0]); } $options[] = array($lines, $option->description); if ($col < $ln) { $col = $ln; } } $ret = $this->parser->message_provider->get('OPTION_WORD') . ":"; foreach ($options as $option) { if (count($option[0]) > 1) { $text = str_pad($option[0][1], $col) . ' ' . $option[1]; $pre = $option[0][0] . "\n"; } else { $text = str_pad($option[0][0], $col) . ' ' . $option[1]; $pre = ''; } $ret .= "\n" . $pre . $this->columnWrap($text, $col+2); } return $ret; } // }}} // commandList() {{{ /** * Render the command list that will be displayed to the user, you can * override this method if you want to change the look of the list. * * @return string The formatted subcommand list */ protected function commandList() { $commands = array(); $col = 0; foreach ($this->parser->commands as $cmdname=>$command) { $cmdname = ' ' . $cmdname; $commands[] = array($cmdname, $command->description, $command->aliases); $ln = strlen($cmdname); if ($col < $ln) { $col = $ln; } } $ret = $this->parser->message_provider->get('COMMAND_WORD') . ":"; foreach ($commands as $command) { $text = str_pad($command[0], $col) . ' ' . $command[1]; if ($aliasesCount = count($command[2])) { $pad = ''; $text .= ' ('; $text .= $aliasesCount > 1 ? 'aliases: ' : 'alias: '; foreach ($command[2] as $alias) { $text .= $pad . $alias; $pad = ', '; } $text .= ')'; } $ret .= "\n" . $this->columnWrap($text, $col+2); } return $ret; } // }}} // wrap() {{{ /** * Wraps the text passed to the method. * * @param string $text The text to wrap * @param int $lw The column width (defaults to line_width property) * * @return string The wrapped text */ protected function wrap($text, $lw=null) { if ($this->line_width > 0) { if ($lw === null) { $lw = $this->line_width; } return wordwrap($text, $lw, "\n", false); } return $text; } // }}} // columnWrap() {{{ /** * Wraps the text passed to the method at the specified width. * * @param string $text The text to wrap * @param int $cw The wrap width * * @return string The wrapped text */ protected function columnWrap($text, $cw) { $tokens = explode("\n", $this->wrap($text)); $ret = $tokens[0]; $chunks = $this->wrap(trim(substr($text, strlen($ret))), $this->line_width - $cw); $tokens = explode("\n", $chunks); foreach ($tokens as $token) { if (!empty($token)) { $ret .= "\n" . str_repeat(' ', $cw) . $token; } } return $ret; } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent an option action. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ abstract class PEAR2_Console_CommandLine_Action { // Properties {{{ /** * A reference to the result instance. * * @var PEAR2_Console_CommandLine_Result $result The result instance */ protected $result; /** * A reference to the option instance. * * @var PEAR2_Console_CommandLine_Option $option The action option */ protected $option; /** * A reference to the parser instance. * * @var PEAR2_Console_CommandLine $parser The parser */ protected $parser; // }}} // __construct() {{{ /** * Constructor * * @param PEAR2_Console_CommandLine_Result $result The result instance * @param PEAR2_Console_CommandLine_Option $option The action option * @param PEAR2_Console_CommandLine $parser The current parser * * @return void */ public function __construct($result, $option, $parser) { $this->result = $result; $this->option = $option; $this->parser = $parser; } // }}} // getResult() {{{ /** * Convenience method to retrieve the value of result->options[name]. * * @return mixed The result value or null */ public function getResult() { if (isset($this->result->options[$this->option->name])) { return $this->result->options[$this->option->name]; } return null; } // }}} // setResult() {{{ /** * Convenience method to assign the result->options[name] value. * * @param mixed $result The result value * * @return void */ public function setResult($result) { $this->result->options[$this->option->name] = $result; } // }}} // execute() {{{ /** * Executes the action with the value entered by the user. * All children actions must implement this method. * * @param mixed $value The option value * @param array $params An optional array of parameters * * @return string */ abstract public function execute($value = false, $params = array()); // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent a command line argument. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Argument extends PEAR2_Console_CommandLine_Element { // Public properties {{{ /** * Setting this to true will tell the parser that the argument expects more * than one argument and that argument values should be stored in an array. * * @var boolean $multiple Whether the argument expects multiple values */ public $multiple = false; /** * Setting this to true will tell the parser that the argument is optional * and can be ommited. * Note that it is not a good practice to make arguments optional, it is * the role of the options to be optional, by essence. * * @var boolean $optional Whether the argument is optional or not. */ public $optional = false; // }}} // validate() {{{ /** * Validates the argument instance. * * @return void * @throws PEAR2_Console_CommandLine_Exception * @todo use exceptions */ public function validate() { // check if the argument name is valid if (!preg_match('/^[a-zA-Z_\x7f-\xff]+[a-zA-Z0-9_\x7f-\xff]*$/', $this->name)) { PEAR2_Console_CommandLine::triggerError( 'argument_bad_name', E_USER_ERROR, array('{$name}' => $this->name) ); } parent::validate(); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent a command with option and arguments. * * This class exist just to clarify the interface but at the moment it is * strictly identical to PEAR2_Console_CommandLine class, it could change in the * future though. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Command extends PEAR2_Console_CommandLine { // Public properties {{{ /** * An array of aliases for the subcommand. * * @var array $aliases Aliases for the subcommand. */ public $aliases = array(); // }}} // __construct() {{{ /** * Constructor. * * @param array $params An optional array of parameters * * @return void */ public function __construct($params = array()) { if (isset($params['aliases'])) { $this->aliases = $params['aliases']; } parent::__construct($params); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent a command line element (an option, or an argument). * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ abstract class PEAR2_Console_CommandLine_Element { // Public properties {{{ /** * The element name. * * @var string $name Element name */ public $name; /** * The name of variable displayed in the usage message, if no set it * defaults to the "name" property. * * @var string $help_name Element "help" variable name */ public $help_name; /** * The element description. * * @var string $description Element description */ public $description; // }}} // __construct() {{{ /** * Constructor. * * @param string $name The name of the element * @param array $params An optional array of parameters * * @return void */ public function __construct($name = null, $params = array()) { $this->name = $name; foreach ($params as $attr => $value) { if (property_exists($this, $attr)) { $this->$attr = $value; } } } // }}} // toString() {{{ /** * Returns the string representation of the element. * * @return string The string representation of the element * @todo use __toString() instead */ public function toString() { return $this->help_name; } // }}} // validate() {{{ /** * Validates the element instance and set it's default values. * * @return void * @throws PEAR2_Console_CommandLine_Exception */ public function validate() { // if no help_name passed, default to name if ($this->help_name == null) { $this->help_name = $this->name; } } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class for exceptions raised by the PEAR2_Console_CommandLine package. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Exception extends \pear2\Exception { // Codes constants {{{ /**#@+ * Exception code constants. */ const OPTION_VALUE_REQUIRED = 1; const OPTION_VALUE_UNEXPECTED = 2; const OPTION_VALUE_TYPE_ERROR = 3; const OPTION_UNKNOWN = 4; const ARGUMENT_REQUIRED = 5; /**#@-*/ // }}} // factory() {{{ /** * Convenience method that builds the exception with the array of params by * calling the message provider class. * * @param string $code The string identifier of the exception * @param array $params Array of template vars/values * @param PEAR2_Console_CommandLine $parser An instance of the parser * * @return PEAR2_Console_CommandLine_Exception The exception instance */ public static function factory($code, $params, $parser) { $msg = $parser->message_provider->get($code, $params); $const = 'PEAR2_Console_CommandLine_Exception::' . $code; $code = defined($const) ? constant($const) : 0; return new PEAR2_Console_CommandLine_Exception($msg, $code); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Message providers common interface, all message providers must implement * this interface. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ interface PEAR2_Console_CommandLine_MessageProvider { // get() {{{ /** * Retrieves the given string identifier corresponding message. * For a list of identifiers please see the provided default message * provider. * * @param string $code The string identifier of the message * @param array $vars An array of template variables * * @return string * @see PEAR2_Console_CommandLine_MessageProvider_Default */ public function get($code, $vars=array()); // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Class that represent a commandline option. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Option extends PEAR2_Console_CommandLine_Element { // Public properties {{{ /** * The option short name (ex: -v). * * @var string $short_name Short name of the option */ public $short_name; /** * The option long name (ex: --verbose). * * @var string $long_name Long name of the option */ public $long_name; /** * The option action, defaults to "StoreString". * * @var string $action Option action */ public $action = 'StoreString'; /** * The default value of the option if not provided on the command line. * * @var mixed $default Default value of the option. */ public $default; /** * An array of possible values for the option if this array is not empty * and the value passed is not in the array an exception is raised. * This only make sense for actions that accept values of course. * * @var array $choices Valid choices for the option */ public $choices = array(); /** * The callback function (or method) to call for an action of type * Callback, this can be any callable supported by the php function * call_user_func. * * Example: * * * $parser->addOption('myoption', array( * 'short_name' => '-m', * 'long_name' => '--myoption', * 'action' => 'Callback', * 'callback' => 'myCallbackFunction' * )); * * * @var callable $callback The option callback */ public $callback; /** * An associative array of additional params to pass to the class * corresponding to the action, this array will also be passed to the * callback defined for an action of type Callback, Example: * * * // for a custom action * $parser->addOption('myoption', array( * 'short_name' => '-m', * 'long_name' => '--myoption', * 'action' => 'MyCustomAction', * 'action_params' => array('foo'=>true, 'bar'=>false) * )); * * // if the user type: * // $ -m spam * // in your MyCustomAction class the execute() method will be called * // with the value 'spam' as first parameter and * // array('foo'=>true, 'bar'=>false) as second parameter * * * @var array $action_params Additional parameters to pass to the action */ public $action_params = array(); /** * For options that expect an argument, this property tells the parser if * the option argument is optional and can be ommited. * * @var bool $argumentOptional Whether the option arg is optional or not */ public $argument_optional = false; /** * For options that uses the "choice" property only. * Adds a --list- option to the parser that displays the list of * choices for the option. * * @var bool $add_list_option Whether to add a list option or not */ public $add_list_option = false; // }}} // __construct() {{{ /** * Constructor. * * @param string $name The name of the option * @param array $params An optional array of parameters * * @return void */ public function __construct($name = null, $params = array()) { parent::__construct($name, $params); if ($this->action == 'Password') { // special case for Password action, password can be passed to the // commandline or prompted by the parser $this->argument_optional = true; } } // }}} // toString() {{{ /** * Returns the string representation of the option. * * @param string $delim Delimiter to use between short and long option * * @return string The string representation of the option * @todo use __toString() instead */ public function toString($delim = ", ") { $ret = ''; $padding = ''; if ($this->short_name != null) { $ret .= $this->short_name; if ($this->expectsArgument()) { $ret .= ' ' . $this->help_name; } $padding = $delim; } if ($this->long_name != null) { $ret .= $padding . $this->long_name; if ($this->expectsArgument()) { $ret .= '=' . $this->help_name; } } return $ret; } // }}} // expectsArgument() {{{ /** * Returns true if the option requires one or more argument and false * otherwise. * * @return bool Whether the option expects an argument or not */ public function expectsArgument() { if ($this->action == 'StoreTrue' || $this->action == 'StoreFalse' || $this->action == 'Help' || $this->action == 'Version' || $this->action == 'Counter' || $this->action == 'List') { return false; } return true; } // }}} // dispatchAction() {{{ /** * Formats the value $value according to the action of the option and * updates the passed PEAR2_Console_CommandLine_Result object. * * @param mixed $value The value to format * @param PEAR2_Console_CommandLine_Result $result The result instance * @param PEAR2_Console_CommandLine $parser The parser instance * * @return void * @throws PEAR2_Console_CommandLine_Exception */ public function dispatchAction($value, $result, $parser) { // check value is in option choices if (!empty($this->choices) && !in_array($value, $this->choices)) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_NOT_VALID', array( 'name' => $this->name, 'choices' => implode('", "', $this->choices), 'value' => $value, ), $parser ); } $actionInfo = PEAR2_Console_CommandLine::$actions[$this->action]; if (true === $actionInfo[1]) { // we have a "builtin" action $tokens = explode('_', $actionInfo[0]); } $clsname = $actionInfo[0]; $action = new $clsname($result, $this, $parser); $action->execute($value, $this->action_params); } // }}} // validate() {{{ /** * Validates the option instance. * * @return void * @throws PEAR2_Console_CommandLine_Exception * @todo use exceptions instead */ public function validate() { // check if the option name is valid if (!preg_match('/^[a-zA-Z_\x7f-\xff]+[a-zA-Z0-9_\x7f-\xff]*$/', $this->name)) { PEAR2_Console_CommandLine::triggerError('option_bad_name', E_USER_ERROR, array('{$name}' => $this->name)); } // call the parent validate method parent::validate(); // a short_name or a long_name must be provided if ($this->short_name == null && $this->long_name == null) { PEAR2_Console_CommandLine::triggerError('option_long_and_short_name_missing', E_USER_ERROR, array('{$name}' => $this->name)); } // check if the option short_name is valid if ($this->short_name != null && !(preg_match('/^\-[a-zA-Z]{1}$/', $this->short_name))) { PEAR2_Console_CommandLine::triggerError('option_bad_short_name', E_USER_ERROR, array( '{$name}' => $this->name, '{$short_name}' => $this->short_name )); } // check if the option long_name is valid if ($this->long_name != null && !preg_match('/^\-\-[a-zA-Z]+[a-zA-Z0-9_\-]*$/', $this->long_name)) { PEAR2_Console_CommandLine::triggerError('option_bad_long_name', E_USER_ERROR, array( '{$name}' => $this->name, '{$long_name}' => $this->long_name )); } // check if we have a valid action if (!is_string($this->action)) { PEAR2_Console_CommandLine::triggerError('option_bad_action', E_USER_ERROR, array('{$name}' => $this->name)); } if (!isset(PEAR2_Console_CommandLine::$actions[$this->action])) { PEAR2_Console_CommandLine::triggerError('option_unregistered_action', E_USER_ERROR, array( '{$action}' => $this->action, '{$name}' => $this->name )); } // if the action is a callback, check that we have a valid callback if ($this->action == 'Callback' && !is_callable($this->callback)) { PEAR2_Console_CommandLine::triggerError('option_invalid_callback', E_USER_ERROR, array('{$name}' => $this->name)); } } // }}} // setDefaults() {{{ /** * Set the default value according to the configured action. * * Note that for backward compatibility issues this method is only called * when the 'force_options_defaults' is set to true, it will become the * default behaviour in the next major release of PEAR2_Console_CommandLine. * * @return void */ public function setDefaults() { if ($this->default !== null) { // already set return; } switch ($this->action) { case 'Counter': case 'StoreInt': $this->default = 0; break; case 'StoreFloat': $this->default = 0.0; break; case 'StoreArray': $this->default = array(); break; case 'StoreTrue': $this->default = false; break; case 'StoreFalse': $this->default = true; break; default: return; } } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Outputters common interface, all outputters must implement this interface. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ interface PEAR2_Console_CommandLine_Outputter { // stdout() {{{ /** * Processes the output for a message that should be displayed on STDOUT. * * @param string $msg The message to output * * @return void */ public function stdout($msg); // }}} // stderr() {{{ /** * Processes the output for a message that should be displayed on STDERR. * * @param string $msg The message to output * * @return void */ public function stderr($msg); // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Renderers common interface, all renderers must implement this interface. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ interface PEAR2_Console_CommandLine_Renderer { // usage() {{{ /** * Returns the full usage message. * * @return string The usage message */ public function usage(); // }}} // error() {{{ /** * Returns a formatted error message. * * @param string $error The error message to format * * @return string The error string */ public function error($error); // }}} // version() {{{ /** * Returns the program version string. * * @return string The version string */ public function version(); // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * A lightweight class to store the result of the command line parsing. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_Result { // Public properties {{{ /** * The result options associative array. * Key is the name of the option and value its value. * * @var array $options Result options array */ public $options = array(); /** * The result arguments array. * * @var array $args Result arguments array */ public $args = array(); /** * Name of the command invoked by the user, false if no command invoked. * * @var string $command_name Result command name */ public $command_name = false; /** * A result instance for the subcommand. * * @var PEAR2_Console_CommandLine_Result $command Result instance for the subcommand */ public $command = false; // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @filesource */ /** * Parser for command line xml definitions. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ class PEAR2_Console_CommandLine_XmlParser { // parse() {{{ /** * Parses the given xml definition file and returns a * PEAR2_Console_CommandLine instance constructed with the xml data. * * @param string $xmlfile The xml file to parse * * @return PEAR2_Console_CommandLine A parser instance */ public static function parse($xmlfile) { if (!is_readable($xmlfile)) { PEAR2_Console_CommandLine::triggerError('invalid_xml_file', E_USER_ERROR, array('{$file}' => $xmlfile)); } $doc = new DomDocument(); $doc->load($xmlfile); self::validate($doc); $nodes = $doc->getElementsByTagName('command'); $root = $nodes->item(0); return self::_parseCommandNode($root, true); } // }}} // parseString() {{{ /** * Parses the given xml definition string and returns a * PEAR2_Console_CommandLine instance constructed with the xml data. * * @param string $xmlstr The xml string to parse * * @return PEAR2_Console_CommandLine A parser instance */ public static function parseString($xmlstr) { $doc = new DomDocument(); $doc->loadXml($xmlstr); self::validate($doc); $nodes = $doc->getElementsByTagName('command'); $root = $nodes->item(0); return self::_parseCommandNode($root, true); } // }}} // validate() {{{ /** * Validates the xml definition using Relax NG. * * @param DomDocument $doc The document to validate * * @return boolean Whether the xml data is valid or not. * @throws PEAR2_Console_CommandLine_Exception * @todo use exceptions only */ public static function validate($doc) { $rngfile = '../../../data/pear2.php.net/PEAR2_Console_CommandLine/xmlschema.rng'; if (!is_file($rngfile)) { $rngfile = __DIR__ . '/../../../data/xmlschema.rng'; } if (!is_readable($rngfile)) { PEAR2_Console_CommandLine::triggerError( 'invalid_xml_file', E_USER_ERROR, array('{$file}' => $rngfile) ); } return $doc->relaxNGValidate($rngfile); } // }}} // _parseCommandNode() {{{ /** * Parses the root command node or a command node and return the * constructed PEAR2_Console_CommandLine or PEAR2_Console_CommandLine_Command * instance. * * @param DomDocumentNode $node The node to parse * @param bool $isRootNode Whether it is a root node or not * * @return mixed PEAR2_Console_CommandLine or PEAR2_Console_CommandLine_Command */ private static function _parseCommandNode($node, $isRootNode = false) { if ($isRootNode) { $obj = new PEAR2_Console_CommandLine(); } else { $obj = new PEAR2_Console_CommandLine_Command(); } foreach ($node->childNodes as $cNode) { $cNodeName = $cNode->nodeName; switch ($cNodeName) { case 'name': case 'description': case 'version': $obj->$cNodeName = trim($cNode->nodeValue); break; case 'add_help_option': case 'add_version_option': case 'force_posix': $obj->$cNodeName = self::_bool(trim($cNode->nodeValue)); break; case 'option': $obj->addOption(self::_parseOptionNode($cNode)); break; case 'argument': $obj->addArgument(self::_parseArgumentNode($cNode)); break; case 'command': $obj->addCommand(self::_parseCommandNode($cNode)); break; case 'aliases': if (!$isRootNode) { foreach ($cNode->childNodes as $subChildNode) { if ($subChildNode->nodeName == 'alias') { $obj->aliases[] = trim($subChildNode->nodeValue); } } } break; default: break; } } return $obj; } // }}} // _parseOptionNode() {{{ /** * Parses an option node and returns the constructed * PEAR2_Console_CommandLine_Option instance. * * @param DomDocumentNode $node The node to parse * * @return PEAR2_Console_CommandLine_Option The built option */ private static function _parseOptionNode($node) { $obj = new PEAR2_Console_CommandLine_Option($node->getAttribute('name')); foreach ($node->childNodes as $cNode) { $cNodeName = $cNode->nodeName; if ($cNodeName == 'choices') { foreach ($cNode->childNodes as $subChildNode) { if ($subChildNode->nodeName == 'choice') { $obj->choices[] = trim($subChildNode->nodeValue); } } } elseif (property_exists($obj, $cNodeName)) { $obj->$cNodeName = trim($cNode->nodeValue); } } if ($obj->action == 'Password') { $obj->argument_optional = true; } return $obj; } // }}} // _parseArgumentNode() {{{ /** * Parses an argument node and returns the constructed * PEAR2_Console_CommandLine_Argument instance. * * @param DomDocumentNode $node The node to parse * * @return PEAR2_Console_CommandLine_Argument The built argument */ private static function _parseArgumentNode($node) { $obj = new PEAR2_Console_CommandLine_Argument($node->getAttribute('name')); foreach ($node->childNodes as $cNode) { $cNodeName = $cNode->nodeName; switch ($cNodeName) { case 'description': case 'help_name': case 'default': $obj->$cNodeName = trim($cNode->nodeValue); break; case 'multiple': $obj->multiple = self::_bool(trim($cNode->nodeValue)); break; default: break; } } return $obj; } // }}} // _bool() {{{ /** * Returns a boolean according to true/false possible strings. * * @param string $str The string to process * * @return boolean */ private static function _bool($str) { return in_array((string)$str, array('true', '1', 'on', 'yes')); } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 0.1.0 */ /** * Main class for parsing command line options and arguments. * * There are three ways to create parsers with this class: * * // direct usage * $parser = new PEAR2_Console_CommandLine(); * * // with an xml definition file * $parser = PEAR2_Console_CommandLine::fromXmlFile('path/to/file.xml'); * * // with an xml definition string * $validXmlString = '..your xml string...'; * $parser = PEAR2_Console_CommandLine::fromXmlString($validXmlString); * * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 * @example docs/examples/ex1.php * @example docs/examples/ex2.php */ class PEAR2_Console_CommandLine { // Public properties {{{ /** * Error messages. * * @var array $errors Error messages * @todo move this to PEAR2_Console_CommandLine_MessageProvider */ public static $errors = array( 'option_bad_name' => 'option name must be a valid php variable name (got: {$name})', 'argument_bad_name' => 'argument name must be a valid php variable name (got: {$name})', 'option_long_and_short_name_missing' => 'you must provide at least an option short name or long name for option "{$name}"', 'option_bad_short_name' => 'option "{$name}" short name must be a dash followed by a letter (got: "{$short_name}")', 'option_bad_long_name' => 'option "{$name}" long name must be 2 dashes followed by a word (got: "{$long_name}")', 'option_unregistered_action' => 'unregistered action "{$action}" for option "{$name}".', 'option_bad_action' => 'invalid action for option "{$name}".', 'option_invalid_callback' => 'you must provide a valid callback for option "{$name}"', 'action_class_does_not_exists' => 'action "{$name}" class "{$class}" not found, make sure that your class is available before calling PEAR2_Console_CommandLine::registerAction()', 'invalid_xml_file' => 'XML definition file "{$file}" does not exists or is not readable', 'invalid_rng_file' => 'RNG file "{$file}" does not exists or is not readable' ); /** * The name of the program, if not given it defaults to argv[0]. * * @var string $name Name of your program */ public $name; /** * A description text that will be displayed in the help message. * * @var string $description Description of your program */ public $description = ''; /** * A string that represents the version of the program, if this property is * not empty and property add_version_option is not set to false, the * command line parser will add a --version option, that will display the * property content. * * @var string $version * @access public */ public $version = ''; /** * Boolean that determine if the command line parser should add the help * (-h, --help) option automatically. * * @var bool $add_help_option Whether to add a help option or not */ public $add_help_option = true; /** * Boolean that determine if the command line parser should add the version * (-v, --version) option automatically. * Note that the version option is also generated only if the version * property is not empty, it's up to you to provide a version string of * course. * * @var bool $add_version_option Whether to add a version option or not */ public $add_version_option = true; /** * The command line parser renderer instance. * * @var object that implements PEAR2_Console_CommandLine_Renderer interface */ public $renderer = false; /** * The command line parser outputter instance. * * @var PEAR2_Console_CommandLine_Outputter An outputter */ public $outputter = false; /** * The command line message provider instance. * * @var PEAR2_Console_CommandLine_MessageProvider A message provider instance */ public $message_provider = false; /** * Boolean that tells the parser to be POSIX compliant, POSIX demands the * following behavior: the first non-option stops option processing. * * @var bool $force_posix Whether to force posix compliance or not */ public $force_posix = false; /** * Boolean that tells the parser to set relevant options default values, * according to the option action. * * @see PEAR2_Console_CommandLine_Option::setDefaults() * @var bool $force_options_defaults Whether to force option default values */ public $force_options_defaults = false; /** * An array of PEAR2_Console_CommandLine_Option objects. * * @var array $options The options array */ public $options = array(); /** * An array of PEAR2_Console_CommandLine_Argument objects. * * @var array $args The arguments array */ public $args = array(); /** * An array of PEAR2_Console_CommandLine_Command objects (sub commands). * * @var array $commands The commands array */ public $commands = array(); /** * Parent, only relevant in Command objects but left here for interface * convenience. * * @var PEAR2_Console_CommandLine The parent instance * @todo move PEAR2_Console_CommandLine::parent to PEAR2_Console_CommandLine_Command */ public $parent = false; /** * Array of valid actions for an option, this array will also store user * registered actions. * * The array format is: *
     * array(
     *      => array(, )
     * )
     * 
* * @var array $actions List of valid actions */ public static $actions = array( 'StoreTrue' => array('PEAR2_Console_CommandLine_Action_StoreTrue', true), 'StoreFalse' => array('PEAR2_Console_CommandLine_Action_StoreFalse', true), 'StoreString' => array('PEAR2_Console_CommandLine_Action_StoreString', true), 'StoreInt' => array('PEAR2_Console_CommandLine_Action_StoreInt', true), 'StoreFloat' => array('PEAR2_Console_CommandLine_Action_StoreFloat', true), 'StoreArray' => array('PEAR2_Console_CommandLine_Action_StoreArray', true), 'Callback' => array('PEAR2_Console_CommandLine_Action_Callback', true), 'Counter' => array('PEAR2_Console_CommandLine_Action_Counter', true), 'Help' => array('PEAR2_Console_CommandLine_Action_Help', true), 'Version' => array('PEAR2_Console_CommandLine_Action_Version', true), 'Password' => array('PEAR2_Console_CommandLine_Action_Password', true), 'List' => array('PEAR2_Console_CommandLine_Action_List', true), ); /** * Array of options that must be dispatched at the end. * * @var array $_dispatchLater Options to be dispatched */ private $_dispatchLater = array(); // }}} // __construct() {{{ /** * Constructor. * Example: * * * $parser = new PEAR2_Console_CommandLine(array( * 'name' => 'yourprogram', // defaults to argv[0] * 'description' => 'Description of your program', * 'version' => '0.0.1', // your program version * 'add_help_option' => true, // or false to disable --version option * 'add_version_option' => true, // or false to disable --help option * 'force_posix' => false // or true to force posix compliance * )); * * * @param array $params An optional array of parameters * * @return void */ public function __construct(array $params = array()) { if (isset($params['name'])) { $this->name = $params['name']; } else if (isset($argv) && count($argv) > 0) { $this->name = $argv[0]; } else if (isset($_SERVER['argv']) && count($_SERVER['argv']) > 0) { $this->name = $_SERVER['argv'][0]; } else if (isset($_SERVER['SCRIPT_NAME'])) { $this->name = basename($_SERVER['SCRIPT_NAME']); } if (isset($params['description'])) { $this->description = $params['description']; } if (isset($params['version'])) { $this->version = $params['version']; } if (isset($params['add_version_option'])) { $this->add_version_option = $params['add_version_option']; } if (isset($params['add_help_option'])) { $this->add_help_option = $params['add_help_option']; } if (isset($params['force_posix'])) { $this->force_posix = $params['force_posix']; } else if (getenv('POSIXLY_CORRECT')) { $this->force_posix = true; } // set default instances $this->renderer = new PEAR2_Console_CommandLine_Renderer_Default($this); $this->outputter = new PEAR2_Console_CommandLine_Outputter_Default(); $this->message_provider = new PEAR2_Console_CommandLine_MessageProvider_Default(); } // }}} // accept() {{{ /** * Method to allow PEAR2_Console_CommandLine to accept either: * + a custom renderer, * + a custom outputter, * + or a custom message provider * * @param mixed $instance The custom instance * * @return void * @throws PEAR2_Console_CommandLine_Exception if wrong argument passed */ public function accept($instance) { if ($instance instanceof PEAR2_Console_CommandLine_Renderer) { if (property_exists($instance, 'parser') && !$instance->parser) { $instance->parser = $this; } $this->renderer = $instance; } else if ($instance instanceof PEAR2_Console_CommandLine_Outputter) { $this->outputter = $instance; } else if ($instance instanceof PEAR2_Console_CommandLine_MessageProvider) { $this->message_provider = $instance; } else { throw PEAR2_Console_CommandLine_Exception::factory( 'INVALID_CUSTOM_INSTANCE', array(), $this ); } } // }}} // fromXmlFile() {{{ /** * Returns a command line parser instance built from an xml file. * * Example: * * $parser = PEAR2_Console_CommandLine::fromXmlFile('path/to/file.xml'); * $result = $parser->parse(); * * * @param string $file Path to the xml file * * @return PEAR2_Console_CommandLine The parser instance */ public static function fromXmlFile($file) { return PEAR2_Console_CommandLine_XmlParser::parse($file); } // }}} // fromXmlString() {{{ /** * Returns a command line parser instance built from an xml string. * * Example: * * $xmldata = ' * * Compress files * * * a list of files * true * * '; * $parser = PEAR2_Console_CommandLine::fromXmlString($xmldata); * $result = $parser->parse(); * * * @param string $string The xml data * * @return PEAR2_Console_CommandLine The parser instance */ public static function fromXmlString($string) { return PEAR2_Console_CommandLine_XmlParser::parseString($string); } // }}} // addArgument() {{{ /** * Adds an argument to the command line parser and returns it. * * Adds an argument with the name $name and set its attributes with the * array $params, then return the PEAR2_Console_CommandLine_Argument instance * created. * The method accepts another form: you can directly pass a * PEAR2_Console_CommandLine_Argument object as the sole argument, this allows * you to contruct the argument separately, in order to reuse it in * different command line parsers or commands for example. * * Example: * * $parser = new PEAR2_Console_CommandLine(); * // add an array argument * $parser->addArgument('input_files', array('multiple'=>true)); * // add a simple argument * $parser->addArgument('output_file'); * $result = $parser->parse(); * print_r($result->args['input_files']); * print_r($result->args['output_file']); * // will print: * // array('file1', 'file2') * // 'file3' * // if the command line was: * // myscript.php file1 file2 file3 * * * In a terminal, the help will be displayed like this: * * $ myscript.php install -h * Usage: myscript.php * * * @param mixed $name A string containing the argument name or an * instance of PEAR2_Console_CommandLine_Argument * @param array $params An array containing the argument attributes * * @return PEAR2_Console_CommandLine_Argument the added argument * @see PEAR2_Console_CommandLine_Argument */ public function addArgument($name, $params = array()) { if ($name instanceof PEAR2_Console_CommandLine_Argument) { $argument = $name; } else { $argument = new PEAR2_Console_CommandLine_Argument($name, $params); } $argument->validate(); $this->args[$argument->name] = $argument; return $argument; } // }}} // addCommand() {{{ /** * Adds a sub-command to the command line parser. * * Adds a command with the given $name to the parser and returns the * PEAR2_Console_CommandLine_Command instance, you can then populate the command * with options, configure it, etc... like you would do for the main parser * because the class PEAR2_Console_CommandLine_Command inherits from * PEAR2_Console_CommandLine. * * An example: * * $parser = new PEAR2_Console_CommandLine(); * $install_cmd = $parser->addCommand('install'); * $install_cmd->addOption( * 'verbose', * array( * 'short_name' => '-v', * 'long_name' => '--verbose', * 'description' => 'be noisy when installing stuff', * 'action' => 'StoreTrue' * ) * ); * $parser->parse(); * * Then in a terminal: * * $ myscript.php install -h * Usage: myscript.php install [options] * * Options: * -h, --help display this help message and exit * -v, --verbose be noisy when installing stuff * * $ myscript.php install --verbose * Installing whatever... * $ * * * @param mixed $name A string containing the command name or an * instance of PEAR2_Console_CommandLine_Command * @param array $params An array containing the command attributes * * @return PEAR2_Console_CommandLine_Command The added subcommand * @see PEAR2_Console_CommandLine_Command */ public function addCommand($name, $params = array()) { if ($name instanceof PEAR2_Console_CommandLine_Command) { $command = $name; } else { $params['name'] = $name; $command = new PEAR2_Console_CommandLine_Command($params); } $command->parent = $this; $this->commands[$command->name] = $command; return $command; } // }}} // addOption() {{{ /** * Adds an option to the command line parser and returns it. * * Adds an option with the name $name and set its attributes with the * array $params, then return the PEAR2_Console_CommandLine_Option instance * created. * The method accepts another form: you can directly pass a * PEAR2_Console_CommandLine_Option object as the sole argument, this allows * you to contruct the option separately, in order to reuse it in different * command line parsers or commands for example. * * Example: * * $parser = new PEAR2_Console_CommandLine(); * $parser->addOption('path', array( * 'short_name' => '-p', // a short name * 'long_name' => '--path', // a long name * 'description' => 'path to the dir', // a description msg * 'action' => 'StoreString', * 'default' => '/tmp' // a default value * )); * $parser->parse(); * * * In a terminal, the help will be displayed like this: * * $ myscript.php --help * Usage: myscript.php [options] * * Options: * -h, --help display this help message and exit * -p, --path path to the dir * * * * Various methods to specify an option, these 3 commands are equivalent: * * $ myscript.php --path=some/path * $ myscript.php -p some/path * $ myscript.php -psome/path * * * @param mixed $name A string containing the option name or an * instance of PEAR2_Console_CommandLine_Option * @param array $params An array containing the option attributes * * @return PEAR2_Console_CommandLine_Option The added option * @see PEAR2_Console_CommandLine_Option */ public function addOption($name, $params = array()) { if ($name instanceof PEAR2_Console_CommandLine_Option) { $opt = $name; } else { $opt = new PEAR2_Console_CommandLine_Option($name, $params); } $opt->validate(); if ($this->force_options_defaults) { $opt->setDefaults(); } $this->options[$opt->name] = $opt; if (!empty($opt->choices) && $opt->add_list_option) { $this->addOption('list_' . $opt->name, array( 'long_name' => '--list-' . $opt->name, 'description' => $this->message_provider->get( 'LIST_OPTION_MESSAGE', array('name' => $opt->name) ), 'action' => 'List', 'action_params' => array('list' => $opt->choices), )); } return $opt; } // }}} // displayError() {{{ /** * Displays an error to the user and exit with $exitCode. * * @param string $error The error message * @param int $exitCode The exit code number * * @return void */ public function displayError($error, $exitCode = 1) { $this->outputter->stderr($this->renderer->error($error)); exit($exitCode); } // }}} // displayUsage() {{{ /** * Displays the usage help message to the user and exit with $exitCode * * @param int $exitCode The exit code number * * @return void */ public function displayUsage($exitCode = 1) { $this->outputter->stderr($this->renderer->usage()); exit($exitCode); } // }}} // displayVersion() {{{ /** * Displays the program version to the user * * @return void */ public function displayVersion() { $this->outputter->stdout($this->renderer->version()); exit(0); } // }}} // findOption() {{{ /** * Finds the option that matches the given short_name (ex: -v), long_name * (ex: --verbose) or name (ex: verbose). * * @param string $str The option identifier * * @return mixed A PEAR2_Console_CommandLine_Option instance or false */ public function findOption($str) { $str = trim($str); if ($str === '') { return false; } $matches = array(); foreach ($this->options as $opt) { if ($opt->short_name == $str || $opt->long_name == $str || $opt->name == $str) { // exact match return $opt; } if (substr($opt->long_name, 0, strlen($str)) === $str) { // abbreviated long option $matches[] = $opt; } } if ($count = count($matches)) { if ($count > 1) { $matches_str = ''; $padding = ''; foreach ($matches as $opt) { $matches_str .= $padding . $opt->long_name; $padding = ', '; } throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_AMBIGUOUS', array('name' => $str, 'matches' => $matches_str), $this ); } return $matches[0]; } return false; } // }}} // registerAction() {{{ /** * Registers a custom action for the parser, an example: * * * * // in this example we create a "range" action: * // the user will be able to enter something like: * // $ -r 1,5 * // and in the result we will have: * // $result->options['range']: array(1, 5) * * class ActionRange extends PEAR2_Console_CommandLine_Action * { * public function execute($value=false, $params=array()) * { * $range = explode(',', str_replace(' ', '', $value)); * if (count($range) != 2) { * throw new Exception(sprintf( * 'Option "%s" must be 2 integers separated by a comma', * $this->option->name * )); * } * $this->setResult($range); * } * } * // then we can register our action * PEAR2_Console_CommandLine::registerAction('Range', 'ActionRange'); * // and now our action is available ! * $parser = new PEAR2_Console_CommandLine(); * $parser->addOption('range', array( * 'short_name' => '-r', * 'long_name' => '--range', * 'action' => 'Range', // note our custom action * 'description' => 'A range of two integers separated by a comma' * )); * // etc... * * * * @param string $name The name of the custom action * @param string $class The class name of the custom action * * @return void */ public static function registerAction($name, $class) { if (!isset(self::$actions[$name])) { if (!class_exists($class)) { self::triggerError('action_class_does_not_exists', E_USER_ERROR, array('{$name}' => $name, '{$class}' => $class)); } self::$actions[$name] = array($class, false); } } // }}} // triggerError() {{{ /** * A wrapper for programming errors triggering. * * @param string $msgId Identifier of the message * @param int $level The php error level * @param array $params An array of search=>replaces entries * * @return void * @todo remove Console::triggerError() and use exceptions only */ public static function triggerError($msgId, $level, $params=array()) { if (isset(self::$errors[$msgId])) { $msg = str_replace(array_keys($params), array_values($params), self::$errors[$msgId]); trigger_error($msg, $level); } else { trigger_error('unknown error', $level); } } // }}} // parse() {{{ /** * Parses the command line arguments and returns a * PEAR2_Console_CommandLine_Result instance. * * @param integer $userArgc Number of arguments (optional) * @param array $userArgv Array containing arguments (optional) * * @return PEAR2_Console_CommandLine_Result The result instance * @throws Exception on user errors */ public function parse($userArgc=null, $userArgv=null) { $this->addBuiltinOptions(); if ($userArgc !== null && $userArgv !== null) { $argc = $userArgc; $argv = $userArgv; } else { list($argc, $argv) = $this->getArgcArgv(); } // build an empty result $result = new PEAR2_Console_CommandLine_Result(); if (!($this instanceof PEAR2_Console_CommandLine_Command)) { // remove script name if we're not in a subcommand array_shift($argv); $argc--; } // will contain aruments $args = array(); foreach ($this->options as $name=>$option) { $result->options[$name] = $option->default; } // parse command line tokens while ($argc--) { $token = array_shift($argv); try { if ($cmd = $this->_getSubCommand($token)) { $result->command_name = $cmd->name; $result->command = $cmd->parse($argc, $argv); break; } else { $this->parseToken($token, $result, $args, $argc); } } catch (Exception $exc) { throw $exc; } } // minimum argument number check $argnum = 0; foreach ($this->args as $name=>$arg) { if (!$arg->optional) { $argnum++; } } if (count($args) < $argnum) { throw PEAR2_Console_CommandLine_Exception::factory( 'ARGUMENT_REQUIRED', array('argnum' => $argnum, 'plural' => $argnum>1 ? 's': ''), $this ); } // handle arguments $c = count($this->args); foreach ($this->args as $name=>$arg) { $c--; if ($arg->multiple) { $result->args[$name] = $c ? array_splice($args, 0, -$c) : $args; } else { $result->args[$name] = array_shift($args); } } // dispatch deferred options foreach ($this->_dispatchLater as $optArray) { $optArray[0]->dispatchAction($optArray[1], $optArray[2], $this); } return $result; } // }}} // parseToken() {{{ /** * Parses the command line token and modifies *by reference* the $options * and $args arrays. * * @param string $token The command line token to parse * @param object $result The PEAR2_Console_CommandLine_Result instance * @param array &$args The argv array * @param int $argc Number of lasting args * * @return void * @access protected * @throws Exception on user errors */ protected function parseToken($token, $result, &$args, $argc) { static $lastopt = false; static $stopflag = false; $last = $argc === 0; $token = trim($token); if (!$stopflag && $lastopt) { if (substr($token, 0, 1) == '-') { if ($lastopt->argument_optional) { $this->_dispatchAction($lastopt, '', $result); if ($lastopt->action != 'StoreArray') { $lastopt = false; } } else if (isset($result->options[$lastopt->name])) { // case of an option that expect a list of args $lastopt = false; } else { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_REQUIRED', array('name' => $lastopt->name), $this ); } } else { // when a StoreArray option is positioned last, the behavior // is to consider that if there's already an element in the // array, and the commandline expects one or more args, we // leave last tokens to arguments if ($lastopt->action == 'StoreArray' && !empty($result->options[$lastopt->name]) && count($this->args) > ($argc + count($args))) { $args[] = $token; return; } $this->_dispatchAction($lastopt, $token, $result); if ($lastopt->action != 'StoreArray') { $lastopt = false; } return; } } if (!$stopflag && substr($token, 0, 2) == '--') { // a long option $optkv = explode('=', $token, 2); if (trim($optkv[0]) == '--') { // the special argument "--" forces in all cases the end of // option scanning. $stopflag = true; return; } $opt = $this->findOption($optkv[0]); if (!$opt) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_UNKNOWN', array('name' => $optkv[0]), $this ); } $value = isset($optkv[1]) ? $optkv[1] : false; if (!$opt->expectsArgument() && $value !== false) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_UNEXPECTED', array('name' => $opt->name, 'value' => $value), $this ); } if ($opt->expectsArgument() && $value === false) { // maybe the long option argument is separated by a space, if // this is the case it will be the next arg if ($last && !$opt->argument_optional) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_REQUIRED', array('name' => $opt->name), $this ); } // we will have a value next time $lastopt = $opt; return; } if ($opt->action == 'StoreArray') { $lastopt = $opt; } $this->_dispatchAction($opt, $value, $result); } else if (!$stopflag && substr($token, 0, 1) == '-') { // a short option $optname = substr($token, 0, 2); if ($optname == '-') { // special case of "-": try to read stdin $args[] = file_get_contents('php://stdin'); return; } $opt = $this->findOption($optname); if (!$opt) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_UNKNOWN', array('name' => $optname), $this ); } // parse other options or set the value // in short: handle -f and -f $next = substr($token, 2, 1); // check if we must wait for a value if ($next === false) { if ($opt->expectsArgument()) { if ($last && !$opt->argument_optional) { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_VALUE_REQUIRED', array('name' => $opt->name), $this ); } // we will have a value next time $lastopt = $opt; return; } $value = false; } else { if (!$opt->expectsArgument()) { if ($nextopt = $this->findOption('-' . $next)) { $this->_dispatchAction($opt, false, $result); $this->parseToken('-' . substr($token, 2), $result, $args, $last); return; } else { throw PEAR2_Console_CommandLine_Exception::factory( 'OPTION_UNKNOWN', array('name' => $next), $this ); } } if ($opt->action == 'StoreArray') { $lastopt = $opt; } $value = substr($token, 2); } $this->_dispatchAction($opt, $value, $result); } else { // We have an argument. // if we are in POSIX compliant mode, we must set the stop flag to // true in order to stop option parsing. if (!$stopflag && $this->force_posix) { $stopflag = true; } $args[] = $token; } } // }}} // addBuiltinOptions() {{{ /** * Adds the builtin "Help" and "Version" options if needed. * * @return void */ public function addBuiltinOptions() { if ($this->add_help_option) { $helpOptionParams = array( 'long_name' => '--help', 'description' => 'show this help message and exit', 'action' => 'Help' ); if (!($option = $this->findOption('-h')) || $option->action == 'Help') { // short name is available, take it $helpOptionParams['short_name'] = '-h'; } $this->addOption('help', $helpOptionParams); } if ($this->add_version_option && !empty($this->version)) { $versionOptionParams = array( 'long_name' => '--version', 'description' => 'show the program version and exit', 'action' => 'Version' ); if (!$this->findOption('-v')) { // short name is available, take it $versionOptionParams['short_name'] = '-v'; } $this->addOption('version', $versionOptionParams); } } // }}} // getArgcArgv() {{{ /** * Tries to return an array containing argc and argv, or trigger an error * if it fails to get them. * * @return array The argc/argv array * @throws PEAR2_Console_CommandLine_Exception */ protected function getArgcArgv() { if (php_sapi_name() != 'cli') { // we have a web request $argv = array($this->name); if (isset($_REQUEST)) { foreach ($_REQUEST as $key => $value) { if (!is_array($value)) { $value = array($value); } $opt = $this->findOption($key); if ($opt instanceof PEAR2_Console_CommandLine_Option) { // match a configured option $argv[] = $opt->short_name ? $opt->short_name : $opt->long_name; foreach ($value as $v) { if ($opt->expectsArgument()) { $argv[] = isset($_GET[$key]) ? urldecode($v) : $v; } else if ($v == '0' || $v == 'false') { array_pop($argv); } } } else if (isset($this->args[$key])) { // match a configured argument foreach ($value as $v) { $argv[] = isset($_GET[$key]) ? urldecode($v) : $v; } } } } return array(count($argv), $argv); } if (isset($argc) && isset($argv)) { // case of register_argv_argc = 1 return array($argc, $argv); } if (isset($_SERVER['argc']) && isset($_SERVER['argv'])) { return array($_SERVER['argc'], $_SERVER['argv']); } return array(0, array()); } // }}} // _dispatchAction() {{{ /** * Dispatches the given option or store the option to dispatch it later. * * @param PEAR2_Console_CommandLine_Option $option The option instance * @param string $token Command line token to parse * @param PEAR2_Console_CommandLine_Result $result The result instance * * @return void */ private function _dispatchAction($option, $token, $result) { if ($option->action == 'Password') { $this->_dispatchLater[] = array($option, $token, $result); } else { $option->dispatchAction($token, $result, $this); } } // }}} // _getSubCommand() {{{ /** * Tries to return the subcommand that matches the given token or returns * false if no subcommand was found. * * @param string $token Current command line token * * @return mixed An instance of Console_CommandLine_Command or false */ private function _getSubCommand($token) { foreach ($this->commands as $cmd) { if ($cmd->name == $token || in_array($token, $cmd->aliases)) { return $cmd; } } return false; } // }}} } * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 1.0.0 */ if (!defined('PHPUnit_MAIN_METHOD')) { define('PHPUnit_MAIN_METHOD', 'Console_CommandLine_AllTests::main'); } require_once 'PHPUnit/Framework.php'; require_once 'PHPUnit/Extensions/PhptTestSuite.php'; require_once 'PHPUnit/TextUI/TestRunner.php'; /** * PEAR2_Console_CommandLine phpt test suite. * * Run all tests from the package root directory: * $ phpunit PEAR2_Console_CommandLine_AllTests tests/AllTests.php * or * $ php tests/AllTests.php * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since Class available since release 1.0.0 */ class PEAR2_Console_CommandLine_AllTests { /** * Runs the test suite * * @return void * @static */ public static function main() { PHPUnit_TextUI_TestRunner::run(self::suite()); } /** * Return the phpt test suite * * @return object the PHPUnit_Framework_TestSuite object * @static */ public static function suite() { return new PHPUnit_Extensions_PhptTestSuite(__DIR__); } } if (PHPUnit_MAIN_METHOD == 'Console_CommandLine_AllTests::main') { PEAR2_Console_CommandLine_AllTests::main(); } ?> --TEST-- Test for PEAR2_Console_CommandLine::accept() method. --FILE-- accept(new CustomRenderer()); echo get_class($parser->renderer) . "\n"; // outputter $parser->accept(new CustomOutputter()); echo get_class($parser->outputter) . "\n"; $parser->accept(new CustomMessageProvider()); echo get_class($parser->message_provider) . "\n"; $parser->accept(new stdclass()); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- CustomRenderer CustomOutputter CustomMessageProvider STDERR >> CustomRenderer::error(INVALID_CUSTOM_INSTANCE) --TEST-- Test for PEAR2_Console_CommandLine::addArgument() method. --FILE-- addArgument('arg1'); $parser->addArgument('arg2', array( 'multiple' => true, 'description' => 'description of arg2' )); $arg3 = new PEAR2_Console_CommandLine_Argument('arg3', array( 'multiple' => true, 'description' => 'description of arg3' )); $parser->addArgument($arg3); $parser->addArgument('arg4', array('optional' => true)); var_dump($parser->args); // a bad argument $parser->addArgument('Some invalid name'); ?> --EXPECTF-- array(4) { ["arg1"]=> object(PEAR2_Console_CommandLine_Argument)#8 (5) { ["multiple"]=> bool(false) ["optional"]=> bool(false) ["name"]=> string(4) "arg1" ["help_name"]=> string(4) "arg1" ["description"]=> NULL } ["arg2"]=> object(PEAR2_Console_CommandLine_Argument)#9 (5) { ["multiple"]=> bool(true) ["optional"]=> bool(false) ["name"]=> string(4) "arg2" ["help_name"]=> string(4) "arg2" ["description"]=> string(19) "description of arg2" } ["arg3"]=> object(PEAR2_Console_CommandLine_Argument)#10 (5) { ["multiple"]=> bool(true) ["optional"]=> bool(false) ["name"]=> string(4) "arg3" ["help_name"]=> string(4) "arg3" ["description"]=> string(19) "description of arg3" } ["arg4"]=> object(PEAR2_Console_CommandLine_Argument)#11 (5) { ["multiple"]=> bool(false) ["optional"]=> bool(true) ["name"]=> string(4) "arg4" ["help_name"]=> string(4) "arg4" ["description"]=> NULL } } Fatal error: argument name must be a valid php variable name (got: Some invalid name) in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addCommand() method. --FILE-- addCommand('cmd1'); $parser->addCommand('cmd2', array( 'description' => 'description of cmd2' )); $cmd3 = new PEAR2_Console_CommandLine_Command(array( 'name' => 'cmd3', 'description' => 'description of cmd3' )); $parser->addCommand($cmd3); var_dump(array_keys($parser->commands)); var_dump($parser->commands['cmd2']->description); var_dump($parser->commands['cmd3']->description); ?> --EXPECT-- array(3) { [0]=> string(4) "cmd1" [1]=> string(4) "cmd2" [2]=> string(4) "cmd3" } string(19) "description of cmd2" string(19) "description of cmd3" --TEST-- Test for PEAR2_Console_CommandLine::addOption() method. --FILE-- addOption('opt1', array( 'short_name' => '-a' )); $parser->addOption('opt2', array( 'short_name' => '-b', 'long_name' => '--foo', 'description' => 'description of opt2', 'action' => 'StoreInt', 'help_name' => 'bar', 'choices' => array(1, 2, 3), 'add_list_option' => true, 'default' => 2 )); $opt3 = new PEAR2_Console_CommandLine_Option('opt3', array( 'long_name' => '--bar', 'description' => 'description of opt3', )); $parser->addOption($opt3); var_dump($parser->options); ?> --EXPECT-- array(4) { ["opt1"]=> object(PEAR2_Console_CommandLine_Option)#8 (12) { ["short_name"]=> string(2) "-a" ["long_name"]=> NULL ["action"]=> string(11) "StoreString" ["default"]=> NULL ["choices"]=> array(0) { } ["callback"]=> NULL ["action_params"]=> array(0) { } ["argument_optional"]=> bool(false) ["add_list_option"]=> bool(false) ["name"]=> string(4) "opt1" ["help_name"]=> string(4) "opt1" ["description"]=> NULL } ["opt2"]=> object(PEAR2_Console_CommandLine_Option)#9 (12) { ["short_name"]=> string(2) "-b" ["long_name"]=> string(5) "--foo" ["action"]=> string(8) "StoreInt" ["default"]=> int(2) ["choices"]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } ["callback"]=> NULL ["action_params"]=> array(0) { } ["argument_optional"]=> bool(false) ["add_list_option"]=> bool(true) ["name"]=> string(4) "opt2" ["help_name"]=> string(3) "bar" ["description"]=> string(19) "description of opt2" } ["list_opt2"]=> object(PEAR2_Console_CommandLine_Option)#10 (12) { ["short_name"]=> NULL ["long_name"]=> string(11) "--list-opt2" ["action"]=> string(4) "List" ["default"]=> NULL ["choices"]=> array(0) { } ["callback"]=> NULL ["action_params"]=> array(1) { ["list"]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } } ["argument_optional"]=> bool(false) ["add_list_option"]=> bool(false) ["name"]=> string(9) "list_opt2" ["help_name"]=> string(9) "list_opt2" ["description"]=> string(35) "lists valid choices for option opt2" } ["opt3"]=> object(PEAR2_Console_CommandLine_Option)#11 (12) { ["short_name"]=> NULL ["long_name"]=> string(5) "--bar" ["action"]=> string(11) "StoreString" ["default"]=> NULL ["choices"]=> array(0) { } ["callback"]=> NULL ["action_params"]=> array(0) { } ["argument_optional"]=> bool(false) ["add_list_option"]=> bool(false) ["name"]=> string(4) "opt3" ["help_name"]=> string(4) "opt3" ["description"]=> string(19) "description of opt3" } } --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 1). --FILE-- addOption('Some invalid name'); ?> --EXPECTF-- Fatal error: option name must be a valid php variable name (got: Some invalid name) in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 2). --FILE-- addOption('name', array()); ?> --EXPECTF-- Fatal error: you must provide at least an option short name or long name for option "name" in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 3). --FILE-- addOption('name', array('short_name'=>'d')); ?> --EXPECTF-- Fatal error: option "name" short name must be a dash followed by a letter (got: "d") in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 4). --FILE-- addOption('name', array('long_name'=>'d')); ?> --EXPECTF-- Fatal error: option "name" long name must be 2 dashes followed by a word (got: "d") in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 5). --FILE-- addOption('name', array('short_name'=>'-d', 'action'=>true)); ?> --EXPECTF-- Fatal error: invalid action for option "name". in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 6). --FILE-- addOption('name', array('short_name'=>'-d', 'action'=>'Inexistant')); ?> --EXPECTF-- Fatal error: unregistered action "Inexistant" for option "name". in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::addOption() method (errors 7). --FILE-- addOption('name', array('short_name'=>'-d', 'action'=>'Callback')); ?> --EXPECTF-- Fatal error: you must provide a valid callback for option "name" in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::fromXmlFile() method. --SKIPIF-- --ARGS-- --help 2>&1 --FILE-- parse(); ?> --EXPECTF-- zip/unzip files Usage: test [options] test [options] [options] [args] Options: -c choice, --choice=choice choice option --list-choice lists valid choices for option choice -p password, --password=password zip file password -v, --verbose turn on verbose output -h, --help show this help message and exit --version show the program version and exit Commands: zip zip given files in the destination file (aliases: compress, zp) unzip unzip given file in the destination dir (alias: uzp) --TEST-- Test for PEAR2_Console_CommandLine::fromXmlFile() method (error). --SKIPIF-- --ARGS-- --help 2>&1 --FILE-- parse(); ?> --EXPECTF-- Fatal error: XML definition file "%sunexisting.xml" does not exists or is not readable in %sCommandLine.php on line %d --TEST-- Test for PEAR2_Console_CommandLine::fromXmlString() method. --SKIPIF-- --ARGS-- --help 2>&1 --FILE-- parse(); ?> --EXPECT-- zip/unzip files Usage: test [options] test [options] [options] [args] Options: -c choice, --choice=choice choice option --list-choice lists valid choices for option choice -p password, --password=password zip file password -v, --verbose turn on verbose output -h, --help show this help message and exit --version show the program version and exit Commands: zip zip given files in the destination file (aliases: compress, zp) unzip unzip given file in the destination dir (alias: uzp) --TEST-- Test for PEAR2_Console_CommandLine::parse() method (--version). --SKIPIF-- --ARGS-- --version --FILE-- parse(); ?> --EXPECT-- some_program version 0.1.0. --TEST-- Test for PEAR2_Console_CommandLine::parse() method (--help). --SKIPIF-- --ARGS-- --help 2>&1 --FILE-- parse(); ?> --EXPECT-- Description of our parser goes here... Usage: some_program [options] Options: -t, --true test the StoreTrue action -f, --false test the StoreFalse action --int=INT test the StoreInt action --float=FLOAT test the StoreFloat action -s STRING, --string=STRING test the StoreString action -c, --counter test the Counter action --callback=callback test the Callback action -a ARRAY, --array=ARRAY test the StoreArray action -p password, --password=password test the Password action -h, --help show this help message and exit -v, --version show the program version and exit Arguments: simple test a simple argument multiple test a multiple argument --TEST-- Test for PEAR2_Console_CommandLine::parse() method (various options). --SKIPIF-- --ARGS-- -tfsfoo --int=3 --flo 4.0 -cccc --callback=somestring -a foo bar baz foo bar --FILE-- parse(); var_dump($result->options); var_dump($result->args); ?> --EXPECT-- array(11) { ["true"]=> bool(true) ["false"]=> bool(false) ["int"]=> int(3) ["float"]=> float(4) ["string"]=> string(3) "foo" ["counter"]=> int(4) ["callback"]=> string(20) "foo__fbzrfgevat__bar" ["array"]=> array(3) { [0]=> string(3) "foo" [1]=> string(3) "bar" [2]=> string(3) "baz" } ["password"]=> NULL ["help"]=> NULL ["version"]=> NULL } array(2) { ["simple"]=> string(3) "foo" ["multiple"]=> array(1) { [0]=> string(3) "bar" } } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (errors 1). --SKIPIF-- --ARGS-- -d 2>&1 --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- Error: Unknown option "-d". Type "some_program --help" to get help. --TEST-- Test for PEAR2_Console_CommandLine::parse() method (errors 2). --SKIPIF-- --ARGS-- --float 2>&1 --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- Error: Option "float" requires a value. Type "some_program --help" to get help. --TEST-- Test for PEAR2_Console_CommandLine::parse() method (errors 3). --SKIPIF-- --ARGS-- --float=1.2 2>&1 --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- Error: You must provide at least 1 argument. Type "some_program --help" to get help. --TEST-- Test for PEAR2_Console_CommandLine::parse() method (special cases 1). --SKIPIF-- --ARGS-- -t -- -f - --float=1.2 foo 2>&1 --FILE-- parse(); var_dump($result); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- object(PEAR2_Console_CommandLine_Result)#21 (4) { ["options"]=> array(11) { ["true"]=> bool(true) ["false"]=> NULL ["int"]=> int(1) ["float"]=> float(1) ["string"]=> NULL ["counter"]=> NULL ["callback"]=> NULL ["array"]=> NULL ["password"]=> NULL ["help"]=> NULL ["version"]=> NULL } ["args"]=> array(2) { ["simple"]=> string(2) "-f" ["multiple"]=> array(3) { [0]=> string(1) "-" [1]=> string(11) "--float=1.2" [2]=> string(3) "foo" } } ["command_name"]=> bool(false) ["command"]=> bool(false) } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (special cases 2). --SKIPIF-- --ARGS-- -t foo bar -f 2>&1 --FILE-- force_posix = true; $result = $parser->parse(); var_dump($result); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- object(PEAR2_Console_CommandLine_Result)#21 (4) { ["options"]=> array(11) { ["true"]=> bool(true) ["false"]=> NULL ["int"]=> int(1) ["float"]=> float(1) ["string"]=> NULL ["counter"]=> NULL ["callback"]=> NULL ["array"]=> NULL ["password"]=> NULL ["help"]=> NULL ["version"]=> NULL } ["args"]=> array(2) { ["simple"]=> string(3) "foo" ["multiple"]=> array(2) { [0]=> string(3) "bar" [1]=> string(2) "-f" } } ["command_name"]=> bool(false) ["command"]=> bool(false) } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (password option). --SKIPIF-- --ARGS-- -p -- foo bar --STDIN-- secretpass --FILE-- parse(); var_dump($result->options); var_dump($result->args); ?> --EXPECT-- Password: array(11) { ["true"]=> NULL ["false"]=> NULL ["int"]=> int(1) ["float"]=> float(1) ["string"]=> NULL ["counter"]=> NULL ["callback"]=> NULL ["array"]=> NULL ["password"]=> string(10) "secretpass" ["help"]=> NULL ["version"]=> NULL } array(2) { ["simple"]=> string(3) "foo" ["multiple"]=> array(1) { [0]=> string(3) "bar" } } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (subcommand). --SKIPIF-- --ARGS-- -v install -f foo --FILE-- parse(); var_dump($result->options); var_dump($result->command_name); var_dump($result->command->options); ?> --EXPECT-- array(4) { ["verbose"]=> bool(true) ["logfile"]=> NULL ["help"]=> NULL ["version"]=> NULL } string(7) "install" array(2) { ["force"]=> bool(true) ["help"]=> NULL } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (subcommand help 1). --SKIPIF-- --ARGS-- --help 2>&1 --FILE-- parse(); ?> --EXPECT-- Description of our parser goes here... Usage: some_program [options] some_program [options] [options] [args] Options: -v, --verbose verbose mode -l logfile, --logfile=logfile path to logfile -h, --help show this help message and exit --version show the program version and exit Commands: install install given package (aliases: inst, instbis) uninstall uninstall given package --TEST-- Test for PEAR2_Console_CommandLine::parse() method (subcommand help 2). --SKIPIF-- --ARGS-- inst --help 2>&1 --FILE-- parse(); ?> --EXPECT-- install given package Usage: some_program [options] install [options] Options: -f, --force force installation -h, --help show this help message and exit Arguments: package package to install --TEST-- Test for PEAR2_Console_CommandLine::parse() method (user errors 1). --SKIPIF-- --ARGS-- --float=foo foo bar --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { echo $exc->getMessage(); } ?> --EXPECT-- Option "float" requires a value of type float (got "foo"). --TEST-- Test for PEAR2_Console_CommandLine::parse() method (user errors 2). --SKIPIF-- --ARGS-- --int=foo foo bar --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { echo $exc->getMessage(); } ?> --EXPECT-- Option "int" requires a value of type int (got "foo"). --TEST-- Test for PEAR2_Console_CommandLine::parse() method (subcommand error). --SKIPIF-- --ARGS-- install -f 2>&1 --FILE-- parse(); } catch (Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- Error: You must provide at least 1 argument. Type "some_program --help" to get help. Type "some_program --help" to get help on specific command. --TEST-- Test for PEAR2_Console_CommandLine::parse() method (user errors 3). --SKIPIF-- --ARGS-- -s fooz foo bar --FILE-- parse(); } catch (PEAR2_Console_CommandLine_Exception $exc) { echo $exc->getMessage(); } ?> --EXPECT-- Option "string" must be one of the following: "foo", "bar", "baz" (got "fooz"). --TEST-- Test for PEAR2_Console_CommandLine::parse() method (user argc/argv 1). --SKIPIF-- --FILE-- parse($argc, $argv); var_dump($result); } catch (Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- object(PEAR2_Console_CommandLine_Result)#21 (4) { ["options"]=> array(11) { ["true"]=> bool(true) ["false"]=> bool(false) ["int"]=> int(1) ["float"]=> float(1.2) ["string"]=> NULL ["counter"]=> NULL ["callback"]=> NULL ["array"]=> NULL ["password"]=> NULL ["help"]=> NULL ["version"]=> NULL } ["args"]=> array(2) { ["simple"]=> string(3) "foo" ["multiple"]=> array(1) { [0]=> string(3) "bar" } } ["command_name"]=> bool(false) ["command"]=> bool(false) } --TEST-- Test for PEAR2_Console_CommandLine::parse() method (user argc/argv 2). --SKIPIF-- --FILE-- parse($argc, $argv); var_dump($result); } catch (PEAR2_Console_CommandLine_Exception $exc) { $parser->displayError($exc->getMessage()); } ?> --EXPECT-- object(PEAR2_Console_CommandLine_Result)#23 (4) { ["options"]=> array(4) { ["verbose"]=> bool(true) ["logfile"]=> NULL ["help"]=> NULL ["version"]=> NULL } ["args"]=> array(0) { } ["command_name"]=> string(7) "install" ["command"]=> object(PEAR2_Console_CommandLine_Result)#25 (4) { ["options"]=> array(2) { ["force"]=> bool(true) ["help"]=> NULL } ["args"]=> array(1) { ["package"]=> string(3) "foo" } ["command_name"]=> bool(false) ["command"]=> bool(false) } } --TEST-- Test for PEAR2_Console_CommandLine::parse() with a web request 1 --GET-- version=1 --FILE-- parse(); ?> --EXPECT-- some_program version 0.1.0. --TEST-- Test for PEAR2_Console_CommandLine::parse() with a web request 2 --GET-- help --FILE-- parse(); ?> --EXPECT-- Description of our parser goes here... Usage: some_program [options] Options: -t, --true test the StoreTrue action -f, --false test the StoreFalse action --int=INT test the StoreInt action --float=FLOAT test the StoreFloat action -s STRING, --string=STRING test the StoreString action -c, --counter test the Counter action --callback=callback test the Callback action -a ARRAY, --array=ARRAY test the StoreArray action -p password, --password=password test the Password action -h, --help show this help message and exit -v, --version show the program version and exit Arguments: simple test a simple argument multiple test a multiple argument --TEST-- Test for PEAR2_Console_CommandLine::parse() with a web request 3 --POST-- true=1&false=1&string=foo&int=3&float=4.0&callback=somestring&-a[]=foo&-a[]=bar&-a[]=baz&simple=foo&multiple=bar --FILE-- parse(); var_dump($result->options); var_dump($result->args); ?> --EXPECT-- array(11) { ["true"]=> bool(true) ["false"]=> bool(false) ["int"]=> int(3) ["float"]=> float(4) ["string"]=> string(3) "foo" ["counter"]=> NULL ["callback"]=> string(20) "foo__fbzrfgevat__bar" ["array"]=> array(3) { [0]=> string(3) "foo" [1]=> string(3) "bar" [2]=> string(3) "baz" } ["password"]=> NULL ["help"]=> NULL ["version"]=> NULL } array(2) { ["simple"]=> string(3) "foo" ["multiple"]=> array(1) { [0]=> string(3) "bar" } } true test zip/unzip files 1.0.0 compress zp zip zip given files in the destination file a list of files to zip together true path to the zip file to generate destination directory unzip uzp unzip given file in the destination dir path to the zip file to unzip * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version SVN: $Id$ */ // ensure that errors will be printed error_reporting(E_ALL | E_STRICT); ini_set('display_errors',true); set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ . '/../src/'); // uncomment this when package won't be in the SandBox anymore // $basedir = __DIR__ . '/../..'; $basedir = dirname(__FILE__) . '/../../..'; require_once $basedir . '/autoload.php'; /** * A dummy callback for tests purposes. * * @param mixed $value value provided by the user * @param object $option the option instance * @param object $result the result instance * @param object $parser the parser instance * @param array $params optional params array * * @return string */ function rot13Callback($value, $option, $result, $parser, $params=array()) { $ret = ''; if (isset($params['prefix'])) { $ret .= $params['prefix'] . '__'; } $ret .= str_rot13($value); if (isset($params['suffix'])) { $ret .= '__' . $params['suffix']; } return $ret; } // }}} // buildParser1() {{{ /** * Build a parser instance and return it. * * @return object PEAR2_Console_CommandLine instance */ function buildParser1() { $parser = new PEAR2_Console_CommandLine(); $parser->name = 'some_program'; $parser->version = '0.1.0'; $parser->description = 'Description of our parser goes here...'; // add options $parser->addOption('true', array( 'short_name' => '-t', 'long_name' => '--true', 'action' => 'StoreTrue', 'description' => 'test the StoreTrue action' )); $parser->addOption('false', array( 'short_name' => '-f', 'long_name' => '--false', 'action' => 'StoreFalse', 'description' => 'test the StoreFalse action' )); $parser->addOption('int', array( 'long_name' => '--int', 'action' => 'StoreInt', 'description' => 'test the StoreInt action', 'help_name' => 'INT', 'default' => 1 )); $parser->addOption('float', array( 'long_name' => '--float', 'action' => 'StoreFloat', 'description' => 'test the StoreFloat action', 'help_name' => 'FLOAT', 'default' => 1.0 )); $parser->addOption('string', array( 'short_name' => '-s', 'long_name' => '--string', 'action' => 'StoreString', 'description' => 'test the StoreString action', 'help_name' => 'STRING', 'choices' => array('foo', 'bar', 'baz') )); $parser->addOption('counter', array( 'short_name' => '-c', 'long_name' => '--counter', 'action' => 'Counter', 'description' => 'test the Counter action' )); $parser->addOption('callback', array( 'long_name' => '--callback', 'action' => 'Callback', 'description' => 'test the Callback action', 'callback' => 'rot13Callback', 'action_params' => array('prefix' => 'foo', 'suffix' => 'bar') )); $parser->addOption('array', array( 'short_name' => '-a', 'long_name' => '--array', 'action' => 'StoreArray', 'help_name' => 'ARRAY', 'description' => 'test the StoreArray action' )); $parser->addOption('password', array( 'short_name' => '-p', 'long_name' => '--password', 'action' => 'Password', 'description' => 'test the Password action' )); $parser->addArgument('simple', array( 'description' => 'test a simple argument' )); $parser->addArgument('multiple', array( 'description' => 'test a multiple argument', 'multiple' => true, 'optional' => true )); return $parser; } // }}} // buildParser2() {{{ /** * Build a parser instance and return it. * * @return object PEAR2_Console_CommandLine instance */ function buildParser2() { $parser = new PEAR2_Console_CommandLine(); $parser->name = 'some_program'; $parser->version = '0.1.0'; $parser->description = 'Description of our parser goes here...'; // add general options $parser->addOption('verbose', array( 'short_name' => '-v', 'long_name' => '--verbose', 'action' => 'StoreTrue', 'description' => 'verbose mode' )); $parser->addOption('logfile', array( 'short_name' => '-l', 'long_name' => '--logfile', 'action' => 'StoreString', 'description' => 'path to logfile' )); // install subcommand $cmd1 = $parser->addCommand('install', array( 'description' => 'install given package', 'aliases' => array('inst', 'instbis'), )); $cmd1->addOption('force', array( 'short_name' => '-f', 'long_name' => '--force', 'action' => 'StoreTrue', 'description' => 'force installation' )); $cmd1->addArgument('package', array( 'description' => 'package to install' )); // uninstall subcommand $cmd2 = $parser->addCommand('uninstall', array( 'description' => 'uninstall given package' )); $cmd2->addArgument('package', array( 'description' => 'package to uninstall' )); return $parser; } // }}} // buildParser3() {{{ /** * Build a parser instance and return it. * * @return object PEAR2_Console_CommandLine instance */ function buildParser3() { $parser = new PEAR2_Console_CommandLine(); $parser->name = 'some_program'; $parser->version = '0.1.0'; $parser->description = 'Description of our parser goes here...'; // we force options default values $parser->force_options_defaults = true; // add options $parser->addOption('true', array( 'short_name' => '-t', 'long_name' => '--true', 'action' => 'StoreTrue', 'description' => 'test the StoreTrue action', )); $parser->addOption('false', array( 'short_name' => '-f', 'long_name' => '--false', 'action' => 'StoreFalse', 'description' => 'test the StoreFalse action', )); $parser->addOption('int', array( 'long_name' => '--int', 'action' => 'StoreInt', 'description' => 'test the StoreInt action', 'help_name' => 'INT', )); $parser->addOption('float', array( 'long_name' => '--float', 'action' => 'StoreFloat', 'description' => 'test the StoreFloat action', 'help_name' => 'FLOAT', )); $parser->addOption('string', array( 'short_name' => '-s', 'long_name' => '--string', 'action' => 'StoreString', 'description' => 'test the StoreString action', 'help_name' => 'STRING', 'choices' => array('foo', 'bar', 'baz') )); $parser->addOption('counter', array( 'short_name' => '-c', 'long_name' => '--counter', 'action' => 'Counter', 'description' => 'test the Counter action' )); $parser->addOption('callback', array( 'long_name' => '--callback', 'action' => 'Callback', 'description' => 'test the Callback action', 'callback' => 'rot13Callback', 'action_params' => array('prefix' => 'foo', 'suffix' => 'bar') )); $parser->addOption('array', array( 'short_name' => '-a', 'long_name' => '--array', 'action' => 'StoreArray', 'help_name' => 'ARRAY', 'description' => 'test the StoreArray action' )); $parser->addOption('password', array( 'short_name' => '-p', 'long_name' => '--password', 'action' => 'Password', 'description' => 'test the Password action' )); return $parser; } // }}} // CustomRenderer() {{{ /** * Some custom renderer for tests purposes. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ class CustomRenderer implements PEAR2_Console_CommandLine_Renderer { // usage() {{{ /** * Return the full usage message * * @return string the usage message * @access public */ public function usage() { return __METHOD__ . '()'; } // }}} // error() {{{ /** * Return a formatted error message * * @param string $error the error message to format * * @return string the error string * @access public */ public function error($error) { return __METHOD__ . "($error)"; } // }}} // version() {{{ /** * Return the program version string * * @return string the version string * @access public */ public function version() { return __METHOD__ . '()'; } // }}} } // }}} // CustomOutputter() {{{ /** * Some custom outputter for tests purposes. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ class CustomOutputter implements PEAR2_Console_CommandLine_Outputter { // stdout() {{{ /** * Called for stdout messages. * * @param string $msg the message to output * * @return void * @access public */ public function stdout($msg) { echo "STDOUT >> $msg\n"; } // }}} // stderr() {{{ /** * Called for stderr messages. * * @param string $msg the message to output * * @return void * @access public */ public function stderr($msg) { echo "STDERR >> $msg\n"; } // }}} } // }}} // CustomMessageProvider() {{{ /** * Some custom message provider for tests purposes. * * @category Console * @package PEAR2_Console_CommandLine * @author David JEAN LOUIS * @copyright 2007-2009 David JEAN LOUIS * @license http://opensource.org/licenses/mit-license.php MIT License * @version Release: @package_version@ * @link http://pear.php.net/package/Console_CommandLine * @since File available since release 0.1.0 */ class CustomMessageProvider implements PEAR2_Console_CommandLine_MessageProvider { // get() {{{ /** * Retrieve the given string identifier corresponding message. * * @param string $code the string identifier of the message * @param array $vars an array of template variables * * @return string * @access public */ public function get($code, $vars = array()) { return $code; } // }}} } // }}} ?> doc.php.net PHP Documentation team phpdocs http://doc.php.net/rest/ http://doc.php.net/rest/ pear.php.net pear PHP Extension and Application Repository http://pear.php.net/rest/ http://pear.php.net/rest/ http://pear.php.net/rest/ http://pear.php.net/rest/ http://us.pear.php.net/rest/ http://us.pear.php.net/rest/ http://us.pear.php.net/rest/ http://us.pear.php.net/rest/ https://de.pear.php.net:3452/rest/ https://de.pear.php.net:3452/rest/ https://de.pear.php.net:3452/rest/ https://de.pear.php.net:3452/rest/ pear2.php.net pear2 PEAR packages for PHP 5.3+ installed by Pyrus http://pear2.php.net/rest/ http://pear2.php.net/rest/ http://pear2.php.net/rest/ http://pear2.php.net/rest/ pecl.php.net pecl PHP Extension Community Library PEAR_Validator_PECL logintest package.listLatestReleases package.listAll package.info package.getDownloadURL package.getDepDownloadURL package.search channel.listAll http://pecl.php.net/rest/ http://pecl.php.net/rest/ __uri __uri Pseudo-channel for static packages **** -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIRANAeQJAAAEZSAAAAAQAAAAQwDQYJKoZIhvcNAQEFBQAw gYkxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJEQzETMBEGA1UEBxMKV2FzaGluZ3Rv bjEXMBUGA1UEChMOQUJBLkVDT00sIElOQy4xGTAXBgNVBAMTEEFCQS5FQ09NIFJv b3QgQ0ExJDAiBgkqhkiG9w0BCQEWFWFkbWluQGRpZ3NpZ3RydXN0LmNvbTAeFw05 OTA3MTIxNzMzNTNaFw0wOTA3MDkxNzMzNTNaMIGJMQswCQYDVQQGEwJVUzELMAkG A1UECBMCREMxEzARBgNVBAcTCldhc2hpbmd0b24xFzAVBgNVBAoTDkFCQS5FQ09N LCBJTkMuMRkwFwYDVQQDExBBQkEuRUNPTSBSb290IENBMSQwIgYJKoZIhvcNAQkB FhVhZG1pbkBkaWdzaWd0cnVzdC5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw ggEKAoIBAQCx0xHgeVVDBwhMywVCAOINg0Y95JO6tgbTDVm9PsHOQ2cBiiGo77zM 0KLMsFWWU4RmBQDaREmA2FQKpSWGlO1jVv9wbKOhGdJ4vmgqRF4vz8wYXke8OrFG PR7wuSw0X4x8TAgpnUBV6zx9g9618PeKgw6hTLQ6pbNfWiKX7BmbwQVo/ea3qZGU LOR4SCQaJRk665WcOQqKz0Ky8BzVX/tr7WhWezkscjiw7pOp03t3POtxA6k4ShZs iSrK2jMTecJVjO2cu/LLWxD4LmE1xilMKtAqY9FlWbT4zfn0AIS2V0KFnTKo+SpU +/94Qby9cSj0u5C8/5Y0BONFnqFGKECBAgMBAAGjFjAUMBIGA1UdEwEB/wQIMAYB Af8CAQgwDQYJKoZIhvcNAQEFBQADggEBAARvJYbk5pYntNlCwNDJALF/VD6Hsm0k qS8Kfv2kRLD4VAe9G52dyntQJHsRW0mjpr8SdNWJt7cvmGQlFLdh6X9ggGvTZOir vRrWUfrAtF13Gn9kCF55xgVM8XrdTX3O5kh7VNJhkoHWG9YA8A6eKHegTYjHInYZ w8eeG6Z3ePhfm1bR8PIXrI6dWeYf/le22V7hXZ9F7GFoGUHhsiAm/lowdiT/QHI8 eZ98IkirRs3bs4Ysj78FQdPB4xTjQRcm0HyncUwZ6EoPclgxfexgeqMiKL0ZJGA/ O4dzwGvky663qyVDslUte6sGDnVdNOVdc22esnVApVnJTzFxiNmIf1Q= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC +Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X 7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz 43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV 6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH 1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF 62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh 4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G 87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i 2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no xqE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym 1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb 2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC 206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 +L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw RY8mkaKO/qk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0 aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyOTA2MDAwMFoXDTM3MTEyMDE1 MDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnej8Mlo2k06AX3dLm/WpcZuS+U 0pPlLYnKhHw/EEMbjIt8hFj4JHxIzyr9wBXZGH6EGhfT257XyuTZ16pYUYfw8ItI TuLCxFlpMGK2MKKMCxGZYTVtfu/FsRkGIBKOQuHfD5YQUqjPnF+VFNivO3ULMSAf RC+iYkGzuxgh28pxPIzstrkNn+9R7017EvILDOGsQI93f7DKeHEMXRZxcKLXwjqF zQ6axOAAsNUl6twr5JQtOJyJQVdkKGUZHLZEtMgxa44Be3ZZJX8VHIQIfHNlIAqh BC4aMqiaILGcLCFZ5/vP7nAtCMpjPiybkxlqpMKX/7eGV4iFbJ4VFitNLLMCAwEA AaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUoTYwFsuGkABFgFOxj8jY PXy+XxIwHwYDVR0jBBgwFoAUoTYwFsuGkABFgFOxj8jYPXy+XxIwDgYDVR0PAQH/ BAQDAgGGMA0GCSqGSIb3DQEBBQUAA4IBAQCKIBilvrMvtKaEAEAwKfq0FHNMeUWn 9nDg6H5kHgqVfGphwu9OH77/yZkfB2FK4V1Mza3u0FIy2VkyvNp5ctZ7CegCgTXT Ct8RHcl5oIBN/lrXVtbtDyqvpxh1MwzqwWEFT2qaifKNuZ8u77BfWgDrvq2g+EQF Z7zLBO+eZMXpyD8Fv8YvBxzDNnGGyjhmSs3WuEvGbKeXO/oTLW4jYYehY0KswsuX n2Fozy1MBJ3XJU8KDk2QixhWqJNIV9xvrr2eZ1d3iVCzvhGbRWeDhhmH05i9CBoW H1iCC+GWaQVLjuyDUTEH1dSf/1l7qG6Fz9NLqUmwX7A5KGgOc90lmt4S -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF5jCCA86gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBgzELMAkGA1UEBhMCVVMx HTAbBgNVBAoTFEFPTCBUaW1lIFdhcm5lciBJbmMuMRwwGgYDVQQLExNBbWVyaWNh IE9ubGluZSBJbmMuMTcwNQYDVQQDEy5BT0wgVGltZSBXYXJuZXIgUm9vdCBDZXJ0 aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyOTA2MDAwMFoXDTM3MDkyODIz NDMwMFowgYMxCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRBT0wgVGltZSBXYXJuZXIg SW5jLjEcMBoGA1UECxMTQW1lcmljYSBPbmxpbmUgSW5jLjE3MDUGA1UEAxMuQU9M IFRpbWUgV2FybmVyIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIw DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3WggWmRToVbEbJGv8x4vmh6mJ 7ouZzU9AhqS2TcnZsdw8TQ2FTBVsRotSeJ/4I/1n9SQ6aF3Q92RhQVSji6UI0ilb m2BPJoPRYxJWSXakFsKlnUWsi4SVqBax7J/qJBrvuVdcmiQhLE0OcR+mrF1FdAOY xFSMFkpBd4aVdQxHAWZg/BXxD+r1FHjHDtdugRxev17nOirYlxcwfACtCJ0zr7iZ YYCLqJV+FNwSbKTQ2O9ASQI2+W6p1h2WVgSysy0WVoaP2SBXgM1nEG2wTPDaRrbq JS5Gr42whTg0ixQmgiusrpkLjhTXUr2eacOGAgvqdnUxCc4zGSGFQ+aJLZ8lN2fx I2rSAG2X+Z/nKcrdH9cG6rjJuQkhn8g/BsXS6RJGAE57COtCPStIbp1n3UsC5ETz kxmlJ85per5n0/xQpCyrw2u544BMzwVhSyvcG7mm0tCq9Stz+86QNZ8MUhy/XCFh EVsVS6kkUfykXPcXnbDS+gfpj1bkGoxoigTTfFrjnqKhynFbotSg5ymFXQNoKk/S Btc9+cMDLz9l+WceR0DTYw/j1Y75hauXTLPXJuuWCpTehTacyH+BCQJJKg71ZDIM gtG6aoIbs0t0EfOMd9afv9w3pKdVBC/UMejTRrkDfNoSTllkt1ExMVCgyhwn2RAu rda9EGYrw7AiShJbAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FE9pbQN+nZ8HGEO8txBO1b+pxCAoMB8GA1UdIwQYMBaAFE9pbQN+nZ8HGEO8txBO 1b+pxCAoMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAO/Ouyugu h4X7ZVnnrREUpVe8WJ8kEle7+z802u6teio0cnAxa8cZmIDJgt43d15Ui47y6mdP yXSEkVYJ1eV6moG2gcKtNuTxVBFT8zRFASbI5Rq8NEQh3q0l/HYWdyGQgJhXnU7q 7C+qPBR7V8F+GBRn7iTGvboVsNIYvbdVgaxTwOjdaRITQrcCtQVBynlQboIOcXKT RuidDV29rs4prWPVVRaAMCf/drr3uNZK49m1+VLQTkCpx+XCMseqdiThawVQ68W/ ClTluUI8JPu3B5wwn3la5uBAUhX0/Kr0VvlEl4ftDmVyXr4m+02kLQgH3thcoNyB M5kYJRF3p+v9WAksmWsbivNSPxpNSGDxoPYzAlOL7SUJuA0t7Zdz7NeWH45gDtoQ my8YJPamTQr5O8t1wswvziRpyQoijlmn94IM19drNZxDAGrElWe6nEXLuA4399xO AU++CrYD062KRffaJ00psUjf5BHklka9bAI+1lHIlRcBFanyqqryvy9lG2/QuRqT 9Y41xICHPpQvZuTpqP9BnHAqTyo5GJUefvthATxRCC4oGKQWDzH9OmwjkyB24f0H hdFbP9IcczLd+rn4jM8Ch3qaluTtT4mNU0OrDhPAARW0eTjb/G49nlG2uBOLZ8/5 fNkiHfZdxRwBL5joeiQYvITX+txyW/fBOmg= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1 dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0 MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5 quGnM/b9Sh/22WA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFLDCCBBSgAwIBAgIEOU99hzANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJX VzESMBAGA1UEChMJYmVUUlVTVGVkMRswGQYDVQQDExJiZVRSVVNUZWQgUm9vdCBD QXMxGjAYBgNVBAMTEWJlVFJVU1RlZCBSb290IENBMB4XDTAwMDYyMDE0MjEwNFoX DTEwMDYyMDEzMjEwNFowWjELMAkGA1UEBhMCV1cxEjAQBgNVBAoTCWJlVFJVU1Rl ZDEbMBkGA1UEAxMSYmVUUlVTVGVkIFJvb3QgQ0FzMRowGAYDVQQDExFiZVRSVVNU ZWQgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANS0c3oT CjhVAb6JVuGUntS+WutKNHUbYSnE4a0IYCF4SP+00PpeQY1hRIfo7clY+vyTmt9P 6j41ffgzeubx181vSUs9Ty1uDoM6GHh3o8/n9E1z2Jo7Gh2+lVPPIJfCzz4kUmwM jmVZxXH/YgmPqsWPzGCgc0rXOD8Vcr+il7dw6K/ifhYGTPWqZCZyByWtNfwYsSbX 2P8ZDoMbjNx4RWc0PfSvHI3kbWvtILNnmrRhyxdviTX/507AMhLn7uzf/5cwdO2N R47rtMNE5qdMf1ZD6Li8tr76g5fmu/vEtpO+GRg+jIG5c4gW9JZDnGdzF5DYCW5j rEq2I8QBoa2k5MUCAwEAAaOCAfgwggH0MA8GA1UdEwEB/wQFMAMBAf8wggFZBgNV HSAEggFQMIIBTDCCAUgGCisGAQQBsT4BAAAwggE4MIIBAQYIKwYBBQUHAgIwgfQa gfFSZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1 bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0 ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGFuZCBjZXJ0aWZpY2F0aW9uIHBy YWN0aWNlIHN0YXRlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IGJlVFJVU1Rl ZCdzIHdlYiBzaXRlLCBodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0L3Rl cm1zMDEGCCsGAQUFBwIBFiVodHRwczovL3d3dy5iZVRSVVNUZWQuY29tL3ZhdWx0 L3Rlcm1zMDQGA1UdHwQtMCswKaAnoCWkIzAhMRIwEAYDVQQKEwliZVRSVVNUZWQx CzAJBgNVBAYTAldXMB0GA1UdDgQWBBQquZtpLjub2M3eKjEENGvKBxirZzAfBgNV HSMEGDAWgBQquZtpLjub2M3eKjEENGvKBxirZzAOBgNVHQ8BAf8EBAMCAf4wDQYJ KoZIhvcNAQEFBQADggEBAHlh26Nebhax6nZR+csVm8tpvuaBa58oH2U+3RGFktTo Qb9+M70j5/Egv6S0phkBxoyNNXxlpE8JpNbYIxUFE6dDea/bow6be3ga8wSGWsb2 jCBHOElQBp1yZzrwmAOtlmdE/D8QDYZN5AA7KXvOOzuZhmElQITcE2K3+spZ1gMe 1lMBzW1MaFVA4e5rxyoAAEiCswoBw2AqDPeCNe5IhpbkdNQ96gFxugR1QKepfzk5 mlWXKWWuGVUlBXJH0+gY3Ljpr0NzARJ0o+FcXxVdJPP55PS2Z2cS52QiivalQaYc tmBjRYoQtLpGEK5BV2VsPyMQPyEQWbfkQN0mDCP2qq4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFajCCBFKgAwIBAgIEPLU9RjANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq YmVUUlVTVGVkIFJvb3QgQ0EtQmFsdGltb3JlIEltcGxlbWVudGF0aW9uMB4XDTAy MDQxMTA3Mzg1MVoXDTIyMDQxMTA3Mzg1MVowZjESMBAGA1UEChMJYmVUUlVTVGVk MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl ZCBSb290IENBLUJhbHRpbW9yZSBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBALx+xDmcjOPWHIb/ymKt4H8wRXqOGrO4x/nRNv8i 805qX4QQ+2aBw5R5MdKR4XeOGCrDFN5R9U+jK7wYFuK13XneIviCfsuBH/0nLI/6 l2Qijvj/YaOcGx6Sj8CoCd8JEey3fTGaGuqDIQY8n7pc/5TqarjDa1U0Tz0yH92B FODEPM2dMPgwqZfT7syj0B9fHBOB1BirlNFjw55/NZKeX0Tq7PQiXLfoPX2k+Ymp kbIq2eszh+6l/ePazIjmiSZuxyuC0F6dWdsU7JGDBcNeDsYq0ATdcT0gTlgn/FP7 eHgZFLL8kFKJOGJgB7Sg7KxrUNb9uShr71ItOrL/8QFArDcCAwEAAaOCAh4wggIa MA8GA1UdEwEB/wQFMAMBAf8wggG1BgNVHSAEggGsMIIBqDCCAaQGDysGAQQBsT4A AAEJKIORMTCCAY8wggFIBggrBgEFBQcCAjCCAToaggE2UmVsaWFuY2Ugb24gb3Ig dXNlIG9mIHRoaXMgQ2VydGlmaWNhdGUgY3JlYXRlcyBhbiBhY2tub3dsZWRnbWVu dCBhbmQgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJk IHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgdGhlIENlcnRpZmljYXRpb24g UHJhY3RpY2UgU3RhdGVtZW50IGFuZCB0aGUgUmVseWluZyBQYXJ0eSBBZ3JlZW1l bnQsIHdoaWNoIGNhbiBiZSBmb3VuZCBhdCB0aGUgYmVUUlVTVGVkIHdlYiBzaXRl LCBodHRwOi8vd3d3LmJldHJ1c3RlZC5jb20vcHJvZHVjdHNfc2VydmljZXMvaW5k ZXguaHRtbDBBBggrBgEFBQcCARY1aHR0cDovL3d3dy5iZXRydXN0ZWQuY29tL3By b2R1Y3RzX3NlcnZpY2VzL2luZGV4Lmh0bWwwHQYDVR0OBBYEFEU9w6nR3D8kVpgc cxiIav+DR+22MB8GA1UdIwQYMBaAFEU9w6nR3D8kVpgccxiIav+DR+22MA4GA1Ud DwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEASZK8o+6svfoNyYt5hhwjdrCA WXf82n+0S9/DZEtqTg6t8n1ZdwWtColzsPq8y9yNAIiPpqCy6qxSJ7+hSHyXEHu6 7RMdmgduyzFiEuhjA6p9beP4G3YheBufS0OM00mG9htc9i5gFdPp43t1P9ACg9AY gkHNZTfqjjJ+vWuZXTARyNtIVBw74acT02pIk/c9jH8F6M7ziCpjBLjqflh8AXtb 4cV97yHgjQ5dUX2xZ/2jvTg2xvI4hocalmhgRvsoFEdV4aeADGvi6t9NfJBIoDa9 CReJf8Py05yc493EG931t3GzUwWJBtDLSoDByFOQtTwxiBdQn8nEDovYqAJjDQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGUTCCBTmgAwIBAgIEPLVPQDANBgkqhkiG9w0BAQUFADBmMRIwEAYDVQQKEwli ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEzMDEGA1UEAxMq YmVUUlVTVGVkIFJvb3QgQ0EgLSBFbnRydXN0IEltcGxlbWVudGF0aW9uMB4XDTAy MDQxMTA4MjQyN1oXDTIyMDQxMTA4NTQyN1owZjESMBAGA1UEChMJYmVUUlVTVGVk MRswGQYDVQQLExJiZVRSVVNUZWQgUm9vdCBDQXMxMzAxBgNVBAMTKmJlVFJVU1Rl ZCBSb290IENBIC0gRW50cnVzdCBJbXBsZW1lbnRhdGlvbjCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBALr0RAOqEmq1Q+xVkrYwfTVXDNvzDSduTPdQqJtO K2/b9a0cS12zqcH+e0TrW6MFDR/FNCswACnxeECypP869AGIF37m1CbTukzqMvtD d5eHI8XbQ6P1KqNRXuE70mVpflUVm3rnafdE4Fe1FehmYA8NA/uCjqPoEXtsvsdj DheT389Lrm5zdeDzqrmkwAkbhepxKYhBMvnwKg5sCfJ0a2ZsUhMfGLzUPvfYbiCe yv78IZTuEyhL11xeDGbu6bsPwTSxfwh28z0mcMmLJR1iJAzqHHVOwBLkuhMdMCkt VjMFu5dZfsZJT4nXLySotohAtWSSU1Yk5KKghbNekLQSM80CAwEAAaOCAwUwggMB MIIBtwYDVR0gBIIBrjCCAaowggGmBg8rBgEEAbE+AAACCSiDkTEwggGRMIIBSQYI KwYBBQUHAgIwggE7GoIBN1JlbGlhbmNlIG9uIG9yIHVzZSBvZiB0aGlzIENlcnRp ZmljYXRlIGNyZWF0ZXMgYW4gYWNrbm93bGVkZ21lbnQgYW5kIGFjY2VwdGFuY2Ug b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0 aW9ucyBvZiB1c2UsIHRoZSBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu dCBhbmQgdGhlIFJlbHlpbmcgUGFydHkgQWdyZWVtZW50LCB3aGljaCBjYW4gYmUg Zm91bmQgYXQgdGhlIGJlVFJVU1RlZCB3ZWIgc2l0ZSwgaHR0cHM6Ly93d3cuYmV0 cnVzdGVkLmNvbS9wcm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMEIGCCsGAQUF BwIBFjZodHRwczovL3d3dy5iZXRydXN0ZWQuY29tL3Byb2R1Y3RzX3NlcnZpY2Vz L2luZGV4Lmh0bWwwEQYJYIZIAYb4QgEBBAQDAgAHMIGJBgNVHR8EgYEwfzB9oHug eaR3MHUxEjAQBgNVBAoTCWJlVFJVU1RlZDEbMBkGA1UECxMSYmVUUlVTVGVkIFJv b3QgQ0FzMTMwMQYDVQQDEypiZVRSVVNUZWQgUm9vdCBDQSAtIEVudHJ1c3QgSW1w bGVtZW50YXRpb24xDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMjA0MTEw ODI0MjdagQ8yMDIyMDQxMTA4NTQyN1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaA FH1w5a44iwY/qhwaj/nPJDCqhIQWMB0GA1UdDgQWBBR9cOWuOIsGP6ocGo/5zyQw qoSEFjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIE kDANBgkqhkiG9w0BAQUFAAOCAQEAKrgXzh8QlOu4mre5X+za95IkrNySO8cgjfKZ 5V04ocI07cUTWVwFtStPYZuR+0H8/NU8TZh2BvWBfevdkObRVlTa4y0MnxEylCIB evZsLHRnBMylj44ss0O1lKLQfelifwa+JwGDnjr9iu6YQ0pr17WXOzq/T220Y/oz ADQuLW2WyXvKmWO6vvT2MKAtmJbpVkQFqUSjYRDrgqFnXbxdJ3Wqiig2KjiS2d2k XgClzMx8KSreKJCrt+G2/30lC0DYqjSjLd4H61/OCt3Kfjp9JsFiaDrmLzfzgYYh xKlkqu9FNtEaZnz46TfW1mG+oq1I59/mdP7TbX3SJdysYlep9w== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFaDCCBFCgAwIBAgIQO1nHe81bV569N1KsdrSqGjANBgkqhkiG9w0BAQUFADBi MRIwEAYDVQQKEwliZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENB czEvMC0GA1UEAxMmYmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRp b24wHhcNMDIwNDExMTExODEzWhcNMjIwNDEyMTEwNzI1WjBiMRIwEAYDVQQKEwli ZVRSVVNUZWQxGzAZBgNVBAsTEmJlVFJVU1RlZCBSb290IENBczEvMC0GA1UEAxMm YmVUUlVTVGVkIFJvb3QgQ0EgLSBSU0EgSW1wbGVtZW50YXRpb24wggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkujQwCY5X0LkGLG9uJIAiv11DpvpPrILn HGhwhRujbrWqeNluB0s/6d/16uhUoWGKDi9pdRi3DOUUjXFumLhV/AyV0Jtu4S2I 1DpAa5LxmZZk3tv/ePTulh1HiXzUvrmIdyM6CeYEnm2qXtLIvZpOGd+J6lsOfsPk tPDgaTuID0GQ+NRxQyTBjyZLO1bp/4xsN+lFrYWMU8NghpBKlsmzVLC7F/AcRdnU GxlkVgoZ98zh/4avflherHqQH8koOUV7orbHnB/ahdQhhlkwk75TMzf270HPM8er cmsl9fNTGwxMLvF1S++gh/f+ihXQbNXL+WhTuXAVE8L1LvtDNXUtAgMBAAGjggIY MIICFDAMBgNVHRMEBTADAQH/MIIBtQYDVR0gBIIBrDCCAagwggGkBg8rBgEEAbE+ AAADCSiDkTEwggGPMEEGCCsGAQUFBwIBFjVodHRwOi8vd3d3LmJldHJ1c3RlZC5j b20vcHJvZHVjdHNfc2VydmljZXMvaW5kZXguaHRtbDCCAUgGCCsGAQUFBwICMIIB OhqCATZSZWxpYW5jZSBvbiBvciB1c2Ugb2YgdGhpcyBDZXJ0aWZpY2F0ZSBjcmVh dGVzIGFuIGFja25vd2xlZGdtZW50IGFuZCBhY2NlcHRhbmNlIG9mIHRoZSB0aGVu IGFwcGxpY2FibGUgc3RhbmRhcmQgdGVybXMgYW5kIGNvbmRpdGlvbnMgb2YgdXNl LCB0aGUgQ2VydGlmaWNhdGlvbiBQcmFjdGljZSBTdGF0ZW1lbnQgYW5kIHRoZSBS ZWx5aW5nIFBhcnR5IEFncmVlbWVudCwgd2hpY2ggY2FuIGJlIGZvdW5kIGF0IHRo ZSBiZVRSVVNUZWQgd2ViIHNpdGUsIGh0dHA6Ly93d3cuYmV0cnVzdGVkLmNvbS9w cm9kdWN0c19zZXJ2aWNlcy9pbmRleC5odG1sMAsGA1UdDwQEAwIBBjAfBgNVHSME GDAWgBSp7BR++dlDzFMrFK3P9/BZiUHNGTAdBgNVHQ4EFgQUqewUfvnZQ8xTKxSt z/fwWYlBzRkwDQYJKoZIhvcNAQEFBQADggEBANuXsHXqDMTBmMpWBcCorSZIry0g 6IHHtt9DwSwddUvUQo3neqh03GZCWYez9Wlt2ames30cMcH1VOJZJEnl7r05pmuK mET7m9cqg5c0Lcd9NUwtNLg+DcTsiCevnpL9UGGCqGAHFFPMZRPB9kdEadIxyKbd LrML3kqNWz2rDcI1UqJWN8wyiyiFQpyRQHpwKzg21eFzGh/l+n5f3NacOzDq28Bb J1zTcwfBwvNMm2+fG8oeqqg4MwlYsq78B+g23FW6L09A/nq9BqaBwZMifIYRCgZ3 SK41ty8ymmFei74pnykkiFY5LKjSq5YDWtRIn7lAhAuYaPsBQ9Yb4gmxlxw= -----END CERTIFICATE----- array ( 0 => 'AAACertificateServices', 1 => 'ABA.ECOMRootCA', 2 => 'AOLTimeWarnerRootCertificationAuthority1', 3 => 'AOLTimeWarnerRootCertificationAuthority2', 4 => 'AddTrustClass1CARoot', 5 => 'AddTrustExternalCARoot', 6 => 'AddTrustPublicCARoot', 7 => 'AddTrustQualifiedCARoot', 8 => 'AmericaOnlineRootCertificationAuthority1', 9 => 'AmericaOnlineRootCertificationAuthority2', 10 => 'AutoridaddeCertificacionFirmaprofesionalCIFA62634068', 11 => 'BaltimoreCyberTrustRoot', 12 => 'BuiltinObjectToken:DigitalSignatureTrustCo.GlobalCA1', 13 => 'BuiltinObjectToken:DigitalSignatureTrustCo.GlobalCA3', 14 => 'BuiltinObjectToken:EquifaxSecureCA', 15 => 'BuiltinObjectToken:EquifaxSecureeBusinessCA2', 16 => 'BuiltinObjectToken:GoDaddyClass2CA', 17 => 'BuiltinObjectToken:RSASecurity1024v3', 18 => 'BuiltinObjectToken:RSASecurity2048v3', 19 => 'BuiltinObjectToken:SecurityCommunicationRootCA', 20 => 'BuiltinObjectToken:StarfieldClass2CA', 21 => 'BuiltinObjectToken:TCTrustCenter,Germany,Class2CA', 22 => 'BuiltinObjectToken:TCTrustCenter,Germany,Class3CA', 23 => 'BuiltinObjectToken:TDCInternetRootCA', 24 => 'BuiltinObjectToken:TaiwanGRCA', 25 => 'BuiltinObjectToken:Verisign-RSASecureServerCA', 26 => 'BuiltinObjectToken:VerisignClass1PublicPrimaryCertificationAuthority', 27 => 'BuiltinObjectToken:VerisignClass1PublicPrimaryCertificationAuthority-G2', 28 => 'BuiltinObjectToken:VerisignClass2PublicPrimaryCertificationAuthority', 29 => 'BuiltinObjectToken:VerisignClass2PublicPrimaryCertificationAuthority-G2', 30 => 'BuiltinObjectToken:VerisignClass3PublicPrimaryCertificationAuthority', 31 => 'BuiltinObjectToken:VerisignClass3PublicPrimaryCertificationAuthority-G2', 32 => 'BuiltinObjectToken:VerisignClass4PublicPrimaryCertificationAuthority-G2', 33 => 'CACertSigningAuthority', 34 => 'COMODOCertificationAuthority', 35 => 'CertumCA', 36 => 'ChambersofCommerceRoot', 37 => 'Class2PrimaryCA', 38 => 'DSTACESCAX6', 39 => 'DSTRootCAX1', 40 => 'DSTRootCAX2', 41 => 'DSTRootCAX3', 42 => 'DigiCertAssuredIDRootCA', 43 => 'DigiCertGlobalRootCA', 44 => 'DigiCertHighAssuranceEVRootCA', 45 => 'DigiNotarRootCA', 46 => 'Entrust.netCertificationAuthority(2048)', 47 => 'Entrust.netClientCertificationAuthority', 48 => 'Entrust.netClientCertificationAuthority2', 49 => 'Entrust.netSecureServerCertificationAuthority', 50 => 'Entrust.netSecureServerCertificationAuthority2', 51 => 'EntrustRootCertificationAuthority', 52 => 'EquifaxSecureGlobaleBusinessCA-1', 53 => 'EquifaxSecureeBusinessCA-1', 54 => 'FreeSSLCertificationAuthority', 55 => 'GPRoot2', 56 => 'GTECyberTrustGlobalRoot', 57 => 'GTECyberTrustRoot', 58 => 'GeoTrustGlobalCA', 59 => 'GeoTrustGlobalCA2', 60 => 'GeoTrustPrimaryCertificationAuthority', 61 => 'GeoTrustUniversalCA', 62 => 'GeoTrustUniversalCA2', 63 => 'GlobalChambersignRoot', 64 => 'GlobalSign', 65 => 'GlobalSign2', 66 => 'GlobalSignExtendedValidationCA', 67 => 'GlobalSignRootCA', 68 => 'GoDaddySecureCertificationAuthority', 69 => 'IPSCACLASE1CertificationAuthority', 70 => 'IPSCACLASE3CertificationAuthority', 71 => 'IPSCACLASEA1CertificationAuthority', 72 => 'IPSCACLASEA3CertificationAuthority', 73 => 'IPSCAChainedCAsCertificationAuthority', 74 => 'IPSCATimestampingCertificationAuthority', 75 => 'IPSSERVIDORES', 76 => 'NetLockExpressz(ClassC)Tanusitvanykiado', 77 => 'NetLockKozjegyzoi(ClassA)Tanusitvanykiado', 78 => 'NetLockMinositettKozjegyzoi(ClassQA)Tanusitvanykiado', 79 => 'NetLockUzleti(ClassB)Tanusitvanykiado', 80 => 'NetworkSolutionsCertificateAuthority', 81 => 'QuoVadisRootCA2', 82 => 'QuoVadisRootCA3', 83 => 'QuoVadisRootCertificationAuthority', 84 => 'SecureCertificateServices', 85 => 'SecureGlobalCA', 86 => 'SecureTrustCA', 87 => 'SoneraClass1CA', 88 => 'SoneraClass2CA', 89 => 'StaatderNederlandenRootCA', 90 => 'StartComCertificationAuthority', 91 => 'SwissSignGoldCA-G2', 92 => 'SwissSignPlatinumCA-G2', 93 => 'SwissSignSilverCA-G2', 94 => 'SwisscomRootCA1', 95 => 'TDCOCESCA', 96 => 'ThawtePersonalBasicCA', 97 => 'ThawtePersonalFreemailCA', 98 => 'ThawtePersonalPremiumCA', 99 => 'ThawtePremiumServerCA', 100 => 'ThawteSGCCA', 101 => 'ThawteServerCA', 102 => 'ThawteTimestampingCA', 103 => 'TrustedCertificateServices', 104 => 'TÜRKTRUSTElektronikSertifikaHizmetSağlayıcısı', 105 => 'TÜRKTRUSTElektronikSertifikaHizmetSağlayıcısı2', 106 => 'UTN-DATACorpSGC', 107 => 'UTN-USERFirst-ClientAuthenticationandEmail', 108 => 'UTN-USERFirst-Hardware', 109 => 'UTN-USERFirst-NetworkApplications', 110 => 'UTN-USERFirst-Object', 111 => 'VeriSignClass1PublicPrimaryCertificationAuthority-G3', 112 => 'VeriSignClass2PublicPrimaryCertificationAuthority-G3', 113 => 'VeriSignClass3PublicPrimaryCertificationAuthority-G3', 114 => 'VeriSignClass3PublicPrimaryCertificationAuthority-G5', 115 => 'VeriSignClass4PublicPrimaryCertificationAuthority-G3', 116 => 'VeriSignTimeStampingAuthorityCA', 117 => 'VisaeCommerceRoot', 118 => 'WellsFargoRootCertificateAuthority', 119 => 'XRampGlobalCertificationAuthority', 120 => 'beTRUSTedRootCA', 121 => 'beTRUSTedRootCA-BaltimoreImplementation', 122 => 'beTRUSTedRootCA-EntrustImplementation', 123 => 'beTRUSTedRootCA-RSAImplementation', 124 => 'thawtePrimaryRootCA', 125 => 'valicert.com', 126 => 'valicert.com2', 127 => 'valicert.com3', )-----BEGIN CERTIFICATE----- MIIHPTCCBSWgAwIBAgIBADANBgkqhkiG9w0BAQQFADB5MRAwDgYDVQQKEwdSb290 IENBMR4wHAYDVQQLExVodHRwOi8vd3d3LmNhY2VydC5vcmcxIjAgBgNVBAMTGUNB IENlcnQgU2lnbmluZyBBdXRob3JpdHkxITAfBgkqhkiG9w0BCQEWEnN1cHBvcnRA Y2FjZXJ0Lm9yZzAeFw0wMzAzMzAxMjI5NDlaFw0zMzAzMjkxMjI5NDlaMHkxEDAO BgNVBAoTB1Jvb3QgQ0ExHjAcBgNVBAsTFWh0dHA6Ly93d3cuY2FjZXJ0Lm9yZzEi MCAGA1UEAxMZQ0EgQ2VydCBTaWduaW5nIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJ ARYSc3VwcG9ydEBjYWNlcnQub3JnMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC CgKCAgEAziLA4kZ97DYoB1CW8qAzQIxL8TtmPzHlawI229Z89vGIj053NgVBlfkJ 8BLPRoZzYLdufujAWGSuzbCtRRcMY/pnCujW0r8+55jE8Ez64AO7NV1sId6eINm6 zWYyN3L69wj1x81YyY7nDl7qPv4coRQKFWyGhFtkZip6qUtTefWIonvuLwphK42y fk1WpRPs6tqSnqxEQR5YYGUFZvjARL3LlPdCfgv3ZWiYUQXw8wWRBB0bF4LsyFe7 w2t6iPGwcswlWyCR7BYCEo8y6RcYSNDHBS4CMEK4JZwFaz+qOqfrU0j36NK2B5jc G8Y0f3/JHIJ6BVgrCFvzOKKrF11myZjXnhCLotLddJr3cQxyYN/Nb5gznZY0dj4k epKwDpUeb+agRThHqtdB7Uq3EvbXG4OKDy7YCbZZ16oE/9KTfWgu3YtLq1i6L43q laegw1SJpfvbi1EinbLDvhG+LJGGi5Z4rSDTii8aP8bQUWWHIbEZAWV/RRyH9XzQ QUxPKZgh/TMfdQwEUfoZd9vUFBzugcMd9Zi3aQaRIt0AUMyBMawSB3s42mhb5ivU fslfrejrckzzAeVLIL+aplfKkQABi6F1ITe1Yw1nPkZPcCBnzsXWWdsC4PDSy826 YreQQejdIOQpvGQpQsgi3Hia/0PsmBsJUUtaWsJx8cTLc6nloQsCAwEAAaOCAc4w ggHKMB0GA1UdDgQWBBQWtTIb1Mfz4OaO873SsDrusjkY0TCBowYDVR0jBIGbMIGY gBQWtTIb1Mfz4OaO873SsDrusjkY0aF9pHsweTEQMA4GA1UEChMHUm9vdCBDQTEe MBwGA1UECxMVaHR0cDovL3d3dy5jYWNlcnQub3JnMSIwIAYDVQQDExlDQSBDZXJ0 IFNpZ25pbmcgQXV0aG9yaXR5MSEwHwYJKoZIhvcNAQkBFhJzdXBwb3J0QGNhY2Vy dC5vcmeCAQAwDwYDVR0TAQH/BAUwAwEB/zAyBgNVHR8EKzApMCegJaAjhiFodHRw czovL3d3dy5jYWNlcnQub3JnL3Jldm9rZS5jcmwwMAYJYIZIAYb4QgEEBCMWIWh0 dHBzOi8vd3d3LmNhY2VydC5vcmcvcmV2b2tlLmNybDA0BglghkgBhvhCAQgEJxYl aHR0cDovL3d3dy5jYWNlcnQub3JnL2luZGV4LnBocD9pZD0xMDBWBglghkgBhvhC AQ0ESRZHVG8gZ2V0IHlvdXIgb3duIGNlcnRpZmljYXRlIGZvciBGUkVFIGhlYWQg b3ZlciB0byBodHRwOi8vd3d3LmNhY2VydC5vcmcwDQYJKoZIhvcNAQEEBQADggIB ACjH7pyCArpcgBLKNQodgW+JapnM8mgPf6fhjViVPr3yBsOQWqy1YPaZQwGjiHCc nWKdpIevZ1gNMDY75q1I08t0AoZxPuIrA2jxNGJARjtT6ij0rPtmlVOKTV39O9lg 18p5aTuxZZKmxoGCXJzN600BiqXfEVWqFcofN8CCmHBh22p8lqOOLlQ+TyGpkO/c gr/c6EWtTZBzCDyUZbAEmXZ/4rzCahWqlwQ3JNgelE5tDlG+1sSPypZt90Pf6DBl Jzt7u0NDY8RD97LsaMzhGY4i+5jhe1o+ATc7iwiwovOVThrLm82asduycPAtStvY sONvRUgzEv/+PDIqVPfE94rwiCPCR/5kenHA0R6mY7AHfqQv0wGP3J8rtsYIqQ+T SCX8Ev2fQtzzxD72V7DX3WnRBnc0CkvSyqD/HMaMyRa+xMwyN2hzXwj7UfdJUzYF CpUCTPJ5GhD22Dp1nPMd8aINcGeGG7MW9S/lpOt5hvk9C8JzC6WZrG/8Z7jlLwum GCSNe9FINSkYQKyTYOGWhlC0elnYjyELn8+CkcY7v2vcB5G5l1YjqrZslMZIBjzk zk6q5PYvCdxTby78dOs6Y5nCpqyJvKeyRKANihDjbPIky/qbn3BHLt4Ui9SyIAmW omTxJBzcoTWcFbLUvFUufQb1nA5V9FrWk9p2rSVzTMVD -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7 HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs 6GAqm4VKQPNriiTsBhYscw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq 7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3 0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p 26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi 1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0 eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu tGWaIZDgqtCYvDi1czyL+Nw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9 MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0 HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4 QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/ AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8 yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7 l7+ijrRU -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI 2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp +2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW /zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB ZQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFijCCA3KgAwIBAgIQDHbanJEMTiye/hXQWJM8TDANBgkqhkiG9w0BAQUFADBf MQswCQYDVQQGEwJOTDESMBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdp Tm90YXIgUm9vdCBDQTEgMB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmww HhcNMDcwNTE2MTcxOTM2WhcNMjUwMzMxMTgxOTIxWjBfMQswCQYDVQQGEwJOTDES MBAGA1UEChMJRGlnaU5vdGFyMRowGAYDVQQDExFEaWdpTm90YXIgUm9vdCBDQTEg MB4GCSqGSIb3DQEJARYRaW5mb0BkaWdpbm90YXIubmwwggIiMA0GCSqGSIb3DQEB AQUAA4ICDwAwggIKAoICAQCssFjBAL3YIQgLK5r+blYwBZ8bd5AQQVzDDYcRd46B 8cp86Yxq7Th0Nbva3/m7wAk3tJZzgX0zGpg595NvlX89ubF1h7pRSOiLcD6VBMXY tsMW2YiwsYcdcNqGtA8Ui3rPENF0NqISe3eGSnnme98CEWilToauNFibJBN4ViIl HgGLS1Fx+4LMWZZpiFpoU8W5DQI3y0u8ZkqQfioLBQftFl9VkHXYRskbg+IIvvEj zJkd1ioPgyAVWCeCLvriIsJJsbkBgWqdbZ1Ad2h2TiEqbYRAhU52mXyC8/O3AlnU JgEbjt+tUwbRrhjd4rI6y9eIOI6sWym5GdOY+RgDz0iChmYLG2kPyes4iHomGgVM ktck1JbyrFIto0fVUvY//s6EBnCmqj6i8rZWNBhXouSBbefK8GrTx5FrAoNBfBXv a5pkXuPQPOWx63tdhvvL5ndJzaNl3Pe5nLjkC1+Tz8wwGjIczhxjlaX56uF0i57p K6kwe6AYHw4YC+VbqdPRbB4HZ4+RS6mKvNJmqpMBiLKR+jFc1abBUggJzQpjotMi puih2TkGl/VujQKQjBR7P4DNG5y6xFhyI6+2Vp/GekIzKQc/gsnmHwUNzUwoNovT yD4cxojvXu6JZOkd69qJfjKmadHdzIif0dDJZiHcBmfFlHqabWJMfczgZICynkeO owIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV HQ4EFgQUiGi/4I41xDs4a2L3KDuEgcgM100wDQYJKoZIhvcNAQEFBQADggIBADsC jcs8MOhuoK3yc7NfniUTBAXT9uOLuwt5zlPe5JbF0a9zvNXD0EBVfEB/zRtfCdXy fJ9oHbtdzno5wozWmHvFg1Wo1X1AyuAe94leY12hE8JdiraKfADzI8PthV9xdvBo Y6pFITlIYXg23PFDk9Qlx/KAZeFTAnVR/Ho67zerhChXDNjU1JlWbOOi/lmEtDHo M/hklJRRl6s5xUvt2t2AC298KQ3EjopyDedTFLJgQT2EkTFoPSdE2+Xe9PpjRchM Ppj1P0G6Tss3DbpmmPHdy59c91Q2gmssvBNhl0L4eLvMyKKfyvBovWsdst+Nbwed 2o5nx0ceyrm/KkKRt2NTZvFCo+H0Wk1Ya7XkpDOtXHAd3ODy63MUkZoDweoAZbwH /M8SESIsrqC9OuCiKthZ6SnTGDWkrBFfGbW1G/8iSlzGeuQX7yCpp/Q/rYqnmgQl nQ7KN+ZQ/YxCKQSa7LnPS3K94gg2ryMvYuXKAdNw23yCIywWMQzGNgeQerEfZ1jE O1hZibCMjFCz2IbLaKPECudpSyDOwR5WS5WpI2jYMNjD67BVUc3l/Su49bsRn1NU 9jQZjHkJNsphFyUXC4KYcwx3dMPVDceoEkzHp1RxRy4sGn3J4ys7SN4nhKdjNrN9 j6BkOSQNPXuHr2ZcdBtLc7LljPCGmbjlxd+Ewbfr -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDKTCCApKgAwIBAgIENnAVljANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL EwhEU1RDQSBFMTAeFw05ODEyMTAxODEwMjNaFw0xODEyMTAxODQwMjNaMEYxCzAJ BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x ETAPBgNVBAsTCERTVENBIEUxMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQCg bIGpzzQeJN3+hijM3oMv+V7UQtLodGBmE5gGHKlREmlvMVW5SXIACH7TpWJENySZ j9mDSI+ZbZUTu0M7LklOiDfBu1h//uG9+LthzfNHwJmm8fOR6Hh8AMthyUQncWlV Sn5JTe2io74CTADKAqjuAQIxZA9SLRN0dja1erQtcQIBA6OCASQwggEgMBEGCWCG SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI RFNUQ0EgRTExDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMTAxODEw MjNagQ8yMDE4MTIxMDE4MTAyM1owCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFGp5 fpFpRhgTCgJ3pVlbYJglDqL4MB0GA1UdDgQWBBRqeX6RaUYYEwoCd6VZW2CYJQ6i +DAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG SIb3DQEBBQUAA4GBACIS2Hod3IEGtgllsofIH160L+nEHvI8wbsEkBFKg05+k7lN QseSJqBcNJo4cvj9axY+IO6CizEqkzaFI4iKPANo08kJD038bKTaKHKTDomAsH3+ gG9lbRgzl4vCa4nuYD3Im+9/KzJic5PLPON74nZ4RbyhkwS7hp86W0N6w4pl -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDKTCCApKgAwIBAgIENm7TzjANBgkqhkiG9w0BAQUFADBGMQswCQYDVQQGEwJV UzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMREwDwYDVQQL EwhEU1RDQSBFMjAeFw05ODEyMDkxOTE3MjZaFw0xODEyMDkxOTQ3MjZaMEYxCzAJ BgNVBAYTAlVTMSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4x ETAPBgNVBAsTCERTVENBIEUyMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC/ k48Xku8zExjrEH9OFr//Bo8qhbxe+SSmJIi2A7fBw18DW9Fvrn5C6mYjuGODVvso LeE4i7TuqAHhzhy2iCoiRoX7n6dwqUcUP87eZfCocfdPJmyMvMa1795JJ/9IKn3o TQPMx7JSxhcxEzu1TdvIxPbDDyQq2gyd55FbgM2UnQIBA6OCASQwggEgMBEGCWCG SAGG+EIBAQQEAwIABzBoBgNVHR8EYTBfMF2gW6BZpFcwVTELMAkGA1UEBhMCVVMx JDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UECxMI RFNUQ0EgRTIxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMTk5ODEyMDkxOTE3 MjZagQ8yMDE4MTIwOTE5MTcyNlowCwYDVR0PBAQDAgEGMB8GA1UdIwQYMBaAFB6C TShlgDzJQW6sNS5ay97u+DlbMB0GA1UdDgQWBBQegk0oZYA8yUFurDUuWsve7vg5 WzAMBgNVHRMEBTADAQH/MBkGCSqGSIb2fQdBAAQMMAobBFY0LjADAgSQMA0GCSqG SIb3DQEBBQUAA4GBAEeNg61i8tuwnkUiBbmi1gMOOHLnnvx75pO2mqWilMg0HZHR xdf0CiUPPXiBng+xZ8SQTGPdXqfiup/1902lMXucKS1M/mQ+7LZT/uqb7YLbdHVL B3luHtgZg3Pe9T7Qtd7nS2h9Qy4qIOF+oHhEngj1mPnHfxsb1gYgAlihw6ID -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7 gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/ h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2 9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID2DCCAsACEQDQHkCLAAACfAAAAAIAAAABMA0GCSqGSIb3DQEBBQUAMIGpMQsw CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE CxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDExITAfBgkqhkiG9w0B CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODEyMDExODE4NTVaFw0wODExMjgx ODE4NTVaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0 IENvLjERMA8GA1UECxMIRFNUQ0EgWDExFjAUBgNVBAMTDURTVCBSb290Q0EgWDEx ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBANLGJrbnpT3BxGjVUG9TxW9JEwm4ryxIjRRqoxdf WvnTLnUv2Chi0ZMv/E3Uq4flCMeZ55I/db3rJbQVwZsZPdJEjdd0IG03Ao9pk1uK xBmd9LIO/BZsubEFkoPRhSxglD5FVaDZqwgh5mDoO3TymVBRaNADLbGAvqPYUrBE zUNKcI5YhZXhTizWLUFv1oTnyJhEykfbLCSlaSbPa7gnYsP0yXqSI+0TZ4KuRS5F 5X5yP4WdlGIQ5jyRoa13AOAV7POEgHJ6jm5gl8ckWRA0g1vhpaRptlc1HHhZxtMv OnNn7pTKBBMFYgZwI7P0fO5F2WQLW0mqpEPOJsREEmy43XkCAwEAATANBgkqhkiG 9w0BAQUFAAOCAQEAojeyP2n714Z5VEkxlTMr89EJFEliYIalsBHiUMIdBlc+Legz ZL6bqq1fG03UmZWii5rJYnK1aerZWKs17RWiQ9a2vAd5ZWRzfdd5ynvVWlHG4VME lo04z6MXrDlxawHDi1M8Y+nuecDkvpIyZHqzH5eUYr3qsiAVlfuX8ngvYzZAOONG Dx3drJXK50uQe7FLqdTF65raqtWjlBRGjS0f8zrWkzr2Pnn86Oawde3uPclwx12q gUtGJRzHbBXjlU4PqjI3lAoXJJIThFjSY28r9+ZbYgsTF7ANUkz+/m9c4pFuHf2k Ytdo+o56T9II2pPc8JIRetDccpMMc5NihWjQ9A== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID2DCCAsACEQDQHkCLAAB3bQAAAAEAAAAEMA0GCSqGSIb3DQEBBQUAMIGpMQsw CQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMOU2FsdCBMYWtlIENp dHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0IENvLjERMA8GA1UE CxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIxITAfBgkqhkiG9w0B CQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTAeFw05ODExMzAyMjQ2MTZaFw0wODExMjcy MjQ2MTZaMIGpMQswCQYDVQQGEwJ1czENMAsGA1UECBMEVXRhaDEXMBUGA1UEBxMO U2FsdCBMYWtlIENpdHkxJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRydXN0 IENvLjERMA8GA1UECxMIRFNUQ0EgWDIxFjAUBgNVBAMTDURTVCBSb290Q0EgWDIx ITAfBgkqhkiG9w0BCQEWEmNhQGRpZ3NpZ3RydXN0LmNvbTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBANx18IzAdZaawGIfJvfE4Zrq4FZzW5nNAUSoCLbV p9oaBBg5kkp4o4HC9Xd6ULRw/5qrxsfKboNPQpj7Jgva3G3WqZlVUmfpKAOS3OWw BZoPFflrWXJW8vo5/Kpo7g8fEIMv/J36F5bdguPmRX3AS4BEH+0s4IT9kVySVGkl 5WJp3OXuAFK9MwutdQKFp2RQLcUZGTDAJtvJ0/0uma1ZtQtN1EGuhUhDWdy3qOKi 3sOP17ihYqZoUFLkzzGnlIXan0YyF1bl8utmPRL/Q9uY73fPy4GNNLHGUEom0eQ+ QVCvbK4iNC7Va26Dunm4dmVI2gkpZGMiuftHdoWMhkTLCdsCAwEAATANBgkqhkiG 9w0BAQUFAAOCAQEAtTYOXeFhKFoRZcA/gwN5Tb4opgsHAlKFzfiR0BBstWogWxyQ 2TA8xkieil5k+aFxd+8EJx8H6+Qm93N0yUQYGmbT4EOvkTvRyyzYdFQ6HE3K1GjN I3wdEJ5F6fYAbqbNGf9PLCmPV03Ed5K+4EwJ+11EhmYhqLkyolbV6YyDfFk/xPEL 553snr2cGA4+wjl5KLcDDQjLxufZATdQEOzMYRZA1K8xdHv8PzGn0EdzMzkbzE5q 10mDEQb+64JYMzJM8FasHpwvVpp7wUocpf1VNs78lk30sPDst2yC7S8xmUJMqbIN uBVd8d+6ybVK1GSYsyapMMj9puyrliGtf8J4tg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/ MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw 7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69 ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5 JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH 4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy vUxFnmG6v4SBkgPR0ml8xQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIE7TCCBFagAwIBAgIEOAOR7jANBgkqhkiG9w0BAQQFADCByTELMAkGA1UEBhMC VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MUgwRgYDVQQLFD93d3cuZW50cnVzdC5u ZXQvQ2xpZW50X0NBX0luZm8vQ1BTIGluY29ycC4gYnkgcmVmLiBsaW1pdHMgbGlh Yi4xJTAjBgNVBAsTHChjKSAxOTk5IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNV BAMTKkVudHJ1c3QubmV0IENsaWVudCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe Fw05OTEwMTIxOTI0MzBaFw0xOTEwMTIxOTU0MzBaMIHJMQswCQYDVQQGEwJVUzEU MBIGA1UEChMLRW50cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9D bGllbnRfQ0FfSW5mby9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjEl MCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMq RW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0G CSqGSIb3DQEBAQUAA4GLADCBhwKBgQDIOpleMRffrCdvkHvkGf9FozTC28GoT/Bo 6oT9n3V5z8GKUZSvx1cDR2SerYIbWtp/N3hHuzeYEpbOxhN979IMMFGpOZ5V+Pux 5zDeg7K6PvHViTs7hbqqdCz+PzFur5GVbgbUB01LLFZHGARS2g4Qk79jkJvh34zm AqTmT173iwIBA6OCAeAwggHcMBEGCWCGSAGG+EIBAQQEAwIABzCCASIGA1UdHwSC ARkwggEVMIHkoIHhoIHepIHbMIHYMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50 cnVzdC5uZXQxSDBGBgNVBAsUP3d3dy5lbnRydXN0Lm5ldC9DbGllbnRfQ0FfSW5m by9DUFMgaW5jb3JwLiBieSByZWYuIGxpbWl0cyBsaWFiLjElMCMGA1UECxMcKGMp IDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEGA1UEAxMqRW50cnVzdC5uZXQg Q2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCyg KqAohiZodHRwOi8vd3d3LmVudHJ1c3QubmV0L0NSTC9DbGllbnQxLmNybDArBgNV HRAEJDAigA8xOTk5MTAxMjE5MjQzMFqBDzIwMTkxMDEyMTkyNDMwWjALBgNVHQ8E BAMCAQYwHwYDVR0jBBgwFoAUxPucKXuXzUyW/O5bs8qZdIuV6kwwHQYDVR0OBBYE FMT7nCl7l81MlvzuW7PKmXSLlepMMAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EA BAwwChsEVjQuMAMCBJAwDQYJKoZIhvcNAQEEBQADgYEAP66K8ddmAwWePvrqHEa7 pFuPeJoSSJn59DXeDDYHAmsQOokUgZwxpnyyQbJq5wcBoUv5nyU7lsqZwz6hURzz wy5E97BnRqqS5TvaHBkUODDV4qIxJS7x7EU47fgGWANzYrAQMY9Av2TgXD7FTx/a EkP/TOYGJqibGapEPHayXOw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEgzCCA+ygAwIBAgIEOJ725DANBgkqhkiG9w0BAQQFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9HQ0NBX0NQUyBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENsaWVu dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDcxNjE2NDBaFw0yMDAy MDcxNjQ2NDBaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 LmVudHJ1c3QubmV0L0dDQ0FfQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp YWIuKTElMCMGA1UECxMcKGMpIDIwMDAgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG A1UEAxMqRW50cnVzdC5uZXQgQ2xpZW50IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCTdLS25MVL1qFof2LV7PdRV7Ny Spj10InJrWPNTTVRaoTUrcloeW+46xHbh65cJFET8VQlhK8pK5/jgOLZy93GRUk0 iJBeAZfv6lOm3fzB3ksqJeTpNfpVBQbliXrqpBFXO/x8PTbNZzVtpKklWb1m9fkn 5JVn1j+SgF7yNH0rhQIDAQABo4IBnjCCAZowEQYJYIZIAYb4QgEBBAQDAgAHMIHd BgNVHR8EgdUwgdIwgc+ggcyggcmkgcYwgcMxFDASBgNVBAoTC0VudHJ1c3QubmV0 MUAwPgYDVQQLFDd3d3cuZW50cnVzdC5uZXQvR0NDQV9DUFMgaW5jb3JwLiBieSBy ZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5l dCBMaW1pdGVkMTMwMQYDVQQDEypFbnRydXN0Lm5ldCBDbGllbnQgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEwKwYDVR0QBCQwIoAPMjAwMDAy MDcxNjE2NDBagQ8yMDIwMDIwNzE2NDY0MFowCwYDVR0PBAQDAgEGMB8GA1UdIwQY MBaAFISLdP3FjcD/J20gN0V8/i3OutN9MB0GA1UdDgQWBBSEi3T9xY3A/ydtIDdF fP4tzrrTfTAMBgNVHRMEBTADAQH/MB0GCSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4w AwIEkDANBgkqhkiG9w0BAQQFAAOBgQBObzWAO9GK9Q6nIMstZVXQkvTnhLUGJoMS hAusO7JE7r3PQNsgDrpuFOow4DtifH+La3xKp9U1PL6oXOpLu5OOgGarDyn9TS2/ GpsKkMWr2tGzhtQvJFJcem3G8v7lTRowjJDyutdKPkN+1MhQGof4T4HHdguEOnKd zmVml64mXg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIElTCCA/6gAwIBAgIEOJsRPDANBgkqhkiG9w0BAQQFADCBujEUMBIGA1UEChML RW50cnVzdC5uZXQxPzA9BgNVBAsUNnd3dy5lbnRydXN0Lm5ldC9TU0xfQ1BTIGlu Y29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMcKGMpIDIwMDAg RW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5uZXQgU2VjdXJl IFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMDAyMDQxNzIwMDBa Fw0yMDAyMDQxNzUwMDBaMIG6MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDE/MD0GA1UE CxQ2d3d3LmVudHJ1c3QubmV0L1NTTF9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMjAwMCBFbnRydXN0Lm5ldCBMaW1pdGVk MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp b24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHwV9OcfHO 8GCGD9JYf9Mzly0XonUwtZZkJi9ow0SrqHXmAGc0V55lxyKbc+bT3QgON1WqJUaB bL3+qPZ1V1eMkGxKwz6LS0MKyRFWmponIpnPVZ5h2QLifLZ8OAfc439PmrkDQYC2 dWcTC5/oVzbIXQA23mYU2m52H083jIITiQIDAQABo4IBpDCCAaAwEQYJYIZIAYb4 QgEBBAQDAgAHMIHjBgNVHR8EgdswgdgwgdWggdKggc+kgcwwgckxFDASBgNVBAoT C0VudHJ1c3QubmV0MT8wPQYDVQQLFDZ3d3cuZW50cnVzdC5uZXQvU1NMX0NQUyBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAyMDAw IEVudHJ1c3QubmV0IExpbWl0ZWQxOjA4BgNVBAMTMUVudHJ1c3QubmV0IFNlY3Vy ZSBTZXJ2ZXIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxDTALBgNVBAMTBENSTDEw KwYDVR0QBCQwIoAPMjAwMDAyMDQxNzIwMDBagQ8yMDIwMDIwNDE3NTAwMFowCwYD VR0PBAQDAgEGMB8GA1UdIwQYMBaAFMtswGvjuz7L/CKc/vuLkpyw8m4iMB0GA1Ud DgQWBBTLbMBr47s+y/winP77i5KcsPJuIjAMBgNVHRMEBTADAQH/MB0GCSqGSIb2 fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQQFAAOBgQBi24GRzsia d0Iv7L0no1MPUBvqTpLwqa+poLpIYcvvyQbvH9X07t9WLebKahlzqlO+krNQAraF JnJj2HVQYnUUt7NQGj/KEQALhUVpbbalrlHhStyCP2yMNLJ3a9kC9n8O6mUE8c1U yrrJzOCE98g+EZfTYAkYvAX/bIkz8OwVDw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi 94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP 9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFFjCCBH+gAwIBAgIBADANBgkqhkiG9w0BAQQFADCBsDELMAkGA1UEBhMCSUwx DzANBgNVBAgTBklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0 Q29tIEx0ZC4xGjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBG cmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYS YWRtaW5Ac3RhcnRjb20ub3JnMB4XDTA1MDMxNzE3Mzc0OFoXDTM1MDMxMDE3Mzc0 OFowgbAxCzAJBgNVBAYTAklMMQ8wDQYDVQQIEwZJc3JhZWwxDjAMBgNVBAcTBUVp bGF0MRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMRowGAYDVQQLExFDQSBBdXRob3Jp dHkgRGVwLjEpMCcGA1UEAxMgRnJlZSBTU0wgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkxITAfBgkqhkiG9w0BCQEWEmFkbWluQHN0YXJ0Y29tLm9yZzCBnzANBgkqhkiG 9w0BAQEFAAOBjQAwgYkCgYEA7YRgACOeyEpRKSfeOqE5tWmrCbIvNP1h3D3TsM+x 18LEwrHkllbEvqoUDufMOlDIOmKdw6OsWXuO7lUaHEe+o5c5s7XvIywI6Nivcy+5 yYPo7QAPyHWlLzRMGOh2iCNJitu27Wjaw7ViKUylS7eYtAkUEKD4/mJ2IhULpNYI LzUCAwEAAaOCAjwwggI4MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgHmMB0G A1UdDgQWBBQcicOWzL3+MtUNjIExtpidjShkjTCB3QYDVR0jBIHVMIHSgBQcicOW zL3+MtUNjIExtpidjShkjaGBtqSBszCBsDELMAkGA1UEBhMCSUwxDzANBgNVBAgT BklzcmFlbDEOMAwGA1UEBxMFRWlsYXQxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4x GjAYBgNVBAsTEUNBIEF1dGhvcml0eSBEZXAuMSkwJwYDVQQDEyBGcmVlIFNTTCBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEhMB8GCSqGSIb3DQEJARYSYWRtaW5Ac3Rh cnRjb20ub3JnggEAMB0GA1UdEQQWMBSBEmFkbWluQHN0YXJ0Y29tLm9yZzAdBgNV HRIEFjAUgRJhZG1pbkBzdGFydGNvbS5vcmcwEQYJYIZIAYb4QgEBBAQDAgAHMC8G CWCGSAGG+EIBDQQiFiBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAy BglghkgBhvhCAQQEJRYjaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL2NhLWNybC5j cmwwKAYJYIZIAYb4QgECBBsWGWh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy8wOQYJ YIZIAYb4QgEIBCwWKmh0dHA6Ly9jZXJ0LnN0YXJ0Y29tLm9yZy9pbmRleC5waHA/ YXBwPTExMTANBgkqhkiG9w0BAQQFAAOBgQBscSXhnjSRIe/bbL0BCFaPiNhBOlP1 ct8nV0t2hPdopP7rPwl+KLhX6h/BquL/lp9JmeaylXOWxkjHXo0Hclb4g4+fd68p 00UOpO6wNnQt8M2YI3s3S9r+UZjEHjQ8iP2ZO1CnwYszx8JSFhKVU2Ui77qLzmLb cCOxgN8aIDjnfg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL 5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe 2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv /NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz 4iIprn2DQKi6bA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl 4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB /wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG 9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m 1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH 6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9 MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0 Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795 B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/ AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIECjCCAvKgAwIBAgILBAAAAAABEAuMnoswDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw0wNzAxMTAwOTAw MDBaFw0xNDAxMjgxMjAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBD QSAtIFIyMRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAps8kDr4ubyiZRULEqz4h VJsL03+EcPoSs8u/h1/Gf4bTsjBc1v2t8Xvc5fhglgmSEPXQU977e35ziKxSiHtK pspJpl6op4xaEbx6guu+jOmzrJYlB5dKmSoHL7Qed7+KD7UCfBuWuMW5Oiy81hK5 61l94tAGhl9eSWq1OV6INOy8eAwImIRsqM1LtKB9DHlN8LgtyyHK1WxbfeGgKYSh +dOUScskYpEgvN0L1dnM+eonCitzkcadG6zIy+jgoPQvkItN+7A2G/YZeoXgbfJh E4hcn+CTClGXilrOr6vV96oJqmC93Nlf33KpYBNeAAHJSvo/pOoHAyECjoLKA8Kb jwIDAQABo4HhMIHeMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0G A1UdDgQWBBSb4gdXZxwewGoG3lm0mi3f3BmGLjBGBgNVHSAEPzA9MDsGBFUdIAAw MzAxBggrBgEFBQcCARYlaHR0cDovL3d3dy5nbG9iYWxzaWduLm5ldC9yZXBvc2l0 b3J5LzAzBgNVHR8ELDAqMCigJqAkhiJodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0 L3Jvb3QuY3JsMB8GA1UdIwQYMBaAFGB7ZhpFDZfKiVAvfQTNNKj//P1LMA0GCSqG SIb3DQEBBQUAA4IBAQCEmeuzQ3pcTg9cnzsuGJMExGbQjMWUmeremTFDNhx3MBb5 GevG3dwQjvKl3ZciW9r9MeKs4qljEdKkFaCgmW0JXh2Ylgt73rQFZtzx2jdQWDfW nQSCtgrmPRpyOHEWTcStQT3uJC5l/SY7SMUK1FSGuBLBtCfLKgdYzhrZQuWcUWHy AcPdwPUWQcSQZ5rBcx+0tNB6eR7+Ua30DBykB86CBdXtI0H1T5e2XmMp8rRsviTG NZPzn3/dA3Uk8NLxaYupKQWPikxy8JC/B7KPh9bWl8DW1ZV4j9tNjYodO5g85wDR 1K8jW2iz/0GhC+SlPaKG59ilq0oEO7KLAxfXOWyw -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIELjCCAxagAwIBAgILBAAAAAABEAuMoRswDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDcwMTEwMTAwMDAwWhcNMjExMjE1 MDcwMDAwWjBiMR8wHQYDVQQLExZFeHRlbmRlZCBWYWxpZGF0aW9uIENBMRMwEQYD VQQKEwpHbG9iYWxTaWduMSowKAYDVQQDEyFHbG9iYWxTaWduIEV4dGVuZGVkIFZh bGlkYXRpb24gQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC1Emt6 QwnnRLFD0fgyHn2XJOtkPy/ieGsyjWyyRakXgmd/EWGtkLNGhEAjYVDxE70u/758 XoXH2Q0c9e5Ecde4j4W2DkbMSSM1ITsl+lAtS33NK1Q/j+opI+qTDvyqhzbEZtcO c/Xc8P0H+cGPeqBI397N2xkYMMrYg/F5rDaKn6jA0onrYKTtKlXFFQxjK8cLfjHO wZsr+oalY032uubczjUhZs9YHMjzqi+My80kugG9J73V72nVdaHiorih7oivdX9f 8tIyEHc1H2n5AmKEf4onD3/6tr6Zcq59rJtyD1jDy8gStbiA4cCxwNHRhjX8cXwg Lva4p7D8hCA2NoaZAgMBAAGjgfowgfcwDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB /wQIMAYBAf8CAQAwRgYDVR0gBD8wPTA7BgRVHSAAMDMwMQYIKwYBBQUHAgEWJWh0 dHA6Ly93d3cuZ2xvYmFsc2lnbi5uZXQvcmVwb3NpdG9yeS8wHQYDVR0OBBYEFDSx +cmMazVEzAhpCu7jo7lcvxbgMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwu Z2xvYmFsc2lnbi5uZXQvcm9vdC1yMi5jcmwwEQYJYIZIAYb4QgEBBAQDAgIEMB8G A1UdIwQYMBaAFJviB1dnHB7AagbeWbSaLd/cGYYuMA0GCSqGSIb3DQEBBQUAA4IB AQBybU+HlOMsVX3g893zKcV1BqlvcyBxp44ToUfqslpgmdGX2OzuVczRM2KNsQlt VV91BvDeNGcsLeo22gMi4+pyKO/PhLeCluq2h9hvDHmuFfMk9fjEoZDfdqJ7Vydp YSP7q86RDpYznoD0OKDxocONYdc7TJWQQ9HJrfJxbrNkbqOoz1FIWl0gaftHhxyi /YAun1AZpfSRXv28aS29ZvJPGGoR2kAau9zXqFo9wz3xqpCpYW5yb3Sr5Nmtw4YV 6fjUIcqbaUPBqQwV7gED9/UQRCG8HcaBWESwxL46rA3wGkjWETHcAKFCJrZrGhqW 7Sn4QmKzhjbRjA3gNtzua7nX -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILAgAAAAAA1ni3lAUwDQYJKoZIhvcNAQEEBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw MDBaFw0xNDAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIABjAdBgNVHQ4EFgQU YHtmGkUNl8qJUC99BM00qP/8/UswDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0B AQQFAAOCAQEArqqf/LfSyx9fOSkoGJ40yWxPbxrwZKJwSk8ThptgKJ7ogUmYfQq7 5bCdPTbbjwVR/wkxKh/diXeeDy5slQTthsu0AD+EAk2AaioteAuubyuig0SDH81Q gkwkr733pbTIWg/050deSY43lv6aiAU62cDbKYfmGZZHpzqmjIs8d/5GY6dT2iHR rH5Jokvmw2dZL7OKDrssvamqQnw1wdh/1acxOk5jQzmvCLBhNIzTmKlDNPYPhyk7 ncJWWJh3w/cbrPad+D6qp1RF8PX51TFl/mtYnHGzHtdS6jIX/EBgHcl5JLL2bP2o Zg6C3ZjL2sJETy6ge/L3ayx2EYRGinij4w== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf ReYNnyicsbkqWletNw+vHX/bvZ8= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ 6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o 0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV U+4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDgDCCAmigAwIBAgICAx4wDQYJKoZIhvcNAQEFBQAwYTELMAkGA1UEBhMCVVMx DTALBgNVBAoTBFZJU0ExLzAtBgNVBAsTJlZpc2EgSW50ZXJuYXRpb25hbCBTZXJ2 aWNlIEFzc29jaWF0aW9uMRIwEAYDVQQDEwlHUCBSb290IDIwHhcNMDAwODE2MjI1 MTAwWhcNMjAwODE1MjM1OTAwWjBhMQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklT QTEvMC0GA1UECxMmVmlzYSBJbnRlcm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRp b24xEjAQBgNVBAMTCUdQIFJvb3QgMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBAKkBcLWqxEDwq2omYXkZAPy/mzdZDK9vZBv42pWUJGkzEXDK41Z0ohdX ZFwgBuHW73G3O/erwWnQSaSxBNf0V2KJXLB1LRckaeNCYOTudNargFbYiCjh+20i /SN8RnNPflRzHqgsVVh1t0zzWkWlAhr62p3DRcMiXvOL8WAp0sdftAw6UYPvMPjU 58fy+pmjIlC++QU3o63tmsPm7IgbthknGziLgE3sucfFicv8GjLtI/C1AVj59o/g halMCXI5Etuz9c9OYmTaxhkVOmMd6RdVoUwiPDQyRvhlV7or7zaMavrZ2UT0qt2E 1w0cslSsMoW0ZA3eQbuxNMYBhjJk1Z8CAwEAAaNCMEAwHQYDVR0OBBYEFJ59SzS/ ca3CBfYDdYDOqU8axCRMMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEG MA0GCSqGSIb3DQEBBQUAA4IBAQAhpXYUVfmtJ3CPPPTVbMjMCqujmAuKBiPFyWHb mQdpNSYx/scuhMKZYdQN6X0uEyt8joW2hcdLzzW2LEc9zikv2G+fiRxkk78IvXbQ kIqUs38oW26sTTMs7WXcFsziza6kPWKSBpUmv9+55CCmc2rBvveURNZNbyoLaxhN dBA2aGpawWqn3TYpjLgwi08hPwAuVDAHOrqK5MOeyti12HvOdUVmB/RtLdh6yumJ ivIj2C/LbgA2T/vwLwHMD8AiZfSr4k5hLQOCfZEWtTDVFN5ex5D8ofyrEK9ca3Cn B+8phuiyJccg/ybdd+95RBTEvd07xQObdyPsoOy7Wjm1zK0G -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIB+jCCAWMCAgGjMA0GCSqGSIb3DQEBBAUAMEUxCzAJBgNVBAYTAlVTMRgwFgYD VQQKEw9HVEUgQ29ycG9yYXRpb24xHDAaBgNVBAMTE0dURSBDeWJlclRydXN0IFJv b3QwHhcNOTYwMjIzMjMwMTAwWhcNMDYwMjIzMjM1OTAwWjBFMQswCQYDVQQGEwJV UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMRwwGgYDVQQDExNHVEUgQ3liZXJU cnVzdCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC45k+625h8cXyv RLfTD0bZZOWTwUKOx7pJjTUteueLveUFMVnGsS8KDPufpz+iCWaEVh43KRuH6X4M ypqfpX/1FZSj1aJGgthoTNE3FQZor734sLPwKfWVWgkWYXcKIiXUT0Wqx73llt/5 1KiOQswkwB6RJ0q1bQaAYznEol44AwIDAQABMA0GCSqGSIb3DQEBBAUAA4GBABKz dcZfHeFhVYAA1IFLezEPI2PnPfMD+fQ2qLvZ46WXTeorKeDWanOB5sCJo9Px4KWl IjeaY8JIILTbcuPI9tl8vrGvU9oUtCG41tWW4/5ODFlitppK+ULdjG+BqXH/9Apy bW1EDp3zdHSo1TRJ6V6e6bR64eVaH4QwnNOfpSXY -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARwxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEzMDEGA1UECxMq SVBTIENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTMwMQYD VQQDEypJUFMgQ0EgQ2hhaW5lZCBDQXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx HjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczAeFw0wMTEyMjkwMDUzNTha Fw0yNTEyMjcwMDUzNThaMIIBHDELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNl bG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQg cHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMu ZXMgQy5JLkYuICBCLTYwOTI5NDUyMTMwMQYDVQQLEypJUFMgQ0EgQ2hhaW5lZCBD QXMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxMzAxBgNVBAMTKklQUyBDQSBDaGFp bmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3DQEJARYP aXBzQG1haWwuaXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcVpJJ spQgvJhPUOtopKdJC7/SMejHT8KGC/po/UNaivNgkjWZOLtNA1IhW/A3mTXhQSCB hYEFcYGdtJUZqV92NC5jNzVXjrQfQj8VXOF6wV8TGDIxya2+o8eDZh65nAQTy2nB Bt4wBrszo7Uf8I9vzv+W6FS+ZoCua9tBhDaiPQIDAQABo4IEQzCCBD8wHQYDVR0O BBYEFKGtMbH5PuEXpsirNPxShwkeYlJBMIIBTgYDVR0jBIIBRTCCAUGAFKGtMbH5 PuEXpsirNPxShwkeYlJBoYIBJKSCASAwggEcMQswCQYDVQQGEwJFUzESMBAGA1UE CBMJQmFyY2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJ bnRlcm5ldCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0Bt YWlsLmlwcy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxMzAxBgNVBAsTKklQUyBDQSBD aGFpbmVkIENBcyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAxMqSVBT IENBIENoYWluZWQgQ0FzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8E BQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYBBQUHAwMG CCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYB BAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMw EYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlwcy5lczBC BglghkgBhvhCAQ0ENRYzQ2hhaW5lZCBDQSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkg aHR0cDovL3d3dy5pcHMuZXMvMCkGCWCGSAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlw cy5lcy9pcHMyMDAyLzA3BglghkgBhvhCAQQEKhYoaHR0cDovL3d3dy5pcHMuZXMv aXBzMjAwMi9pcHMyMDAyQ0FDLmNybDA8BglghkgBhvhCAQMELxYtaHR0cDovL3d3 dy5pcHMuZXMvaXBzMjAwMi9yZXZvY2F0aW9uQ0FDLmh0bWw/MDkGCWCGSAGG+EIB BwQsFipodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3JlbmV3YWxDQUMuaHRtbD8w NwYJYIZIAYb4QgEIBCoWKGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5 Q0FDLmh0bWwwbQYDVR0fBGYwZDAuoCygKoYoaHR0cDovL3d3dy5pcHMuZXMvaXBz MjAwMi9pcHMyMDAyQ0FDLmNybDAyoDCgLoYsaHR0cDovL3d3d2JhY2suaXBzLmVz L2lwczIwMDIvaXBzMjAwMkNBQy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAERyMJ1W WKJBGyi3leGmGpVfp3hAK+/blkr8THFj2XOVvQLiogbHvpcqk4A0hgP63Ng9HgfN HnNDJGD1HWHc3JagvPsd4+cSACczAsDAK1M92GsDgaPb1pOVIO/Tln4mkImcJpvN b2ar7QMiRDjMWb2f2/YHogF/JsRj9SVCXmK9 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl SVBTIENBIENMQVNFMSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3 DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAwNTkzOFoXDTI1MTIyNzAw NTkzOFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTEgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4FEnpwvdr9G5Q1uCN0VWcu+atsIS7ywS zHb5BlmvXSHU0lq4oNTzav3KaY1mSPd05u42veiWkXWmcSjK5yISMmmwPh5r9FBS YmL9Yzt9fuzuOOpi9GyocY3h6YvJP8a1zZRCb92CRTzo3wno7wpVqVZHYUxJZHMQ KD/Kvwn/xi8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBTrsxl588GlHKzcuh9morKb adB4CDCCAUQGA1UdIwSCATswggE3gBTrsxl588GlHKzcuh9morKbadB4CKGCARqk ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UxIENlcnRpZmljYXRpb24g QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UxIENBIENlcnRp ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEuY3JsMD8GCWCG SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D TEFTRTEuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw czIwMDIvcmVuZXdhbENMQVNFMS5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTEuaHRtbDBzBgNVHR8EbDBq MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTEu Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy Q0xBU0UxLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAK9Dr/drIyllq2tPMMi7JVBuK Yn4VLenZMdMu9Ccj/1urxUq2ckCuU3T0vAW0xtnIyXf7t/k0f3gA+Nak5FI/LEpj V4F1Wo7ojPsCwJTGKbqz3Bzosq/SLmJbGqmODszFV0VRFOlOHIilkfSj945RyKm+ hjM+5i9Ibq9UkE6tsSU= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIH6jCCB1OgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARIxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEuMCwGA1UECxMl SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMl SVBTIENBIENMQVNFMyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEeMBwGCSqGSIb3 DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMDE0NFoXDTI1MTIyNzAx MDE0NFowggESMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFyY2Vsb25hMRIwEAYD VQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5ldCBwdWJsaXNoaW5n IFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlwcy5lcyBDLkkuRi4g IEItNjA5Mjk0NTIxLjAsBgNVBAsTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxLjAsBgNVBAMTJUlQUyBDQSBDTEFTRTMgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkxHjAcBgkqhkiG9w0BCQEWD2lwc0BtYWlsLmlwcy5lczCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAqxf+DrDGaBtT8FK+n/ra+osTBLsBjzLZ H49NzjaY2uQARIwo2BNEKqRrThckQpzTiKRBgtYj+4vJhuW5qYIF3PHeH+AMmVWY 8jjsbJ0gA8DvqqPGZARRLXgNo9KoOtYkTOmWehisEyMiG3zoMRGzXwmqMHBxRiVr SXGAK5UBsh8CAwEAAaOCBEowggRGMB0GA1UdDgQWBBS4k/8uy9wsjqLnev42USGj mFsMNDCCAUQGA1UdIwSCATswggE3gBS4k/8uy9wsjqLnev42USGjmFsMNKGCARqk ggEWMIIBEjELMAkGA1UEBhMCRVMxEjAQBgNVBAgTCUJhcmNlbG9uYTESMBAGA1UE BxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJUFMgSW50ZXJuZXQgcHVibGlzaGluZyBT ZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJpcHNAbWFpbC5pcHMuZXMgQy5JLkYuICBC LTYwOTI5NDUyMS4wLAYDVQQLEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g QXV0aG9yaXR5MS4wLAYDVQQDEyVJUFMgQ0EgQ0xBU0UzIENlcnRpZmljYXRpb24g QXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYD VR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggr BgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIB FQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhC AQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGB D2lwc0BtYWlsLmlwcy5lczBBBglghkgBhvhCAQ0ENBYyQ0xBU0UzIENBIENlcnRp ZmljYXRlIGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgEC BBwWGmh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMDoGCWCGSAGG+EIBBAQtFito dHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMuY3JsMD8GCWCG SAGG+EIBAwQyFjBodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25D TEFTRTMuaHRtbD8wPAYJYIZIAYb4QgEHBC8WLWh0dHA6Ly93d3cuaXBzLmVzL2lw czIwMDIvcmVuZXdhbENMQVNFMy5odG1sPzA6BglghkgBhvhCAQgELRYraHR0cDov L3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lDTEFTRTMuaHRtbDBzBgNVHR8EbDBq MDGgL6AthitodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJDTEFTRTMu Y3JsMDWgM6Axhi9odHRwOi8vd3d3YmFjay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAy Q0xBU0UzLmNybDAvBggrBgEFBQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9v Y3NwLmlwcy5lcy8wDQYJKoZIhvcNAQEFBQADgYEAF2VcmZVDAyevJuXr0LMXI/dD qsfwfewPxqmurpYPdikc4gYtfibFPPqhwYHOU7BC0ZdXGhd+pFFhxu7pXu8Fuuu9 D6eSb9ijBmgpjnn1/7/5p6/ksc7C0YBCJwUENPjDfxZ4IwwHJPJGR607VNCv1TGy r33I6unUVtkOE7LFRVA= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm SVBTIENBIENMQVNFQTEgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT JklQUyBDQSBDTEFTRUExIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNTMyWhcNMjUxMjI3 MDEwNTMyWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALsw19zQVL01Tp/FTILq0VA8R5j8 m2mdd81u4D/u6zJfX5/S0HnllXNEITLgCtud186Nq1KLK3jgm1t99P1tCeWu4Wwd ByOgF9H5fahGRpEiqLJpxq339fWUoTCUvQDMRH/uxJ7JweaPCjbB/SQ9AaD1e+J8 eGZDi09Z8pvZ+kmzAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUZyaW56G/2LUDnf47 3P7yiuYV3TAwggFGBgNVHSMEggE9MIIBOYAUZyaW56G/2LUDnf473P7yiuYV3TCh ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTEgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUExIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMSBD QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMS5j cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2 b2NhdGlvbkNMQVNFQTEuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTEuaHRtbD8wOwYJYIZIAYb4QgEI BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMS5odG1s MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz MjAwMkNMQVNFQTEuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz MjAwMi9pcHMyMDAyQ0xBU0VBMS5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAH66iqyA AIQVCtWYUQxkxZwCWINmyq0eB81+atqAB98DNEock8RLWCA1NnHtogo1EqWmZaeF aQoO42Hu6r4okzPV7Oi+xNtff6j5YzHIa5biKcJboOeXNp13XjFr/tOn2yrb25aL H2betgPAK7N41lUH5Y85UN4HI3LmvSAUS7SG -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIH9zCCB2CgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCARQxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjEvMC0GA1UECxMm SVBTIENBIENMQVNFQTMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxLzAtBgNVBAMT JklQUyBDQSBDTEFTRUEzIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4wHAYJKoZI hvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMwHhcNMDExMjI5MDEwNzUwWhcNMjUxMjI3 MDEwNzUwWjCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXMw gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAO6AAPYaZC6tasiDsYun7o/ZttvN G7uGBiJ2MwwSbUhWYdLcgiViL5/SaTBlA0IjWLxH3GvWdV0XPOH/8lhneaDBgbHU VqLyjRGZ/fZ98cfEXgIqmuJKtROKAP2Md4bm15T1IHUuDky/dMQ/gT6DtKM4Ninn 6Cr1jIhBqoCm42zvAgMBAAGjggRTMIIETzAdBgNVHQ4EFgQUHp9XUEe2YZM50yz8 2l09BXW3mQIwggFGBgNVHSMEggE9MIIBOYAUHp9XUEe2YZM50yz82l09BXW3mQKh ggEcpIIBGDCCARQxCzAJBgNVBAYTAkVTMRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQ BgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UEChMlSVBTIEludGVybmV0IHB1Ymxpc2hp bmcgU2VydmljZXMgcy5sLjErMCkGA1UEChQiaXBzQG1haWwuaXBzLmVzIEMuSS5G LiAgQi02MDkyOTQ1MjEvMC0GA1UECxMmSVBTIENBIENMQVNFQTMgQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkxLzAtBgNVBAMTJklQUyBDQSBDTEFTRUEzIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MR4wHAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOC AQAwDAYDVR0TBAUwAwEB/zAMBgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUF BwMBBggrBgEFBQcDAgYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYB BAGCNwIBFQYKKwYBBAGCNwIBFgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglg hkgBhvhCAQEEBAMCAAcwGgYDVR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1Ud EgQTMBGBD2lwc0BtYWlsLmlwcy5lczBCBglghkgBhvhCAQ0ENRYzQ0xBU0VBMyBD QSBDZXJ0aWZpY2F0ZSBpc3N1ZWQgYnkgaHR0cDovL3d3dy5pcHMuZXMvMCkGCWCG SAGG+EIBAgQcFhpodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyLzA7BglghkgBhvhC AQQELhYsaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyQ0xBU0VBMy5j cmwwQAYJYIZIAYb4QgEDBDMWMWh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcmV2 b2NhdGlvbkNMQVNFQTMuaHRtbD8wPQYJYIZIAYb4QgEHBDAWLmh0dHA6Ly93d3cu aXBzLmVzL2lwczIwMDIvcmVuZXdhbENMQVNFQTMuaHRtbD8wOwYJYIZIAYb4QgEI BC4WLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvcG9saWN5Q0xBU0VBMy5odG1s MHUGA1UdHwRuMGwwMqAwoC6GLGh0dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvaXBz MjAwMkNMQVNFQTMuY3JsMDagNKAyhjBodHRwOi8vd3d3YmFjay5pcHMuZXMvaXBz MjAwMi9pcHMyMDAyQ0xBU0VBMy5jcmwwLwYIKwYBBQUHAQEEIzAhMB8GCCsGAQUF BzABhhNodHRwOi8vb2NzcC5pcHMuZXMvMA0GCSqGSIb3DQEBBQUAA4GBAEo9IEca 2on0eisxeewBwMwB9dbB/MjD81ACUZBYKp/nNQlbMAqBACVHr9QPDp5gJqiVp4MI 3y2s6Q73nMify5NF8bpqxmdRSmlPa/59Cy9SKcJQrSRE7SOzSMtEQMEDlQwKeAYS AfWRMS1Jjbs/RU4s4OjNtckUFQzjB4ObJnXv -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIIODCCB6GgAwIBAgIBADANBgkqhkiG9w0BAQUFADCCAR4xCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCYXJjZWxvbmExEjAQBgNVBAcTCUJhcmNlbG9uYTEuMCwGA1UE ChMlSVBTIEludGVybmV0IHB1Ymxpc2hpbmcgU2VydmljZXMgcy5sLjErMCkGA1UE ChQiaXBzQG1haWwuaXBzLmVzIEMuSS5GLiAgQi02MDkyOTQ1MjE0MDIGA1UECxMr SVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTE0MDIG A1UEAxMrSVBTIENBIFRpbWVzdGFtcGluZyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eTEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVzMB4XDTAxMTIyOTAxMTAx OFoXDTI1MTIyNzAxMTAxOFowggEeMQswCQYDVQQGEwJFUzESMBAGA1UECBMJQmFy Y2Vsb25hMRIwEAYDVQQHEwlCYXJjZWxvbmExLjAsBgNVBAoTJUlQUyBJbnRlcm5l dCBwdWJsaXNoaW5nIFNlcnZpY2VzIHMubC4xKzApBgNVBAoUImlwc0BtYWlsLmlw cy5lcyBDLkkuRi4gIEItNjA5Mjk0NTIxNDAyBgNVBAsTK0lQUyBDQSBUaW1lc3Rh bXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxNDAyBgNVBAMTK0lQUyBDQSBU aW1lc3RhbXBpbmcgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxHjAcBgkqhkiG9w0B CQEWD2lwc0BtYWlsLmlwcy5lczCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA vLjuVqWajOY2ycJioGaBjRrVetJznw6EZLqVtJCneK/K/lRhW86yIFcBrkSSQxA4 Efdo/BdApWgnMjvEp+ZCccWZ73b/K5Uk9UmSGGjKALWkWi9uy9YbLA1UZ2t6KaFY q6JaANZbuxjC3/YeE1Z2m6Vo4pjOxgOKNNtMg0GmqaMCAwEAAaOCBIAwggR8MB0G A1UdDgQWBBSL0BBQCYHynQnVDmB4AyKiP8jKZjCCAVAGA1UdIwSCAUcwggFDgBSL 0BBQCYHynQnVDmB4AyKiP8jKZqGCASakggEiMIIBHjELMAkGA1UEBhMCRVMxEjAQ BgNVBAgTCUJhcmNlbG9uYTESMBAGA1UEBxMJQmFyY2Vsb25hMS4wLAYDVQQKEyVJ UFMgSW50ZXJuZXQgcHVibGlzaGluZyBTZXJ2aWNlcyBzLmwuMSswKQYDVQQKFCJp cHNAbWFpbC5pcHMuZXMgQy5JLkYuICBCLTYwOTI5NDUyMTQwMgYDVQQLEytJUFMg Q0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MTQwMgYDVQQD EytJUFMgQ0EgVGltZXN0YW1waW5nIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MR4w HAYJKoZIhvcNAQkBFg9pcHNAbWFpbC5pcHMuZXOCAQAwDAYDVR0TBAUwAwEB/zAM BgNVHQ8EBQMDB/+AMGsGA1UdJQRkMGIGCCsGAQUFBwMBBggrBgEFBQcDAgYIKwYB BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYKKwYBBAGCNwIBFQYKKwYBBAGCNwIB FgYKKwYBBAGCNwoDAQYKKwYBBAGCNwoDBDARBglghkgBhvhCAQEEBAMCAAcwGgYD VR0RBBMwEYEPaXBzQG1haWwuaXBzLmVzMBoGA1UdEgQTMBGBD2lwc0BtYWlsLmlw cy5lczBHBglghkgBhvhCAQ0EOhY4VGltZXN0YW1waW5nIENBIENlcnRpZmljYXRl IGlzc3VlZCBieSBodHRwOi8vd3d3Lmlwcy5lcy8wKQYJYIZIAYb4QgECBBwWGmh0 dHA6Ly93d3cuaXBzLmVzL2lwczIwMDIvMEAGCWCGSAGG+EIBBAQzFjFodHRwOi8v d3d3Lmlwcy5lcy9pcHMyMDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMEUGCWCG SAGG+EIBAwQ4FjZodHRwOi8vd3d3Lmlwcy5lcy9pcHMyMDAyL3Jldm9jYXRpb25U aW1lc3RhbXBpbmcuaHRtbD8wQgYJYIZIAYb4QgEHBDUWM2h0dHA6Ly93d3cuaXBz LmVzL2lwczIwMDIvcmVuZXdhbFRpbWVzdGFtcGluZy5odG1sPzBABglghkgBhvhC AQgEMxYxaHR0cDovL3d3dy5pcHMuZXMvaXBzMjAwMi9wb2xpY3lUaW1lc3RhbXBp bmcuaHRtbDB/BgNVHR8EeDB2MDegNaAzhjFodHRwOi8vd3d3Lmlwcy5lcy9pcHMy MDAyL2lwczIwMDJUaW1lc3RhbXBpbmcuY3JsMDugOaA3hjVodHRwOi8vd3d3YmFj ay5pcHMuZXMvaXBzMjAwMi9pcHMyMDAyVGltZXN0YW1waW5nLmNybDAvBggrBgEF BQcBAQQjMCEwHwYIKwYBBQUHMAGGE2h0dHA6Ly9vY3NwLmlwcy5lcy8wDQYJKoZI hvcNAQEFBQADgYEAZbrBzAAalZHK6Ww6vzoeFAh8+4Pua2JR0zORtWB5fgTYXXk3 6MNbsMRnLWhasl8OCvrNPzpFoeo2zyYepxEoxZSPhExTCMWTs/zif/WN87GphV+I 3pGW7hdbrqXqcGV4LCFkAZXOzkw+UPS2Wctjjba9GNSHSl/c7+lW8AoM6HU= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICtzCCAiACAQAwDQYJKoZIhvcNAQEEBQAwgaMxCzAJBgNVBAYTAkVTMRIwEAYD VQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UEChMQSVBT IFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcwFQYDVQQD Ew5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwuaXBzLmVz MB4XDTk4MDEwMTIzMjEwN1oXDTA5MTIyOTIzMjEwN1owgaMxCzAJBgNVBAYTAkVT MRIwEAYDVQQIEwlCQVJDRUxPTkExEjAQBgNVBAcTCUJBUkNFTE9OQTEZMBcGA1UE ChMQSVBTIFNlZ3VyaWRhZCBDQTEYMBYGA1UECxMPQ2VydGlmaWNhY2lvbmVzMRcw FQYDVQQDEw5JUFMgU0VSVklET1JFUzEeMBwGCSqGSIb3DQEJARYPaXBzQG1haWwu aXBzLmVzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCsT1J0nznqjtwlxLyY XZhkJAk8IbPMGbWOlI6H0fg3PqHILVikgDVboXVsHUUMH2Fjal5vmwpMwci4YSM1 gf/+rHhwLWjhOgeYlQJU3c0jt4BT18g3RXIGJBK6E2Ehim51KODFDzT9NthFf+G4 Nu+z4cYgjui0OLzhPvYR3oydAQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBACzzw3lY JN7GO9HgQmm47mSzPWIBubOE3yN93ZjPEKn+ANgilgUTB1RXxafey9m4iEL2mdsU dx+2/iU94aI+A6mB0i1sR/WWRowiq8jMDQ6XXotBtDvECgZAHd1G9AHduoIuPD14 cJ58GNCr+Lh3B0Zx8coLY1xq+XKU1QFPoNtC -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC 2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0 YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0 aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4 Fp1hBWeAyNDYpQcCNJgEjTME1A== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0 dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0 N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi 3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8 WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4 QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0 YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3 Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6 ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1 YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP 0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK 8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIG0TCCBbmgAwIBAgIBezANBgkqhkiG9w0BAQUFADCByTELMAkGA1UEBhMCSFUx ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMUIwQAYDVQQD EzlOZXRMb2NrIE1pbm9zaXRldHQgS296amVneXpvaSAoQ2xhc3MgUUEpIFRhbnVz aXR2YW55a2lhZG8xHjAcBgkqhkiG9w0BCQEWD2luZm9AbmV0bG9jay5odTAeFw0w MzAzMzAwMTQ3MTFaFw0yMjEyMTUwMTQ3MTFaMIHJMQswCQYDVQQGEwJIVTERMA8G A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxQjBABgNVBAMTOU5l dExvY2sgTWlub3NpdGV0dCBLb3pqZWd5em9pIChDbGFzcyBRQSkgVGFudXNpdHZh bnlraWFkbzEeMBwGCSqGSIb3DQEJARYPaW5mb0BuZXRsb2NrLmh1MIIBIjANBgkq hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx1Ilstg91IRVCacbvWy5FPSKAtt2/Goq eKvld/Bu4IwjZ9ulZJm53QE+b+8tmjwi8F3JV6BVQX/yQ15YglMxZc4e8ia6AFQe r7C8HORSjKAyr7c3sVNnaHRnUPYtLmTeriZ539+Zhqurf4XsoPuAzPS4DB6TRWO5 3Lhbm+1bOdRfYrCnjnxmOCyqsQhjF2d9zL2z8cM/z1A57dEZgxXbhxInlrfa6uWd vLrqOU+L73Sa58XQ0uqGURzk/mQIKAR5BevKxXEOC++r6uwSEaEYBTJp0QwsGj0l mT+1fMptsK6ZmfoIYOcZwvK9UdPM0wKswREMgM6r3JSda6M5UzrWhQIDAMV9o4IC wDCCArwwEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8EBAMCAQYwggJ1Bglg hkgBhvhCAQ0EggJmFoICYkZJR1lFTEVNISBFemVuIHRhbnVzaXR2YW55IGEgTmV0 TG9jayBLZnQuIE1pbm9zaXRldHQgU3pvbGdhbHRhdGFzaSBTemFiYWx5emF0YWJh biBsZWlydCBlbGphcmFzb2sgYWxhcGphbiBrZXN6dWx0LiBBIG1pbm9zaXRldHQg ZWxla3Ryb25pa3VzIGFsYWlyYXMgam9naGF0YXMgZXJ2ZW55ZXN1bGVzZW5laywg dmFsYW1pbnQgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYSBNaW5vc2l0ZXR0IFN6 b2xnYWx0YXRhc2kgU3phYmFseXphdGJhbiwgYXogQWx0YWxhbm9zIFN6ZXJ6b2Rl c2kgRmVsdGV0ZWxla2JlbiBlbG9pcnQgZWxsZW5vcnplc2kgZWxqYXJhcyBtZWd0 ZXRlbGUuIEEgZG9rdW1lbnR1bW9rIG1lZ3RhbGFsaGF0b2sgYSBodHRwczovL3d3 dy5uZXRsb2NrLmh1L2RvY3MvIGNpbWVuIHZhZ3kga2VyaGV0b2sgYXogaW5mb0Bu ZXRsb2NrLm5ldCBlLW1haWwgY2ltZW4uIFdBUk5JTkchIFRoZSBpc3N1YW5jZSBh bmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGFyZSBzdWJqZWN0IHRvIHRo ZSBOZXRMb2NrIFF1YWxpZmllZCBDUFMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3 Lm5ldGxvY2suaHUvZG9jcy8gb3IgYnkgZS1tYWlsIGF0IGluZm9AbmV0bG9jay5u ZXQwHQYDVR0OBBYEFAlqYhaSsFq7VQ7LdTI6MuWyIckoMA0GCSqGSIb3DQEBBQUA A4IBAQCRalCc23iBmz+LQuM7/KbD7kPgz/PigDVJRXYC4uMvBcXxKufAQTPGtpvQ MznNwNuhrWw3AkxYQTvyl5LGSKjN5Yo5iWH5Upfpvfb5lHTocQ68d4bDBsxafEp+ NFAwLvt/MpqNPfMgW/hqyobzMUwsWYACff44yTB1HLdV47yfuqhthCgFdbOLDcCR VCHnpgu0mfVRQdzNo0ci2ccBgcTcR08m6h/t280NmPSjnLRzMkqWmf68f8glWPhY 83ZmiVSkpj7EUFy6iRiCdUgh0k8T6GB+B3bbELVR5qq5aKrN9p2QdRLqOBrKROi3 macqaJVmlaut74nLYKkGEsaUR+ko -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0 b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05 OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0 IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06 sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS NitjrFgBazMpUIaD8QFI -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH /nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp +ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1 ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og /zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2 A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y 4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza 8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB 4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd 8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A 4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0 aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0 aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0 7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd +LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B 4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57 k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK 4SVhM7JZG+Ju1zdXtg2pEto= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0 aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0 aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8 7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK SnQ2+Q== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICXDCCAcWgAwIBAgIQCgEBAQAAAnwAAAALAAAAAjANBgkqhkiG9w0BAQUFADA6 MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp dHkgMTAyNCBWMzAeFw0wMTAyMjIyMTAxNDlaFw0yNjAyMjIyMDAxNDlaMDoxGTAX BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAx MDI0IFYzMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDV3f5mCc8kPD6ugU5O isRpgFtZO9+5TUzKtS3DJy08rwBCbbwoppbPf9dYrIMKo1W1exeQFYRMiu4mmdxY 78c4pqqv0I5CyGLXq6yp+0p9v+r+Ek3d/yYtbzZUaMjShFbuklNhCbM/OZuoyZu9 zp9+1BlqFikYvtc6adwlWzMaUQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4G A1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBTEwBykB5T9zU0B1FTapQxf3q4FWjAd BgNVHQ4EFgQUxMAcpAeU/c1NAdRU2qUMX96uBVowDQYJKoZIhvcNAQEFBQADgYEA Py1q4yZDlX2Jl2X7deRyHUZXxGFraZ8SmyzVWujAovBDleMf6XbN3Ou8k6BlCsdN T1+nr6JGFLkM88y9am63nd4lQtBU/55oc2PcJOsiv6hy8l4A4Q1OOkNumU4/iXgD mMrzVcydro7BqkWY+o8aoI2II/EVQQ2lRj6RP4vr93E= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6 MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg /9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2 PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/ Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+ f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch 6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3 7CAFYd4= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk 3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz 6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa /FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7 sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO 0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj 7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS 8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB /zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3 6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/ 3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR 3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5 WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8 9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9 Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5 Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIBJDANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MxIENBMB4XDTAx MDQwNjEwNDkxM1oXDTIxMDQwNjEwNDkxM1owOTELMAkGA1UEBhMCRkkxDzANBgNV BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMSBDQTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBALWJHytPZwp5/8Ue+H887dF+2rDNbS82rDTG 29lkFwhjMDMiikzujrsPDUJVyZ0upe/3p4zDq7mXy47vPxVnqIJyY1MPQYx9EJUk oVqlBvqSV536pQHydekfvFYmUk54GWVYVQNYwBSujHxVX3BbdyMGNpfzJLWaRpXk 3w0LBUXl0fIdgrvGE+D+qnr9aTCU89JFhfzyMlsy3uhsXR/LpCJ0sICOXZT3BgBL qdReLjVQCfOAl/QMF6452F/NM8EcyonCIvdFEu1eEpOdY6uCLrnrQkFEy0oaAIIN nvmLVz5MxxftLItyM19yejhW1ebZrgUaHXVFsculJRwSVzb9IjcCAwEAAaMzMDEw DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQIR+IMi/ZTiFIwCwYDVR0PBAQDAgEG MA0GCSqGSIb3DQEBBQUAA4IBAQCLGrLJXWG04bkruVPRsoWdd44W7hE928Jj2VuX ZfsSZ9gqXLar5V7DtxYvyOirHYr9qxp81V9jz9yw3Xe5qObSIjiHBxTZ/75Wtf0H DjxVyhbMp6Z3N/vbXB9OWQaHowND9Rart4S9Tu+fMTfwRvFAttEMpWT4Y14h21VO TzF2nBBhjrZTOqMRvq9tfB69ri3iDGnHhVNoomG6xT60eVR4ngrHAr5i0RGCS2Uv kVrCqIexVmiUefkl98HVrhq4uz2PqYo4Ffdz0Fpg0YCw8NzVUM1O7pJIae2yIx4w zMiUyLb1O4Z/P6Yun/Y+LLWSlj7fLJOK/4GMDw9ZIRlXvVWa -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt 5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s 3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu 8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/ 3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6 Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2 ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71 9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA 7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k /rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6 u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy 7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf 8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN +lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA 1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ 9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0 YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9 m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/ TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo 19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e 3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6 MBr1mmz0DlP5OlvRHA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8 76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+ bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c 6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7 lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn 8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6 45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5 O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a 77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3 92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFwTCCA6mgAwIBAgIITrIAZwwDXU8wDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEjMCEGA1UEAxMaU3dpc3NTaWdu IFBsYXRpbnVtIENBIC0gRzIwHhcNMDYxMDI1MDgzNjAwWhcNMzYxMDI1MDgzNjAw WjBJMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMSMwIQYDVQQD ExpTd2lzc1NpZ24gUGxhdGludW0gQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAMrfogLi2vj8Bxax3mCq3pZcZB/HL37PZ/pEQtZ2Y5Wu669y IIpFR4ZieIbWIDkm9K6j/SPnpZy1IiEZtzeTIsBQnIJ71NUERFzLtMKfkr4k2Htn IuJpX+UFeNSH2XFwMyVTtIc7KZAoNppVRDBopIOXfw0enHb/FZ1glwCNioUD7IC+ 6ixuEFGSzH7VozPY1kneWCqv9hbrS3uQMpe5up1Y8fhXSQQeol0GcN1x2/ndi5ob jM89o03Oy3z2u5yg+gnOI2Ky6Q0f4nIoj5+saCB9bzuohTEJfwvH6GXp43gOCWcw izSC+13gzJ2BbWLuCB4ELE6b7P6pT1/9aXjvCR+htL/68++QHkwFix7qepF6w9fl +zC8bBsQWJj3Gl/QKTIDE0ZNYWqFTFJ0LwYfexHihJfGmfNtf9dng34TaNhxKFrY zt3oEBSa/m0jh26OWnA81Y0JAKeqvLAxN23IhBQeW71FYyBrS3SMvds6DsHPWhaP pZjydomyExI7C3d3rLvlPClKknLKYRorXkzig3R3+jVIeoVNjZpTxN94ypeRSCtF KwH3HBqi7Ri6Cr2D+m+8jVeTO9TUps4e8aCxzqv9KyiaTxvXw3LbpMS/XUz13XuW ae5ogObnmLo2t/5u7Su9IPhlGdpVCX4l3P5hYnL5fhgC72O00Puv5TtjjGePAgMB AAGjgawwgakwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O BBYEFFCvzAeHFUdvOMW0ZdHelarp35zMMB8GA1UdIwQYMBaAFFCvzAeHFUdvOMW0 ZdHelarp35zMMEYGA1UdIAQ/MD0wOwYJYIV0AVkBAQEBMC4wLAYIKwYBBQUHAgEW IGh0dHA6Ly9yZXBvc2l0b3J5LnN3aXNzc2lnbi5jb20vMA0GCSqGSIb3DQEBBQUA A4ICAQAIhab1Fgz8RBrBY+D5VUYI/HAcQiiWjrfFwUF1TglxeeVtlspLpYhg0DB0 uMoI3LQwnkAHFmtllXcBrqS3NQuB2nEVqXQXOHtYyvkv+8Bldo1bAbl93oI9ZLi+ FHSjClTTLJUYFzX1UWs/j6KWYTl4a0vlpqD4U99REJNi54Av4tHgvI42Rncz7Lj7 jposiU0xEQ8mngS7twSNC/K5/FqdOxa3L8iYq/6KUFkuozv8KV2LwUvJ4ooTHbG/ u0IdUt1O2BReEMYxB+9xJ/cbOQncguqLs5WGXv312l0xpuAxtpTmREl0xRbl9x8D YSjFyMsSoEJL+WuICI20MhjzdZ/EfwBPBZWcoxcCw7NTm6ogOSkrZvqdr16zktK1 puEa+S1BaYEUtLS17Yk9zvupnTVCRLEcFHOBzyoBNZox1S2PbYTfgE1X4z/FhHXa icYwu+uPyyIIoK6q8QNsOktNCaUOcsZWayFCTiMlFGiudgp8DAdwZPmaL/YFOSbG DI8Zf0NebvRbFS/bYV3mZy8/CJT5YLSYMdp08YSTcU1f+2BY0fvEwW2JorsgH51x kcsymxM9Pn2SUjWskpSi0xjCfMfqr3YFFt1nJ8J+HAciIfNAChs0B0QTwoRqjt8Z Wr9/6x3iGjjRXK9HkmuAtTClyY3YqzGBH9/CZjfTk6mFhnll0g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH 6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/ c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6 5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0 cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9 xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ 2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8 aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/ OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+ hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/ MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2 jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7 hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1 EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl pYYsfPQS -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDXDCCAsWgAwIBAgICA+owDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAyIENBMSkwJwYJKoZIhvcN AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1 c3RDZW50ZXIgQ2xhc3MgMiBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANo46O0y AClxgwENv4wB3NrGrTmkqYov1YtcaF9QxmL1Zr3KkSLsqh1R1z2zUbKDTl3LSbDw TFXlay3HhQswHJJOgtTKAu33b77c4OMUuAVT8pr0VotanoWT0bSCVq5Nu6hLVxa8 /vhYnvgpjbB7zXjJT6yLZwzxnPv8V5tXXE8NAgMBAAGjazBpMA8GA1UdEwEB/wQF MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3 LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G CSqGSIb3DQEBBAUAA4GBAIRS+yjf/x91AbwBvgRWl2p0QiQxg/lGsQaKic+WLDO/ jLVfenKhhQbOhvgFjuj5Jcrag4wGrOs2bYWRNAQ29ELw+HkuCkhcq8xRT3h2oNms Gb0q0WkEKJHKNhAngFdb0lz1wlurZIFjdFH0l7/NEij3TWZ/p/AcASZ4smZHcFFk -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDXDCCAsWgAwIBAgICA+swDQYJKoZIhvcNAQEEBQAwgbwxCzAJBgNVBAYTAkRF MRAwDgYDVQQIEwdIYW1idXJnMRAwDgYDVQQHEwdIYW1idXJnMTowOAYDVQQKEzFU QyBUcnVzdENlbnRlciBmb3IgU2VjdXJpdHkgaW4gRGF0YSBOZXR3b3JrcyBHbWJI MSIwIAYDVQQLExlUQyBUcnVzdENlbnRlciBDbGFzcyAzIENBMSkwJwYJKoZIhvcN AQkBFhpjZXJ0aWZpY2F0ZUB0cnVzdGNlbnRlci5kZTAeFw05ODAzMDkxMTU5NTla Fw0xMTAxMDExMTU5NTlaMIG8MQswCQYDVQQGEwJERTEQMA4GA1UECBMHSGFtYnVy ZzEQMA4GA1UEBxMHSGFtYnVyZzE6MDgGA1UEChMxVEMgVHJ1c3RDZW50ZXIgZm9y IFNlY3VyaXR5IGluIERhdGEgTmV0d29ya3MgR21iSDEiMCAGA1UECxMZVEMgVHJ1 c3RDZW50ZXIgQ2xhc3MgMyBDQTEpMCcGCSqGSIb3DQEJARYaY2VydGlmaWNhdGVA dHJ1c3RjZW50ZXIuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALa0wTUF Lg2N7KBAahwOJ6ZQkmtQGwfeLud2zODa/ISoXoxjaitN2U4CdhHBC/KNecoAtvGw Dtf7pBc9r6tpepYnv68zoZoqWarEtTcI8hKlMbZD9TKWcSgoq40oht+77uMMfTDW w1Krj10nnGvAo+cFa1dJRLNu6mTP0o56UHd3AgMBAAGjazBpMA8GA1UdEwEB/wQF MAMBAf8wDgYDVR0PAQH/BAQDAgGGMDMGCWCGSAGG+EIBCAQmFiRodHRwOi8vd3d3 LnRydXN0Y2VudGVyLmRlL2d1aWRlbGluZXMwEQYJYIZIAYb4QgEBBAQDAgAHMA0G CSqGSIb3DQEBBAUAA4GBABY9xs3Bu4VxhUafPiCPUSiZ7C1FIWMjWwS7TJC4iJIE Tb19AaM/9uzO8d7+feXhPrvGq14L3T2WxMup1Pkm5gZOngylerpuw3yCGdHHsbHD 2w2Om0B8NwvxXej9H5CIpQ5ON2QhqE6NtJ/x3kit1VYYUimLRzQSCdS7kjXvD9s0 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a 0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1 4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3 WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+ 2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89 9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0 jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38 aQNiuJkFBT1reBK9sG9l -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIFGTCCBAGgAwIBAgIEPki9xDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJE SzEMMAoGA1UEChMDVERDMRQwEgYDVQQDEwtUREMgT0NFUyBDQTAeFw0wMzAyMTEw ODM5MzBaFw0zNzAyMTEwOTA5MzBaMDExCzAJBgNVBAYTAkRLMQwwCgYDVQQKEwNU REMxFDASBgNVBAMTC1REQyBPQ0VTIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEArGL2YSCyz8DGhdfjeebM7fI5kqSXLmSjhFuHnEz9pPPEXyG9VhDr 2y5h7JNp46PMvZnDBfwGuMo2HP6QjklMxFaaL1a8z3sM8W9Hpg1DTeLpHTk0zY0s 2RKY+ePhwUp8hjjEqcRhiNJerxomTdXkoCJHhNlktxmW/OwZ5LKXJk5KTMuPJItU GBxIYXvViGjaXbXqzRowwYCDdlCqT9HU3Tjw7xb04QxQBr/q+3pJoSgrHPb8FTKj dGqPqcNiKXEx5TukYBdedObaE+3pHx8b0bJoc8YQNHVGEBDjkAB2QMuLt0MJIf+r TpPGWOmlgtt3xDqZsXKVSQTwtyv6e1mO3QIDAQABo4ICNzCCAjMwDwYDVR0TAQH/ BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwgewGA1UdIASB5DCB4TCB3gYIKoFQgSkB AQEwgdEwLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuY2VydGlmaWthdC5kay9yZXBv c2l0b3J5MIGdBggrBgEFBQcCAjCBkDAKFgNUREMwAwIBARqBgUNlcnRpZmlrYXRl ciBmcmEgZGVubmUgQ0EgdWRzdGVkZXMgdW5kZXIgT0lEIDEuMi4yMDguMTY5LjEu MS4xLiBDZXJ0aWZpY2F0ZXMgZnJvbSB0aGlzIENBIGFyZSBpc3N1ZWQgdW5kZXIg T0lEIDEuMi4yMDguMTY5LjEuMS4xLjARBglghkgBhvhCAQEEBAMCAAcwgYEGA1Ud HwR6MHgwSKBGoESkQjBAMQswCQYDVQQGEwJESzEMMAoGA1UEChMDVERDMRQwEgYD VQQDEwtUREMgT0NFUyBDQTENMAsGA1UEAxMEQ1JMMTAsoCqgKIYmaHR0cDovL2Ny bC5vY2VzLmNlcnRpZmlrYXQuZGsvb2Nlcy5jcmwwKwYDVR0QBCQwIoAPMjAwMzAy MTEwODM5MzBagQ8yMDM3MDIxMTA5MDkzMFowHwYDVR0jBBgwFoAUYLWF7FZkfhIZ J2cdUBVLc647+RIwHQYDVR0OBBYEFGC1hexWZH4SGSdnHVAVS3OuO/kSMB0GCSqG SIb2fQdBAAQQMA4bCFY2LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEACrom JkbTc6gJ82sLMJn9iuFXehHTuJTXCRBuo7E4A9G28kNBKWKnctj7fAXmMXAnVBhO inxO5dHKjHiIzxvTkIvmI/gLDjNDfZziChmPyQE+dF10yYscA+UYyAFMP8uXBV2Y caaYb7Z8vTd/vuGTJW1v8AqtFxjhA7wHKcitJuj4YfD9IQl+mo6paH1IYnK9AOoB mbgGglGBTvH1tJFUuSN6AJqfXY3gPGS5GhKSKseCRHI53OI8xthV9RVOyAUO28bQ YqbsFbS1AoLbrIyigfCbmTH1ICCoiGEKB5+U/NDXG8wuF/MEJ3Zn61SD/aSQfgY9 BKNDLdr8C2LqL19iUw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDITCCAoqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCByzELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT ZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFBlcnNvbmFsIEJhc2lj IENBMSgwJgYJKoZIhvcNAQkBFhlwZXJzb25hbC1iYXNpY0B0aGF3dGUuY29tMB4X DTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgcsxCzAJBgNVBAYTAlpBMRUw EwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEaMBgGA1UE ChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRpb24gU2Vy dmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQZXJzb25hbCBCYXNpYyBD QTEoMCYGCSqGSIb3DQEJARYZcGVyc29uYWwtYmFzaWNAdGhhd3RlLmNvbTCBnzAN BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAvLyTU23AUE+CFeZIlDWmWr5vQvoPR+53 dXLdjUmbllegeNTKP1GzaQuRdhciB5dqxFGTS+CN7zeVoQxN2jSQHReJl+A1OFdK wPQIcOk8RHtQfmGakOMj04gRRif1CwcOu93RfyAKiLlWCy4cgNrx454p7xS9CkT7 G1sY0b8jkyECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQQF AAOBgQAt4plrsD16iddZopQBHyvdEktTwq1/qqcAXJFAVyVKOKqEcLnZgA+le1z7 c8a914phXAPjLSeoF+CEhULcXpvGt7Jtu3Sv5D/Lp7ew4F2+eIMllNLbgQ95B21P 9DkVWlIBe94y1k049hJcBlDfBVu9FEuh3ym6O0GN92NWod8isQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDLTCCApagAwIBAgIBADANBgkqhkiG9w0BAQQFADCB0TELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT ZXJ2aWNlcyBEaXZpc2lvbjEkMCIGA1UEAxMbVGhhd3RlIFBlcnNvbmFsIEZyZWVt YWlsIENBMSswKQYJKoZIhvcNAQkBFhxwZXJzb25hbC1mcmVlbWFpbEB0aGF3dGUu Y29tMB4XDTk2MDEwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgdExCzAJBgNVBAYT AlpBMRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEa MBgGA1UEChMRVGhhd3RlIENvbnN1bHRpbmcxKDAmBgNVBAsTH0NlcnRpZmljYXRp b24gU2VydmljZXMgRGl2aXNpb24xJDAiBgNVBAMTG1RoYXd0ZSBQZXJzb25hbCBG cmVlbWFpbCBDQTErMCkGCSqGSIb3DQEJARYccGVyc29uYWwtZnJlZW1haWxAdGhh d3RlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1GnX1LCUZFtx6UfY DFG26nKRsIRefS0Nj3sS34UldSh0OkIsYyeflXtL734Zhx2G6qPduc6WZBrCFG5E rHzmj+hND3EfQDimAKOHePb5lIZererAXnbr2RSjXW56fAylS1V/Bhkpf56aJtVq uzgkCGqYx7Hao5iR/Xnb5VrEHLkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN BgkqhkiG9w0BAQQFAAOBgQDH7JJ+Tvj1lqVnYiqk8E0RYNBvjWBYYawmu1I1XAjP MPuoSpaKH2JCI4wXD/S6ZJwXrEcp352YXtJsYHFcoqzceePnbgBHH7UNKOgCneSa /RP0ptl8sfjcXyMmCZGAc9AUG95DqYMl8uacLxXK/qarigd1iwzdUYRr5PjRznei gQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDKTCCApKgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBzzELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMRowGAYD VQQKExFUaGF3dGUgQ29uc3VsdGluZzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBT ZXJ2aWNlcyBEaXZpc2lvbjEjMCEGA1UEAxMaVGhhd3RlIFBlcnNvbmFsIFByZW1p dW0gQ0ExKjAoBgkqhkiG9w0BCQEWG3BlcnNvbmFsLXByZW1pdW1AdGhhd3RlLmNv bTAeFw05NjAxMDEwMDAwMDBaFw0yMDEyMzEyMzU5NTlaMIHPMQswCQYDVQQGEwJa QTEVMBMGA1UECBMMV2VzdGVybiBDYXBlMRIwEAYDVQQHEwlDYXBlIFRvd24xGjAY BgNVBAoTEVRoYXd0ZSBDb25zdWx0aW5nMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9u IFNlcnZpY2VzIERpdmlzaW9uMSMwIQYDVQQDExpUaGF3dGUgUGVyc29uYWwgUHJl bWl1bSBDQTEqMCgGCSqGSIb3DQEJARYbcGVyc29uYWwtcHJlbWl1bUB0aGF3dGUu Y29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJZtn4B0TPuYwu8KHvE0Vs Bd/eJxZRNkERbGw77f4QfRKe5ZtCmv5gMcNmt3M6SK5O0DI3lIi1DbbZ8/JE2dWI Et12TfIa/G8jHnrx2JhFTgcQ7xZC0EN1bUre4qrJMf8fAHB8Zs8QJQi6+u4A6UYD ZicRFTuqW/KY3TZCstqIdQIDAQABoxMwETAPBgNVHRMBAf8EBTADAQH/MA0GCSqG SIb3DQEBBAUAA4GBAGk2ifc0KjNyL2071CKyuG+axTZmDhs8obF1Wub9NdP4qPIH b4Vnjt4rueIXsDqg8A6iAJrf8xQVbrvIhVqYgPn/vnQdPfP+MCXRNzRn+qVxeTBh KXLA4CxM+1bkOqhv5TJZUtt1KFBZDPgLGeSs2a+WjS9Q2wfD6h+rM+D1KzGJ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 jVaMaA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ qdq5snUb9kLy78fyGPmJvKP/iiMucEc= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDIzCCAoygAwIBAgIEMAAAAjANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJV UzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xNzA1BgNVBAsTLkNsYXNzIDMgUHVi bGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQwNTEzMDAw MDAwWhcNMTQwNTEyMjM1OTU5WjBMMQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhh d3RlIENvbnN1bHRpbmcgKFB0eSkgTHRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBD QTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1NNn0I0Vf67NMf59HZGhPwtx PKzMyGT7Y/wySweUvW+Aui/hBJPAM/wJMyPpC3QrccQDxtLN4i/1CWPN/0ilAL/g 5/OIty0y3pg25gqtAHvEZEo7hHUD8nCSfQ5i9SGraTaEMXWQ+L/HbIgbBpV8yeWo 3nWhLHpo39XKHIdYYBkCAwEAAaOB/jCB+zASBgNVHRMBAf8ECDAGAQH/AgEAMAsG A1UdDwQEAwIBBjARBglghkgBhvhCAQEEBAMCAQYwKAYDVR0RBCEwH6QdMBsxGTAX BgNVBAMTEFByaXZhdGVMYWJlbDMtMTUwMQYDVR0fBCowKDAmoCSgIoYgaHR0cDov L2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwMgYIKwYBBQUHAQEEJjAkMCIGCCsG AQUFBzABhhZodHRwOi8vb2NzcC50aGF3dGUuY29tMDQGA1UdJQQtMCsGCCsGAQUF BwMBBggrBgEFBQcDAgYJYIZIAYb4QgQBBgpghkgBhvhFAQgBMA0GCSqGSIb3DQEB BQUAA4GBAFWsY+reod3SkF+fC852vhNRj5PZBSvIG3dLrWlQoe7e3P3bB+noOZTc q3J5Lwa/q4FwxKjt6lM07e8eU9kGx1Yr0Vz00YqOtCuxN5BICEIlxT6Ky3/rbwTR bcV0oveifHtgPHfNDs5IAn8BL7abN+AqKjbc1YXWrOU/VG+WHgWv -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICoTCCAgqgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzAN BgNVBAoTBlRoYXd0ZTEdMBsGA1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAd BgNVBAMTFlRoYXd0ZSBUaW1lc3RhbXBpbmcgQ0EwHhcNOTcwMTAxMDAwMDAwWhcN MjAxMjMxMjM1OTU5WjCBizELMAkGA1UEBhMCWkExFTATBgNVBAgTDFdlc3Rlcm4g Q2FwZTEUMBIGA1UEBxMLRHVyYmFudmlsbGUxDzANBgNVBAoTBlRoYXd0ZTEdMBsG A1UECxMUVGhhd3RlIENlcnRpZmljYXRpb24xHzAdBgNVBAMTFlRoYXd0ZSBUaW1l c3RhbXBpbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANYrWHhhRYZT 6jR7UZztsOYuGA7+4F+oJ9O0yeB8WU4WDnNUYMF/9p8u6TqFJBU820cEY8OexJQa Wt9MevPZQx08EHp5JduQ/vBR5zDWQQD9nyjfeb6Uu522FOMjhdepQeBMpHmwKxqL 8vg7ij5FrHGSALSQQZj7X+36ty6K+Ig3AgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB Af8wDQYJKoZIhvcNAQEEBQADgYEAZ9viwuaHPUCDhjc1fR/OmsMMZiCouqoEiYbC 9RAIDb/LogWK0E02PvTX72nGXuSwlG9KuefeW4i2e9vjJ+V2w/A1wcu1J5szedyQ pgCed/r8zSeUQhac0xxo7L9c3eWpexAKMnRUEzGLhQOEkbdYATAUOK8oyvyxUBkZ CayJSdM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW 1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8 dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7 XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1 JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51 b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV 9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7 kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS RGQDJereW26fyfJOrN3H -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3 WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4 Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK 4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv 2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 mfnGV/TJVTl4uix5yaaIK/QI -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEojCCA4qgAwIBAgIQRL4Mi1AAJLQR0zYlJWfJiTANBgkqhkiG9w0BAQUFADCB rjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmlyc3Qt Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw05OTA3MDkxNzI4NTBa Fw0xOTA3MDkxNzM2NThaMIGuMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAV BgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5l dHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTE2MDQGA1UE AxMtVVROLVVTRVJGaXJzdC1DbGllbnQgQXV0aGVudGljYXRpb24gYW5kIEVtYWls MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsjmFpPJ9q0E7YkY3rs3B YHW8OWX5ShpHornMSMxqmNVNNRm5pELlzkniii8efNIxB8dOtINknS4p1aJkxIW9 hVE1eaROaJB7HHqkkqgX8pgV8pPMyaQylbsMTzC9mKALi+VuG6JG+ni8om+rWV6l L8/K2m2qL+usobNqqrcuZzWLeeEeaYji5kbNoKXqvgvOdjp6Dpvq/NonWz1zHyLm SGHGTPNpsaguG7bUMSAsvIKKjqQOpdeJQ/wWWq8dcdcRWdq6hw2v+vPhwvCkxWeM 1tZUOt4KpLoDd7NlyP0e03RiqhjKaJMeoYV+9Udly/hNVyh00jT/MLbu9mIwFIws 6wIDAQABo4G5MIG2MAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud DgQWBBSJgmd9xJ0mcABLtFBIfN49rgRufTBYBgNVHR8EUTBPME2gS6BJhkdodHRw Oi8vY3JsLnVzZXJ0cnVzdC5jb20vVVROLVVTRVJGaXJzdC1DbGllbnRBdXRoZW50 aWNhdGlvbmFuZEVtYWlsLmNybDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUH AwQwDQYJKoZIhvcNAQEFBQADggEBALFtYV2mGn98q0rkMPxTbyUkxsrt4jFcKw7u 7mFVbwQ+zznexRtJlOTrIEy05p5QLnLZjfWqo7NK2lYcYJeA3IKirUq9iiv/Cwm0 xtcgBEXkzYABurorbs6q15L+5K/r9CYdFip/bDCVNy8zEqx/3cfREYxRmLLQo5HQ rfafnoOTHh1CuEava2bwm3/q4wMC5QJRwarVNZ1yQAOJujEdxRBoUp7fooXFXAim eOZTT7Hot9MUnpOmw2TjrH5xzbyf6QMbzPvprDHBr3wVdAKZw7JHpsIyYdfHb0gk USeh1YdV8nuPmD0Wnu51tvjQjvLzxq4oW6fw8zYX/MMF08oDSlQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn 0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t 3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEZDCCA0ygAwIBAgIQRL4Mi1AAJLQR0zYwS8AzdzANBgkqhkiG9w0BAQUFADCB ozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VSRmlyc3Qt TmV0d29yayBBcHBsaWNhdGlvbnMwHhcNOTkwNzA5MTg0ODM5WhcNMTkwNzA5MTg1 NzQ5WjCBozELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0 IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYD VQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xKzApBgNVBAMTIlVUTi1VU0VS Rmlyc3QtTmV0d29yayBBcHBsaWNhdGlvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IB DwAwggEKAoIBAQCz+5Gh5DZVhawGNFugmliy+LUPBXeDrjKxdpJo7CNKyXY/45y2 N3kDuatpjQclthln5LAbGHNhSuh+zdMvZOOmfAz6F4CjDUeJT1FxL+78P/m4FoCH iZMlIJpDgmkkdihZNaEdwH+DBmQWICzTSaSFtMBhf1EI+GgVkYDLpdXuOzr0hARe YFmnjDRy7rh4xdE7EkpvfmUnuaRVxblvQ6TFHSyZwFKkeEwVs0CYCGtDxgGwenv1 axwiP8vv/6jQOkt2FZ7S0cYu49tXGzKiuG/ohqY/cKvlcJKrRB5AUPuco2LkbG6g yN7igEL66S/ozjIEj3yNtxyjNTwV3Z7DrpelAgMBAAGjgZEwgY4wCwYDVR0PBAQD AgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFPqGydvguul49Uuo1hXf8NPh ahQ8ME8GA1UdHwRIMEYwRKBCoECGPmh0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V VE4tVVNFUkZpcnN0LU5ldHdvcmtBcHBsaWNhdGlvbnMuY3JsMA0GCSqGSIb3DQEB BQUAA4IBAQCk8yXM0dSRgyLQzDKrm5ZONJFUICU0YV8qAhXhi6r/fWRRzwr/vH3Y IWp4yy9Rb/hCHTO967V7lMPDqaAt39EpHx3+jz+7qEUqf9FuVSTiuwL7MT++6Lzs QCv4AdRWOOTKRIK1YSAhZ2X28AvnNPilwpyjXEAfhZOVBt5P1CeptqX8Fs1zMT+4 ZSfP1FMa8Kxun08FDAOBp4QpxFq9ZFdyrTvPNximmMatBrTcCKME1SmklpoSZ0qM YEWd8SOasACcaLWYUNPvji6SZbFIPiG+FTAqDbUMo2s/rn9X9R+WfN9v3YIwLGUb QErNaLly7HF27FSOH4UMAWr6pjisH8SE -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEZjCCA06gAwIBAgIQRL4Mi1AAJLQR0zYt4LNfGzANBgkqhkiG9w0BAQUFADCB lTELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHTAbBgNVBAMTFFVUTi1VU0VSRmlyc3Qt T2JqZWN0MB4XDTk5MDcwOTE4MzEyMFoXDTE5MDcwOTE4NDAzNlowgZUxCzAJBgNV BAYTAlVTMQswCQYDVQQIEwJVVDEXMBUGA1UEBxMOU2FsdCBMYWtlIENpdHkxHjAc BgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEhMB8GA1UECxMYaHR0cDovL3d3 dy51c2VydHJ1c3QuY29tMR0wGwYDVQQDExRVVE4tVVNFUkZpcnN0LU9iamVjdDCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6qgT+jo2F4qjEAVZURnicP HxzfOpuCaDDASmEd8S8O+r5596Uj71VRloTN2+O5bj4x2AogZ8f02b+U60cEPgLO KqJdhwQJ9jCdGIqXsqoc/EHSoTbL+z2RuufZcDX65OeQw5ujm9M89RKZd7G3CeBo 5hy485RjiGpq/gt2yb70IuRnuasaXnfBhQfdDWy/7gbHd2pBnqcP1/vulBe3/IW+ pKvEHDHd17bR5PDv3xaPslKT16HUiaEHLr/hARJCHhrh2JU022R5KP+6LhHC5ehb kkj7RwvCbNqtMoNB86XlQXD9ZZBt+vpRxPm9lisZBCzTbafc8H9vg2XiaquHhnUC AwEAAaOBrzCBrDALBgNVHQ8EBAMCAcYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4E FgQU2u1kdBScFDyr3ZmpvVsoTYs8ydgwQgYDVR0fBDswOTA3oDWgM4YxaHR0cDov L2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtT2JqZWN0LmNybDApBgNV HSUEIjAgBggrBgEFBQcDAwYIKwYBBQUHAwgGCisGAQQBgjcKAwQwDQYJKoZIhvcN AQEFBQADggEBAAgfUrE3RHjb/c652pWWmKpVZIC1WkDdIaXFwfNfLEzIR1pp6ujw NTX00CXzyKakh0q9G7FzCL3Uw8q2NbtZhncxzaeAFK4T7/yxSPlrJSUtUbYsbUXB mMiKVl0+7kNOPmsnjtA6S4ULX9Ptaqd1y9Fahy85dRNacrACgZ++8A+EVCBibGnU 4U3GDZlDAQ0Slox4nb9QorFEqmrPF3rPbw/U+CRVX/A0FklmPlBGyWNxODFiuGK5 81OtbLUrohKqGU8J2l7nk8aOFAj+8DCAGKCGhU3IfdeLA/5u1fedFqySLKAj5ZyR Uh+U3xeUc8OzwcFxBSAAeL0TUh2oPs0AH8g= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs 2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICNDCCAaECEAKtZn5ORf5eV288mBle3cAwDQYJKoZIhvcNAQECBQAwXzELMAkG A1UEBhMCVVMxIDAeBgNVBAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYD VQQLEyVTZWN1cmUgU2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk0 MTEwOTAwMDAwMFoXDTEwMDEwNzIzNTk1OVowXzELMAkGA1UEBhMCVVMxIDAeBgNV BAoTF1JTQSBEYXRhIFNlY3VyaXR5LCBJbmMuMS4wLAYDVQQLEyVTZWN1cmUgU2Vy dmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGbMA0GCSqGSIb3DQEBAQUAA4GJ ADCBhQJ+AJLOesGugz5aqomDV6wlAXYMra6OLDfO6zV4ZFQD5YRAUcm/jwjiioII 0haGN1XpsSECrXZogZoFokvJSyVmIlZsiAeP94FZbYQHZXATcXY+m3dM41CJVphI uR2nKRoTLkoRWZweFdVJVCxzOmmCsZc5nG1wZ0jl3S3WyB57AgMBAAEwDQYJKoZI hvcNAQECBQADfgBl3X7hsuyw4jrg7HFGmhkRuNPHoLQDQCYCPgmc4RKz0Vr2N6W3 YQO2WxZpO8ZECAyIUwxrl0nHPjXcbLm7qt9cuzovk2C2qUtN8iD3zV9/ZHuO3ABc 1/p3yjkWWW8O6tO1g39NTUJWdrTJXwT4OPjr0l91X817/OWOgHz8UA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICPTCCAaYCEQDNun9W8N/kvFT+IqyzcqpVMA0GCSqGSIb3DQEBAgUAMF8xCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xh c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05 NjAxMjkwMDAwMDBaFw0yODA4MDEyMzU5NTlaMF8xCzAJBgNVBAYTAlVTMRcwFQYD VQQKEw5WZXJpU2lnbiwgSW5jLjE3MDUGA1UECxMuQ2xhc3MgMSBQdWJsaWMgUHJp bWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCBnzANBgkqhkiG9w0BAQEFAAOB jQAwgYkCgYEA5Rm/baNWYS2ZSHH2Z965jeu3noaACpEO+jglr0aIguVzqKCbJF0N H8xlbgyw0FaEGIeaBpsQoXPftFg5a27B9hXVqKg/qhIGjTGsf7A01480Z4gJzRQR 4k5FVmkfeAKA2txHkSm7NsljXMXg1y2He6G3MrB7MLoqLzGq7qNn2tsCAwEAATAN BgkqhkiG9w0BAQIFAAOBgQBMP7iLxmjf7kMzDl3ppssHhE16M/+SG/Q2rdiVIjZo EWx8QszznC7EBz8UsA9P/5CSdvnivErpj82ggAr3xSnxgiJduLHdgSOjeyUVRjB5 FvjqBUuUfx3CHMjjt/QQQDwTw18fU+hI5Ia0e6E1sHslurjTjqs/OJ0ANACY89Fx lA== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAjCCAmsCEEzH6qqYPnHTkxD4PTqJkZIwDQYJKoZIhvcNAQEFBQAwgcExCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh c3MgMSBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMSBQdWJsaWMg UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB AQUAA4GNADCBiQKBgQCq0Lq+Fi24g9TK0g+8djHKlNgdk4xWArzZbxpvUjZudVYK VdPfQ4chEWWKfo+9Id5rMj8bhDSVBZ1BNeuS65bdqlk/AVNtmU/t5eIqWpDBucSm Fc/IReumXY6cPvBkJHalzasab7bYe1FhbqZ/h8jit+U03EGI6glAvnOSPWvndQID AQABMA0GCSqGSIb3DQEBBQUAA4GBAKlPww3HZ74sy9mozS11534Vnjty637rXC0J h9ZrbWB85a7FkCMMXErQr7Fd88e2CtvgFZMN3QO8x3aKtd1Pw5sTdbgBwObJW2ul uIncrKTdcu1OofdPvAbT6shkdHvClUGcZXNY8ZCaPGqxmMnEh7zPRW1F4m4iP/68 DzFc6PLZ -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCLW3VWhFSFCwDPrzhIzrGkMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT aWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu IENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAN2E1Lm0+afY8wR4 nN493GwTFtl63SRRZsDHJlkNrAYIwpTRMx/wgzUfbhvI3qpuFU5UJ+/EbRrsC+MO 8ESlV8dAWB6jRx9x7GD2bZTIGDnt/kIYVt/kTEkQeE4BdjVjEjbdZrwBBDajVWjV ojYJrKshJlQGrT/KFOCsyq0GHZXi+J3x4GD/wn91K0zM2v6HmSHquv4+VNfSWXjb PG7PoBMAGrgnoeS+Z5bKoMWznN3JdZ7rMJpfo83ZrngZPyPpXNspva1VyBtUjGP2 6KbqxzcSXKMpHgLZ2x87tNcPVkeBFQRKr4Mn0cVYiMHd9qqnoxjaaKptEVHhv2Vr n5Z20T0CAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAq2aN17O6x5q25lXQBfGfMY1a qtmqRiYPce2lrVNWYgFHKkTp/j90CxObufRNG7LRX7K20ohcs5/Ny9Sn2WCVhDr4 wTcdYcrnsMXlkdpUpqwxga6X3s0IrLjAl4B/bnKk52kTlWUfxJM8/XmPBNQ+T+r3 ns7NZ3xPZQL/kYVUc8f/NveGLezQXk//EZ9yBta4GvFMDSZl4kSAHsef493oCtrs pSCAaWihT37ha88HQfqDjrw43bAuEbFrskLMmrz5SCJ5ShkPshw+IHTZasO+8ih4 E1Z5T21Q6huwtVexN2ZYI/PcD98Kh8TvhgXVOBRgmaNL3gaWcSzy27YfpO8/7g== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICPDCCAaUCEC0b/EoXjaOR6+f/9YtFvgswDQYJKoZIhvcNAQECBQAwXzELMAkG A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz cyAyIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAyIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQC2WoujDWojg4BrzzmH9CETMwZMJaLtVRKXxaeAufqDwSCg+i8VDXyh YGt+eSz6Bg86rvYbb7HS/y8oUl+DfUvEerf4Zh+AVPy3wo5ZShRXRtGak75BkQO7 FYCTXOvnzAhsPz6zSvz/S2wj1VCCJkQZjiPDceoZJEcEnnW/yKYAHwIDAQABMA0G CSqGSIb3DQEBAgUAA4GBAIobK/o5wXTXXtgZZKJYSi034DNHD6zt96rbHuSLBlxg J8pFUs4W7z8GZOeUaHxgMxURaa+dYo2jA1Rrpr7l7gUYYAS/QoD90KioHgE796Nc r6Pc5iaAIzy4RHT3Cq5Ji2F4zCS/iIqnDupzGUH9TQPwiNHleI2lKk/2lw0Xd8rY -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAzCCAmwCEQC5L2DMiJ+hekYJuFtwbIqvMA0GCSqGSIb3DQEBBQUAMIHBMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0Ns YXNzIDIgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH MjE6MDgGA1UECxMxKGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9y aXplZCB1c2Ugb25seTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazAe Fw05ODA1MTgwMDAwMDBaFw0yODA4MDEyMzU5NTlaMIHBMQswCQYDVQQGEwJVUzEX MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xPDA6BgNVBAsTM0NsYXNzIDIgUHVibGlj IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBHMjE6MDgGA1UECxMx KGMpIDE5OTggVmVyaVNpZ24sIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s eTEfMB0GA1UECxMWVmVyaVNpZ24gVHJ1c3QgTmV0d29yazCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAp4gBIXQs5xoD8JjhlzwPIQjxnNuX6Zr8wgQGE75fUsjM HiwSViy4AWkszJkfrbCWrnkE8hM5wXuYuggs6MKEEyyqaekJ9MepAqRCwiNPStjw DqL7MWzJ5m+ZJwf15vRMeJ5t60aG+rmGyVTyssSv1EYcWskVMP8NbPUtDm3Of3cC AwEAATANBgkqhkiG9w0BAQUFAAOBgQByLvl/0fFx+8Se9sVeUYpAmLho+Jscg9ji nb3/7aHmZuovCfTK1+qlK5X2JGCGTUQug6XELaDTrnhpb3LabK4I8GOSN+a7xDAX rXfMSTWqz9iP0b63GJZHc2pUIjRkLbYWm1lbtFFZOrMLFPQS32eg9K0yZF6xRnIn jBJ7xUS0rg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEGTCCAwECEGFwy0mMX5hFKeewptlQW3owDQYJKoZIhvcNAQEFBQAwgcoxCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVy aVNpZ24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24s IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNp Z24gQ2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eSAtIEczMB4XDTk5MTAwMTAwMDAwMFoXDTM2MDcxNjIzNTk1OVowgcoxCzAJBgNV BAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjEfMB0GA1UECxMWVmVyaVNp Z24gVHJ1c3QgTmV0d29yazE6MDgGA1UECxMxKGMpIDE5OTkgVmVyaVNpZ24sIElu Yy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTFFMEMGA1UEAxM8VmVyaVNpZ24g Q2xhc3MgMiBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt IEczMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArwoNwtUs22e5LeWU J92lvuCwTY+zYVY81nzD9M0+hsuiiOLh2KRpxbXiv8GmR1BeRjmL1Za6tW8UvxDO JxOeBUebMXoT2B/Z0wI3i60sR/COgQanDTAM6/c8DyAd3HJG7qUCyFvDyVZpTMUY wZF7C9UTAJu878NIPkZgIIUq1ZC2zYugzDLdt/1AVbJQHFauzI13TccgTacxdu9o koqQHgiBVrKtaaNS0MscxCM9H5n+TOgWY47GCI72MfbS+uV23bUckqNJzc0BzWjN qWm6o+sdDZykIKbBoMXRRkwXbdKsZj+WjOCE1Db/IlnF+RFgqF8EffIa9iVCYQ/E Srg+iQIDAQABMA0GCSqGSIb3DQEBBQUAA4IBAQA0JhU8wI1NQ0kdvekhktdmnLfe xbjQ5F1fdiLAJvmEOjr5jLX77GDx6M4EsMjdpwOPMPOY36TmpDHf0xwLRtxyID+u 7gU8pDM/CzmscHhzS5kr3zDCVLCoO1Wh/hYozUK9dG6A2ydEp85EXdQbkJgNHkKU sQAsBNB0owIFImNjzYO1+8FtYmtpdf1dcEG59b98377BMnMiIYtYgXsVkXq642RI sH/7NiXaldDxJBQX3RiAa0YjOVT1jmIJBB2UkKab5iXiQkWquJCtvgiPqQtCGJTP cjnhsUPgKM+351psE2tJs//jGHyJizNdrDPXp/naOlXJWBD5qu9ats9LS98q -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY oJ2daZH9 -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDAjCCAmsCEDKIjprS9esTR/h/xCA3JfgwDQYJKoZIhvcNAQEFBQAwgcExCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh c3MgNCBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgNCBQdWJsaWMg UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB AQUAA4GNADCBiQKBgQC68OTP+cSuhVS5B1f5j8V/aBH4xBewRNzjMHPVKmIquNDM HO0oW369atyzkSTKQWI8/AIBvxwWMZQFl3Zuoq29YRdsTjCG8FE3KlDHqGKB3FtK qsGgtG7rL+VXxbErQHDbWk2hjh+9Ax/YA9SPTJlxvOKCzFjomDqG04Y48wApHwID AQABMA0GCSqGSIb3DQEBBQUAA4GBAIWMEsGnuVAVess+rLhDityq3RS6iYF+ATwj cSGIL4LcY/oCRaxFWdcqWERbt5+BO5JoPeI3JPV7bI92NZYJqFmduc4jq3TWg/0y cyfYaT5DdPauxYma51N86Xv2S/PBZYPejYqcPIiNOVn8qj8ijaHBZlCBckztImRP T8qAkbYp -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDzTCCAzagAwIBAgIQU2GyYK7bcY6nlLMTM/QHCTANBgkqhkiG9w0BAQUFADCB wTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTwwOgYDVQQL EzNDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 IC0gRzIxOjA4BgNVBAsTMShjKSAxOTk4IFZlcmlTaWduLCBJbmMuIC0gRm9yIGF1 dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdv cmswHhcNMDAwOTI2MDAwMDAwWhcNMTAwOTI1MjM1OTU5WjCBpTEXMBUGA1UEChMO VmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsx OzA5BgNVBAsTMlRlcm1zIG9mIHVzZSBhdCBodHRwczovL3d3dy52ZXJpc2lnbi5j b20vcnBhIChjKTAwMSwwKgYDVQQDEyNWZXJpU2lnbiBUaW1lIFN0YW1waW5nIEF1 dGhvcml0eSBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0hmdZ8IAIVli zrQJIkRpivglWtvtDbc2fk7gu5Q+kCWHwmFHKdm9VLhjzCx9abQzNvQ3B5rB3UBU /OB4naCTuQk9I1F/RMIUdNsKvsvJMDRAmD7Q1yUQgZS9B0+c1lQn3y6ov8uQjI11 S7zi6ESHzeZBCiVu6PQkAsVSD27smHUCAwEAAaOB3zCB3DAPBgNVHRMECDAGAQH/ AgEAMEUGA1UdIAQ+MDwwOgYMYIZIAYb4RQEHFwEDMCowKAYIKwYBBQUHAgEWHGh0 dHBzOi8vd3d3LnZlcmlzaWduLmNvbS9ycGEwMQYDVR0fBCowKDAmoCSgIoYgaHR0 cDovL2NybC52ZXJpc2lnbi5jb20vcGNhMy5jcmwwCwYDVR0PBAQDAgEGMEIGCCsG AQUFBwEBBDYwNDAyBggrBgEFBQcwAaYmFiRodHRwOi8vb2NzcC52ZXJpc2lnbi5j b20vb2NzcC9zdGF0dXMwDQYJKoZIhvcNAQEFBQADgYEAgnBold+2DcIBcBlK0lRW HqzyRUyHuPU163hLBanInTsZIS5wNEqi9YngFXVF5yg3ADQnKeg3S/LvRJdrF1Ea w1adPBqK9kpGRjeM+sv1ZFo4aC4cw+9wzrhGBha/937ntag+RaypJXUie28/sJyU 58dzq6wf7iWbwBbtt8pb8BQ= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h 2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq 299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3 LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd 7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw ++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt 398znM/jra6O1I7mT1GvFpLgXPYHDw== -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0 MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13 5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo 7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/ 0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7 nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ 33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ O+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- install pear2\Pyrus\ScriptFrontend\Commands install Install a package. Use install --plugin to install plugins i package 1 0 package.xml, local package archive, remove package archive, or abstract package. Installs listed packages. local package.xml example: php pyrus.phar install package.xml local package archive example: php pyrus.phar install PackageName-1.2.0.tar remote package archive example: php pyrus.phar install http://www.example.com/PackageName-1.2.0.tgz Examples of an abstract package: php pyrus.phar install PackageName installs PackageName from the default channel with stability preferred_state php pyrus.phar pear/PackageName installs PackageName from the pear.php.net channel with stability preferred_state php pyrus.phar install channel://doc.php.net/PackageName installs PackageName from the doc.php.net channel with stability preferred_state php pyrus.phar install PackageName-beta installs PackageName from the default channel, beta or stable stability php pyrus.phar install PackageName-1.2.0 installs PackageName from the default channel, version 1.2.0 upgrade pear2\Pyrus\ScriptFrontend\Commands upgrade Upgrade a package. Use upgrade --plugin to upgrade plugins up package 1 0 package.xml, local package archive, remove package archive, or abstract package. Installs or upgrades listed packages. local package.xml example: php pyrus.phar install package.xml local package archive example: php pyrus.phar install PackageName-1.2.0.tar remote package archive example: php pyrus.phar install http://www.example.com/PackageName-1.2.0.tgz Examples of an abstract package: php pyrus.phar install PackageName installs PackageName from the default channel with stability preferred_state php pyrus.phar pear/PackageName installs PackageName from the pear.php.net channel with stability preferred_state php pyrus.phar install channel://doc.php.net/PackageName installs PackageName from the doc.php.net channel with stability preferred_state php pyrus.phar install PackageName-beta installs PackageName from the default channel, beta or stable stability php pyrus.phar install PackageName-1.2.0 installs PackageName from the default channel, version 1.2.0 uninstall pear2\Pyrus\ScriptFrontend\Commands uninstall Uninstall a package. Use uninstall --plugin to uninstall plugins un package 1 0 channel/PackageName of packages to uninstall Uninstall a package Uninstalls packages. Example: php pyrus.phar uninstall PackageName uninstalls [default channel]/PackageName php pyrus.phar uninstall channelname/PackageName uninstalls package PackageName from channel channelname. info pear2\Pyrus\ScriptFrontend\Commands info Display information about a package in package 0 0 Package name, local package archive, or package.xml. field 0 1 one of "description", "notes", "files" Display information about a package This command is used to display a list of information on a package, such as the maintainers, the stability and version or versions available (for remote packages). If passed "description" or "notes", display the complete text of these fields If passed "files", list the files in the package (on-disk location for installed packages) build pear2\Pyrus\ScriptFrontend\Commands build Build a PHP extension package from source and install the compiled extension b PackageName 1 0 Package name to build. Build a PECL package from source, and install the compiled extension. This command is used to build an extension. It performs an automatic version of: phpize --clean phpize ./configure make make install In the source directory of the package. list-upgrades pear2\Pyrus\ScriptFrontend\Commands listUpgrades List packages with upgrades available lu List packages with upgrades available. This command lists all packages that have upgrades available within the current preferred_state or the installed package's stability, whichever is less stable. remote-list pear2\Pyrus\ScriptFrontend\Commands listAll List all remote packages in a channel, organized by category rd channel 0 0 Channel name to retrieve remote information about. List all remote packages in a channel, organized by category This command present an alphabetized list of all packages with the latest release and package summary. Installed packages are marked with an *. If the basic option is specified, only package name, latest release, and latest stable release are provided download pear2\Pyrus\ScriptFrontend\Commands download Download a remote package to the current directory d package 1 0 package.xml, local package archive, remove package archive, or abstract package. Download a remote package. This command downloads a package to the current directory. It can download a remote package or copy a local package (although cp may be more efficient) list-packages pear2\Pyrus\ScriptFrontend\Commands listPackages List all installed packages in all channels l List all installed packages. This command lists all installed packages organized by channel and by installation location. list-channels pear2\Pyrus\ScriptFrontend\Commands listChannels List all discovered channels lc List all discovered channels. This command lists channels already known. Use channel-discover or channel-add to add a new channel. channel-discover pear2\Pyrus\ScriptFrontend\Commands channelDiscover Discover a new channel di channel 0 0 Channel name Discover a new channel. This command searches for a channel.xml first at a secure and then unsecured http address. Examples: php pyrus.phar channel-discover pear.example.com This tries to locate https://pear.example.com/channel.xml and if that fails, http://pear.example.com/channel.xml, and then adds the channel to the registry. Use channel-add to add a local channel.xml to the registry channel-add pear2\Pyrus\ScriptFrontend\Commands channelAdd Add a new channel to the registry ca channelfile 0 0 Path to local channel.xml file Add a new channel to the registry. Use channel-discover to add a remote channel to the registry. channel-del pear2\Pyrus\ScriptFrontend\Commands channelDel Remove a channel from the registry cd channel 0 0 Channel name Remove an existing channel from the registry. pear2.php.net, pear.php.net, pecl.php.net, and doc.php.net cannot be removed from the registry. upgrade-registry pear2\Pyrus\ScriptFrontend\Commands upgradeRegistry Upgrade an old PEAR installation to the new registry format ur path 0 0 Path to PEAR registry to upgrade Upgrade an old PEAR installation to the new Sqlite and XML registry. This command does not remove the old PEAR registry, but creates a duplicate in the new Sqlite and XML formats, so that Pyrus can take advantage of the greater stability and speed of the new format. run-scripts pear2\Pyrus\ScriptFrontend\Commands runScripts Run all post-install scripts for a package r package 1 0 Package name for which to run post-install scripts Run all post-install scripts for a package. This command runs each post-install script, and is interactive, prompting for answers to queries posed by the post-install script, and executes based on the answers provided. config-show pear2\Pyrus\ScriptFrontend\Commands configShow Show all configuration values cs List all configuration values. This lists configuration values, organized by system configuration settings and user configuration settings. set pear2\Pyrus\ScriptFrontend\Commands set Set a configuration value set variable 0 0 Configuration variable name. This can be a system or user variable. value 0 0 Value to set the variable. Set a configuration variable. For example: php pyrus.phar set download_dir /home/blah/downloads get pear2\Pyrus\ScriptFrontend\Commands get Get a configuration value get variable 0 0 Configuration variable name. This can be a system or user variable. Get a configuration variable. For example: php pyrus.phar get download_dir mypear pear2\Pyrus\ScriptFrontend\Commands mypear Set a configuration value m path 1 0 Set the path of your preferred PEAR locations. Set the path of your preferred PEAR locations. For example: to set a local PEAR install at /home/user/pear and a system install at /usr/local/lib/php, do php pyrus.phar mypear /home/user/pear /usr/local/lib/php On windows: php pyrus.phar mypear "C:\Documents and Settings\User\pear" C:\php5 This is a convenience alias to the set command with my_pear_path. help pear2\Pyrus\ScriptFrontend\Commands help Get help on a particular command, or all commands h command 0 1 Command to get help on. Leave blank to get help on all commands Get detailed help on a command. Class implementing command name Relative path within php_dir to search for this role's classes in the autoloader. If not present, no additional autoloader is added to the autoloader chain. function within the command class that will handle the argument callback. Arguments: command name, option name Return: value to set the option result to Class implementing custom role A method in the class that implements package-time validation Relative path within php_dir to search for this role's classes in the autoloader. If not present, no additional autoloader is added to the autoloader chain. Should contain PHP source to execute to retrieve the default value. The source must set the variable $default to the default value system configuration variables are stored in the actual installation, user configuration variables are installation-independent. channel-specific configuration variables are also installation-independent, but unique for each channel. Class implementing custom task Relative path within php_dir to search for this task's classes in the autoloader make pear2\Pyrus\ScriptFrontend\Commands dummyStub Create or update a package.xml from a standard PEAR2 directory layout mk packagename 0 1 Name of the package to create, default is grabbed from existing package.xml. channel 0 1 Name of the channel of the package to create, default is grabbed from existing package.xml or pear2.php.net. dir 0 1 path to directory to make the packagefile for. Make a package.xml file from a standard PEAR2 directory layout. This command looks for these standard files: CREDITS, README, RELEASE-X.Y.Z (where X.Y.Z is the release version) API-X.Y.Z (where X.Y.Z is the API version) and for a standard directory layout of src/ PHP files data/ Data files tests/ Test files doc/ Documentation files examples/ Example files (documentation) scripts/ Executable files, scripts www/ Web files customrole/ Custom installer role xml definition files customtask/ Custom installer task xml definition files customcommand/ Custom command xml definition files The CREDITS file must have this format: ;; comments ignored Maintainer One [handle1] <email@example.com> (role) Maintainer Two [handle2] <email@example.com> (role) Where role is one of lead, developer, contributor, helper. The first line of README is used as the summary of the package. RELEASE-X.Y.Z is used as the release notes. if --packagexmlsetup is specified, the script should work with variable $package for modifying the package.xml, and $compatible for the compatible one (if present). If --packagexmlsetup is not specified, and packagexmlsetup.php exists in the same directory where the package.xml will go, it will be used. if --package is specified, it should be a comma-delimited list of package formats, such as --package=phar,tar,zip pickle pear2\Pyrus\ScriptFrontend\Commands dummyStub Create or update a package.xml and then package a PECL extension release pi packagename 0 1 Name of the package to create. If blank, the name is drawn from existing package.xml channel 0 1 Name of the channel of the package to create, default is pecl.php.net or whatever is in package.xml. dir 0 1 path to Package directory, default is the current directory. extension 1 1 source file extension (default is c, cc, h, m4, w32, re, y, l, frag). Create or update a package.xml and then package a PECL extension release. This command looks for these standard files: CREDITS, README, RELEASE-X.Y.Z (where X.Y.Z is the release version), API-X.Y.Z (where X.Y.Z is the API version) and for a standard directory layout of / Extension source files data/ Data files tests/ Test files doc/ Documentation files examples/ Example files (documentation) The CREDITS file must have this format: ;; comments ignored Maintainer One [handle1] <email@example.com> (role) Maintainer Two [handle2] <email@example.com> (role) Where role is one of lead, developer, contributor, helper. The first line of README is used as the summary of the package. RELEASE-X.Y.Z is used as the release notes. package pear2\Pyrus\ScriptFrontend\Commands dummyStub Create a release from an existing package.xml p packagexml 0 1 path to the package.xml for this package. Create a release from an existing package.xml If the package.xml is not specified, here is the search order - ./package.xml - if package.xml is version 1.0, ./package2.xml Use PEAR to validate package.xml version 1.0, Pyrus will not validate it. Packages with a PEAR2 package.xml are packaged using Pyrus, packages with a PEAR package.xml (pearinstaller dep is not >= 2.0.0a1) are packaged straight into a tar archive. By default, an attempt is made to make a .phar release for a Pyrus package, falling back to a .tgz or .tar. PEAR packages are only ever packaged as .tgz or .tar. If the --stub option is not explicit and stub.php exists in the same directory as package.xml, it will be used as the stub for phar archives. if the --extrasetup option is not explicit and extrasetup.php exists in the same directory as package.xml, it will be used for extra setup for all archives. run-phpt pear2\Pyrus\ScriptFrontend\Commands dummyStub Run PHPT tests rp path 1 1 path to tests, or to the tests directory followed by source directory if --modified (default is ./tests ./src). Run PHPT tests This command can be used to execute tests for PECL extensions, or for packages written using phpt tests. The --modified option allows running only tests that have been modified, added, or are affected by modified source files. Coverage can be viewed in a web browser by opening pear2coverage.phar.php generate-pear2 pear2\Pyrus\ScriptFrontend\Commands dummyStub Generate the subversion source layout for a new PEAR2 package gp package 0 0 Package name channel 0 1 Channel name, defaults to pear2.php.net Create the subversion source layout for a new PEAR2 package. This command is used to create a bare skeleton for a new PEAR2 package as it will reside in Subversion. It creates everything needed except the source code. generate-ext pear2\Pyrus\ScriptFrontend\Commands dummyStub Generate the subversion source layout for a new PHP extension that is PECL-ready es extension 0 0 Extension name Create the subversion source layout for a new PHP extension package. This command is used to create a bare skeleton for a new PECL package or PHP extension as it will reside in Subversion. This is designed to provide all of the functionality of the ext_skel command but also generates a package.xml and other files that can be used to automatically update for a release. If the --proto option is specified, the file passed to this option must contain only function prototypes, one per line. Here are 4 examples showing all of the supported types for a function or a method: int myfunc(string firstarg, unicode secondarg, array thirdarg, object fourtharg [, double optionalarg1 [, float optionalarg2 [, callback optionalarg3 [, text optionalarg4]]]]) void Myclass::myfunc(array|object arg1, bool arg2, class arg3, resource arg4, mixed arg5 [, ... varargs]) static int Myclass::staticfunc() protected string Myclass::otherguy([mixed optionalarg]) static protected object Myclass::factory(text path) This command automatically creates class definitions as well as ZEND_ARG_INFO for parameters to provide useful reflection to your extension's users. uri of the package that contains the source of this extension this is ignored if the release type is bundle for php script releases for extension source releases for compiled extension source releases for bundling several releases together in one release tells the installer not to install the default dependency group absolute required dependencies all other optional dependency groups simple optional dependencies version string regex name of the package that contains the source of this extension (can be the same if the source and binaries are in the same package) if a package can provide one or more compatible extensions (dblib/sybase/mssql for instance) uri of the package that contains the source of this extension this is ignored if the release type is bundle for php script releases for extension source releases for zend extension source releases for compiled extension source releases for compiled zend extension source releases for bundling several releases together in one release tells the installer not to install the default dependency group absolute required dependencies all other optional dependency groups simple optional dependencies version string regex name of the package that contains the source of this extension (can be the same if the source and binaries are in the same package) if a package can provide one or more compatible extensions (dblib/sybase/mssql for instance) scs-update pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple channel server: Update all releases of a within the get/ directory. su This command scans all existing .tar and .tgz files within the get/ directory, and then uses them to re-generate the REST files in the rest/ directory. It must be executed from the channel root directory, the directory must contain the get/ directory with all releases, and must contain channel.xml. In addition, the handle configuration variable must be set to your handle scs-create pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple channel server: Create a channel.xml, get/ and rest/ directory for a channel sc name 0 0 Name of the channel to create. This should be the full name, such as pear2.php.net or pear.example.com/path summary 0 0 Short, 1-line description of the channnel alias 0 1 Channel alias, such as pear2 for pear2.php.net file 0 1 full path to the channel.xml to create. Default is channel.xml in the working directory This command creates a new channel in the current directory, or the directory specified by the location of the channel.xml file. scs-add-maintainer pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple Channel Server: Add a new maintaing developer to the channel sam handle 0 0 Developer handle as used in package.xml name 0 0 Developer name uri 0 1 Developer homepage This command adds a developer to the channel, and is useful for adding developers to be listed prior to making their first release. scs-add-category pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple Channel Server: Add a new category to the channel sac category 0 0 Name of the category. This may contain spaces (use "" to contain them) description 0 0 Short description of the category's packages Categories are used to organize channels with large numbers of packages. Use this command to create a new category. scs-categorize pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple Channel Server: Categorize a package scat package 0 0 Package to add to the category category 0 0 Name of the category. This may contain spaces (use "" to contain them) Use this command to add a package to a category. scs-release pear2\Pyrus\ScriptFrontend\Commands scsDummyStub Simple Channel Server: Release a package sr path 0 0 path to the release tarball Release a package. This command uses the handle configuration variable as the releasing maintainer's handle, and generates REST files for the release in the rest/ directory as well as the released tarballs in the get/ directory. #!/usr/bin/env php run($_SERVER['argv']); * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception for atomic file transaction mechanism * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\AtomicFileTransaction; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception for channels * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Interface for channel mirrors * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; interface IMirror { public function getChannel(); } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Remote REST iteration handler for category listing * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; class Remotecategories implements \ArrayAccess, \Iterator { protected $parent; protected $rest; protected $categoryList; function __construct(\pear2\Pyrus\IChannel $channelinfo) { $this->parent = $channelinfo; if (!isset($this->parent->protocols->rest['REST1.1'])) { throw new \pear2\Pyrus\Channel\Exception('Cannot access remote categories without REST1.1 protocol'); } $this->rest = new \pear2\Pyrus\REST; } function offsetGet($var) { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.1']->baseurl . 'c/' . urlencode($var) . '/packagesinfo.xml'); return new \pear2\Pyrus\Channel\Remotecategory($this->parent, $var, $info); } function offsetSet($var, $value) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } function offsetUnset($var) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } function offsetExists($var) { // implement this } function valid() { return current($this->categoryList); } function current() { $category = $this->key(); $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.1']->baseurl . 'c/' . urlencode($category) . '/packagesinfo.xml'); return new \pear2\Pyrus\Channel\Remotecategory($this->parent, $category, $info); } function key() { $cur = current($this->categoryList); return urldecode($cur['_content']); } function next() { return next($this->categoryList); } function rewind() { $this->categoryList = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.1']->baseurl . 'c/categories.xml'); $this->categoryList = $this->categoryList['c']; if (!isset($this->categoryList[0])) { $this->categoryList = array($this->categoryList); } } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Remote REST iteration handler * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; class Remotecategory implements \ArrayAccess, \Iterator, \Countable { protected $parent; protected $category; protected $packagesinfo; protected $rest; protected $minimumStability; function __construct(\pear2\Pyrus\IChannelFile $channelinfo, $category, $packagesinfo) { $this->parent = $channelinfo; $this->category = $category; if (!isset($packagesinfo['pi'])) { $packagesinfo['pi'] = array(); } elseif (!isset($packagesinfo['pi'][0])) { $packagesinfo['pi'] = array($packagesinfo['pi']); } $this->packagesinfo = $packagesinfo['pi']; usort($this->packagesinfo, function($a, $b) { return strnatcasecmp($a['p']['n'], $b['p']['n']); }); $this->rest = new \pear2\Pyrus\REST; $this->minimumStability = \pear2\Pyrus\Config::current()->preferred_state; } function __get($var) { if ($var == 'name') { return $this->category; } if ($var == 'basiclist') { $ret = array(); foreach ($this->packagesinfo as $info) { if (!isset($info['a']) || !$info['a']) { $ret[] = array('package' => $info['p']['n'], 'latest' => array('v' => 'n/a', 's' => 'n/a', 'm' => 'n/a'), 'stable' => 'n/a'); continue; } if (!isset($info['a']['r'][0])) { $info['a']['r'] = array($info['a']['r']); } $inf = array('package' => $info['p']['n'], 'latest' => current($info['a']['r']), 'stable' => 'n/a'); $inf['latest']['m'] = '5.2.0'; foreach ($info['a']['r'] as $release) { if ($release['s'] == 'stable') { $inf['stable'] = $release['v']; break; } } $ret[] = $inf; } return $ret; } } function offsetGet($var) { $lowerpackage = strtolower($var); foreach ($this->packagesinfo as $package) { if (strtolower($package['p']['n']) != $lowerpackage) { continue; } return $this->getPackage($package); } throw new Exception('Unknown remote package in ' . $this->category . ' category: "' . $var . '"'); } protected function getPackage($package) { $releases = array(); if (isset($package['a']) && $package['a']) { $releases = $package['a']['r']; if (!isset($releases[0])) { $releases = array($releases); } foreach ($releases as $i => $release) { if (!isset($release['m'])) { $releases[$i]['m'] = '5.2.0'; } } } $pxml = new \pear2\Pyrus\Channel\Remotepackage($this->parent, $releases); $pxml->channel = $package['p']['c']; $pxml->name = $package['p']['n']; $pxml->license = $package['p']['l']; $pxml->summary = $package['p']['s']; $pxml->description = $package['p']['d']; $reg = \pear2\Pyrus\Config::current()->registry; if ($reg->exists($package['p']['n'], $package['p']['c'])) { $pxml->setExplicitState($version = $reg->info($package['p']['n'], $package['p']['c'], 'version')); $found = false; foreach ($pxml as $remoteversion => $rinfo) { if (version_compare($remoteversion, $version, '<=')) { continue; } if (version_compare($rinfo['minimumphp'], phpversion(), '>')) { continue; } // found one, so upgrade is possible if dependencies pass $found = true; break; } // the installed package version satisfies this dependency, don't do anything if ($found) { $pxml->setUpgradeable(); } } else { $pxml->setExplicitState($this->minimumStability); } return $pxml; } function offsetExists($var) { $lowerpackage = strtolower($var); foreach ($this->packagesinfo as $package) { if (strtolower($package['p']['n']) != $lowerpackage) { continue; } return true; } return false; } function count() { return count($this->packagesinfo); } function offsetSet($var, $value) { throw new Exception('remote channel info is read-only'); } function offsetUnset($var) { throw new Exception('remote channel info is read-only'); } function valid() { return current($this->packagesinfo); } function current() { return $this->getPackage(current($this->packagesinfo)); } function next() { return next($this->packagesinfo); } function rewind() { return reset($this->packagesinfo); } function key() { $current = current($this->packagesinfo); return $current['p']['n']; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Remote REST iteration handler * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; class Remotepackage extends \pear2\Pyrus\PackageFile\v2 implements \ArrayAccess, \Iterator { /** * openssl CA authorities whose certs we have */ protected static $authorities = array ( 0 => 'AAACertificateServices', 1 => 'ABA.ECOMRootCA', 2 => 'AOLTimeWarnerRootCertificationAuthority1', 3 => 'AOLTimeWarnerRootCertificationAuthority2', 4 => 'AddTrustClass1CARoot', 5 => 'AddTrustExternalCARoot', 6 => 'AddTrustPublicCARoot', 7 => 'AddTrustQualifiedCARoot', 8 => 'AmericaOnlineRootCertificationAuthority1', 9 => 'AmericaOnlineRootCertificationAuthority2', 10 => 'AutoridaddeCertificacionFirmaprofesionalCIFA62634068', 11 => 'BaltimoreCyberTrustRoot', 12 => 'DigitalSignatureTrustCo.GlobalCA1', 13 => 'DigitalSignatureTrustCo.GlobalCA3', 14 => 'EquifaxSecureCA', 15 => 'EquifaxSecureeBusinessCA2', 16 => 'GoDaddyClass2CA', 17 => 'RSASecurity1024v3', 18 => 'RSASecurity2048v3', 19 => 'SecurityCommunicationRootCA', 20 => 'StarfieldClass2CA', 21 => 'TCTrustCenter,Germany,Class2CA', 22 => 'TCTrustCenter,Germany,Class3CA', 23 => 'TDCInternetRootCA', 24 => 'TaiwanGRCA', 25 => 'Verisign-RSASecureServerCA', 26 => 'VerisignClass1PublicPrimaryCertificationAuthority', 27 => 'VerisignClass1PublicPrimaryCertificationAuthority-G2', 28 => 'VerisignClass2PublicPrimaryCertificationAuthority', 29 => 'VerisignClass2PublicPrimaryCertificationAuthority-G2', 30 => 'VerisignClass3PublicPrimaryCertificationAuthority', 31 => 'VerisignClass3PublicPrimaryCertificationAuthority-G2', 32 => 'VerisignClass4PublicPrimaryCertificationAuthority-G2', 33 => 'CACertSigningAuthority', 34 => 'COMODOCertificationAuthority', 35 => 'CertumCA', 36 => 'ChambersofCommerceRoot', 37 => 'Class2PrimaryCA', 38 => 'DSTACESCAX6', 39 => 'DSTRootCAX1', 40 => 'DSTRootCAX2', 41 => 'DSTRootCAX3', 42 => 'DigiCertAssuredIDRootCA', 43 => 'DigiCertGlobalRootCA', 44 => 'DigiCertHighAssuranceEVRootCA', 45 => 'DigiNotarRootCA', 46 => 'Entrust.netCertificationAuthority(2048)', 47 => 'Entrust.netClientCertificationAuthority', 48 => 'Entrust.netClientCertificationAuthority2', 49 => 'Entrust.netSecureServerCertificationAuthority', 50 => 'Entrust.netSecureServerCertificationAuthority2', 51 => 'EntrustRootCertificationAuthority', 52 => 'EquifaxSecureGlobaleBusinessCA-1', 53 => 'EquifaxSecureeBusinessCA-1', 54 => 'FreeSSLCertificationAuthority', 55 => 'GPRoot2', 56 => 'GTECyberTrustGlobalRoot', 57 => 'GTECyberTrustRoot', 58 => 'GeoTrustGlobalCA', 59 => 'GeoTrustGlobalCA2', 60 => 'GeoTrustPrimaryCertificationAuthority', 61 => 'GeoTrustUniversalCA', 62 => 'GeoTrustUniversalCA2', 63 => 'GlobalChambersignRoot', 64 => 'GlobalSign', 65 => 'GlobalSign2', 66 => 'GlobalSignExtendedValidationCA', 67 => 'GlobalSignRootCA', 68 => 'GoDaddySecureCertificationAuthority', 69 => 'IPSCACLASE1CertificationAuthority', 70 => 'IPSCACLASE3CertificationAuthority', 71 => 'IPSCACLASEA1CertificationAuthority', 72 => 'IPSCACLASEA3CertificationAuthority', 73 => 'IPSCAChainedCAsCertificationAuthority', 74 => 'IPSCATimestampingCertificationAuthority', 75 => 'IPSSERVIDORES', 76 => 'NetLockExpressz(ClassC)Tanusitvanykiado', 77 => 'NetLockKozjegyzoi(ClassA)Tanusitvanykiado', 78 => 'NetLockMinositettKozjegyzoi(ClassQA)Tanusitvanykiado', 79 => 'NetLockUzleti(ClassB)Tanusitvanykiado', 80 => 'NetworkSolutionsCertificateAuthority', 81 => 'QuoVadisRootCA2', 82 => 'QuoVadisRootCA3', 83 => 'QuoVadisRootCertificationAuthority', 84 => 'SecureCertificateServices', 85 => 'SecureGlobalCA', 86 => 'SecureTrustCA', 87 => 'SoneraClass1CA', 88 => 'SoneraClass2CA', 89 => 'StaatderNederlandenRootCA', 90 => 'StartComCertificationAuthority', 91 => 'SwissSignGoldCA-G2', 92 => 'SwissSignPlatinumCA-G2', 93 => 'SwissSignSilverCA-G2', 94 => 'SwisscomRootCA1', 95 => 'TDCOCESCA', 96 => 'ThawtePersonalBasicCA', 97 => 'ThawtePersonalFreemailCA', 98 => 'ThawtePersonalPremiumCA', 99 => 'ThawtePremiumServerCA', 100 => 'ThawteSGCCA', 101 => 'ThawteServerCA', 102 => 'ThawteTimestampingCA', 103 => 'TrustedCertificateServices', 104 => 'TURKTRUST', 105 => 'TURKTRUST2', 106 => 'UTN-DATACorpSGC', 107 => 'UTN-USERFirst-ClientAuthenticationandEmail', 108 => 'UTN-USERFirst-Hardware', 109 => 'UTN-USERFirst-NetworkApplications', 110 => 'UTN-USERFirst-Object', 111 => 'VeriSignClass1PublicPrimaryCertificationAuthority-G3', 112 => 'VeriSignClass2PublicPrimaryCertificationAuthority-G3', 113 => 'VeriSignClass3PublicPrimaryCertificationAuthority-G3', 114 => 'VeriSignClass3PublicPrimaryCertificationAuthority-G5', 115 => 'VeriSignClass4PublicPrimaryCertificationAuthority-G3', 116 => 'VeriSignTimeStampingAuthorityCA', 117 => 'VisaeCommerceRoot', 118 => 'WellsFargoRootCertificateAuthority', 119 => 'XRampGlobalCertificationAuthority', 120 => 'beTRUSTedRootCA', 121 => 'beTRUSTedRootCA-BaltimoreImplementation', 122 => 'beTRUSTedRootCA-EntrustImplementation', 123 => 'beTRUSTedRootCA-RSAImplementation', 124 => 'thawtePrimaryRootCA', 125 => 'valicert.com', 126 => 'valicert.com2', 127 => 'valicert.com3', ); protected $parent; protected $rest; protected $releaseList; protected $remotedeps; protected $remoteAbridgedInfo; protected $versionSet = false; protected $minimumStability; protected $explicitVersion = false; protected $fullPackagexml = false; /** * Flag used to determine whether this package has been tested for upgradeability */ protected $isUpgradeable = null; static function authorities() { static $authorities = null; if ($authorities) { return $authorities; } $d = \pear2\Pyrus\Main::getDataPath() . DIRECTORY_SEPARATOR . 'x509rootcerts'; // for running out of svn if (!file_exists($d)) { $d = realpath(__DIR__ . '/../../../data/x509rootcerts'); } else { if (strpos($d, 'phar://') === 0) { if (!file_exists($temp = \pear2\Pyrus\Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'x509rootcerts')) { mkdir($temp, 0755, true); } // openssl can't process these from within a phar (pity) foreach (static::$authorities as $i => $authority) { copy($d . DIRECTORY_SEPARATOR . $authority, $temp . DIRECTORY_SEPARATOR . $authority); $authorities[$i] = $temp . DIRECTORY_SEPARATOR . $authority; } return $authorities; } } $authorities = static::$authorities; foreach ($authorities as $i => $authority) { $authorities[$i] = $d . DIRECTORY_SEPARATOR . $authority; } return $authorities; } function __construct(\pear2\Pyrus\IChannelFile $channelinfo, $releases = null) { $this->parent = $channelinfo; if (!isset($this->parent->protocols->rest['REST1.0'])) { throw new \pear2\Pyrus\Channel\Exception('Cannot access remote packages without REST1.0 protocol'); } // instruct parent::__set() to call $this->setRawVersion() when setting rawversion $this->rawMap['rawversion'] = array('setRawVersion'); $this->rest = new \pear2\Pyrus\REST; $this->releaseList = $releases; $this->minimumStability = \pear2\Pyrus\Config::current()->preferred_state; $this->explicitVersion = false; } /** * Sets the minimum stability allowed. * * This is set by a call to a package such as "pyrus install Pname-stable" * or "pyrus install Pname-beta" * * The stability is only changed if it is less stable than preferred_state. * @param string */ function setExplicitState($stability) { $states = \pear2\Pyrus\Installer::betterStates($this->minimumStability); $newstates = \pear2\Pyrus\Installer::betterStates($stability); if (count($newstates) > count($states)) { $this->minimumStability = $stability; } } function setExplicitVersion($version) { $this->explicitVersion = $version; } function getExplicitVersion() { return $this->explicitVersion; } function resetConcreteVersion() { $this->versionSet = false; } function hasConcreteVersion() { return $this->versionSet; } function setUpgradeable() { $this->isUpgradeable = true; } function isUpgradeable() { return $this->isUpgradeable; } function isPlugin() { return false; // until there is some REST in place, we have to return false } function setRawVersion($var, $value) { if (isset($this->parent->protocols->rest['REST1.3'])) { $a = $this->remoteAbridgedInfo = $this->rest->retrieveCacheFirst( $this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . strtolower($this->name) . '/v2.' . $value['release'] . '.xml'); $this->packageInfo['version']['api'] = $a['a']; } else { $a = $this->remoteAbridgedInfo = $this->rest->retrieveCacheFirst( $this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . strtolower($this->name) . '/' . $value['release'] . '.xml'); } $this->packageInfo['version'] = $value; $this->stability['release'] = $a['st']; $this->license['name'] = $a['l']; $this->summary = $a['s']; $this->description = $a['d']; list($this->date, $this->time) = explode(' ', $a['da']); $this->notes = $a['n']; $this->versionSet = true; } function getDownloadURL($ext = '') { if (!$this->versionSet) { // this happens when doing a simple download outside of an install $this->rewind(); $ok = \pear2\Pyrus\Installer::betterStates($this->minimumStability, true); foreach ($this->releaseList as $versioninfo) { if (isset($versioninfo['m'])) { // minimum PHP version required if (version_compare($versioninfo['m'], $this->getPHPVersion(), '>=')) { continue; } } if (!in_array($versioninfo['s'], $ok) && !isset(\pear2\Pyrus\Main::$options['force'])) { // release is not stable enough continue; } $this->version['release'] = $versioninfo['v']; break; } } return $this->remoteAbridgedInfo['g'] . $ext; } function download() { $url = $this->getDownloadURL(); $errs = new \pear2\MultiErrors; $certdownloaded = false; if (extension_loaded('openssl')) { // try to download openssl x509 signature certificate for our release try { $cert = \pear2\Pyrus\Main::download($url . '.pem'); $cert = $cert->body; $certdownloaded = true; } catch (\pear2\Pyrus\HTTPException $e) { // file does not exist, ignore } if ($certdownloaded) { $info = openssl_x509_parse($cert); if (!$info) { throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate is not a certificate'); } if (true !== openssl_x509_checkpurpose($cert, X509_PURPOSE_SSL_SERVER, self::authorities())) { throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate is invalid'); } // now verify that this cert is in fact the releasing maintainer's certificate // by verifying that alternate name is the releaser's email address if (!isset($info['subject']) || !isset($info['subject']['emailAddress'])) { throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate does not contain' . ' an alternate name corresponding to the releaser\'s email address'); } // retrieve releaser's email address if ($info['subject']['emailAddress'] != $this->maintainer[$this->remoteAbridgedInfo['m']]->email) { throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name . ' - releasing maintainer\'s certificate ' . 'alternate name does not match the releaser\'s email address ' . $this->maintainer[$this->remoteAbridgedInfo['m']]->email); } $key = openssl_pkey_get_public($cert); $key = openssl_pkey_get_details($key); $key = $key['key']; } } // first try to download .phar, then .tgz, then .tar, then .zip // if a public key was downloaded, save it where ext/phar will // look to validate the openssl signature foreach (array('.phar', '.tgz', '.tar') as $ext) { try { if ($certdownloaded) { if (!file_exists(\pear2\Pyrus\Config::current()->download_dir)) { mkdir(\pear2\Pyrus\Config::current()->download_dir, 0755, true); } file_put_contents($pubkey = \pear2\Pyrus\Config::current()->download_dir . DIRECTORY_SEPARATOR . basename($url) . $ext . '.pubkey', $key); } $ret = new \pear2\Pyrus\Package\Remote($url . $ext); if ($certdownloaded) { if ($ext == '.tar' || $ext == '.tgz') { if (phpversion() == '5.3.0') { \pear2\Pyrus\Logger::log(0, 'WARNING: ' . $url . $ext . ' may not be installable ' . 'with PHP version 5.3.0, the PHP extension phar ' . 'has a bug verifying openssl signatures for ' . 'tar and tgz files. Either upgrade to PHP 5.3.1 ' . 'or install the .zip version'); } } } return $ret; } catch (\pear2\Pyrus\HTTPException $e) { if ($certdownloaded && file_exists($pubkey)) { unlink($pubkey); } $errs->E_ERROR[] = $e; } catch (\Exception $e) { if ($certdownloaded && file_exists($pubkey)) { unlink($pubkey); } $errs->E_ERROR[] = $e; throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name, $errs); } } try { // phar does not support signatures for zip archives $ret = new \pear2\Pyrus\Package\Remote($url . '.zip'); return $ret; } catch (\pear2\Pyrus\HTTPException $e) { $errs->E_ERROR[] = $e; throw new \pear2\Pyrus\Package\Exception( 'Could not download abstract package ' . $this->channel . '/' . $this->name, $errs); } catch (\Exception $e) { $errs->E_ERROR[] = $e; throw new \pear2\Pyrus\Package\Exception( 'Invalid abstract package ' . $this->channel . '/' . $this->name, $errs); } } function offsetGet($var) { $lowerpackage = strtolower($var); try { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'p/' . $lowerpackage . '/info.xml'); } catch (\Exception $e) { throw new \pear2\Pyrus\Channel\Exception('package ' . $var . ' does not exist', $e); } if (is_string($this->releaseList)) { $ok = \pear2\Pyrus\Installer::betterStates($this->releaseList, true); if (isset($this->parent->protocols->rest['REST1.3'])) { $rinfo = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . $lowerpackage . '/allreleases2.xml'); } else { $rinfo = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . $lowerpackage . '/allreleases.xml'); } if (!isset($rinfo['r'][0])) { $rinfo['r'] = array($rinfo['r']); } $releases = array(); foreach ($rinfo['r'] as $release) { if (!in_array($release['s'], $ok)) { continue; } if (!isset($release['m'])) { $release['m'] = '5.2.0'; } $releases[] = $release; } $this->releaseList = $releases; } $pxml = clone $this; $pxml->channel = $info['c']; $pxml->name = $info['n']; $pxml->license = $info['l']; $pxml->summary = $info['s']; $pxml->description = $info['d']; return $pxml; } function offsetSet($var, $value) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } function offsetUnset($var) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } /** * This is very expensive, use sparingly if at all */ function offsetExists($var) { try { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'p/' . strtolower($var) . '/info.xml'); } catch (\Exception $e) { return false; } return true; } function valid() { return current($this->releaseList); } function current() { $info = current($this->releaseList); if (!isset($info['m'])) { $info['m'] = '5.2.0'; // guess something lower than us } // setting this allows us to retrieve information specific to this // version $this->version['release'] = $info['v']; return array('stability' => $info['s'], 'minimumphp' => $info['m']); } function key() { $info = current($this->releaseList); return $info['v']; } function next() { return next($this->releaseList); } function rewind() { if (is_array($this->releaseList)) { return reset($this->releaseList); } if (!$this->name) { throw new \pear2\Pyrus\Channel\Exception('Cannot iterate without first choosing a remote package'); } if (isset($this->parent->protocols->rest['REST1.3'])) { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . strtolower($this->name) . '/allreleases2.xml'); } else { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . strtolower($this->name) . '/allreleases.xml'); } $this->releaseList = $info['r']; if (!isset($this->releaseList[0])) { $this->releaseList = array($this->releaseList); } } function getReleaseList() { $this->rewind(); return $this->releaseList; } function getDependencies() { // dynamically retrieve the dependencies from the remote server when requested $deps = unserialize($this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . strtolower($this->name) . '/deps.' . $this->version['release'] . '.txt')); if ($deps) { $this->packageInfo['dependencies'] = $deps; } return parent::getDependencies(); } function getMaintainer() { // can't get email addresses from REST, have to grab the entire package.xml $this->grabEntirePackagexml(); return parent::getMaintainer(); } function getPackagefileObject() { return $this; } /** * This is used to download the entire package.xml, which is useful * for commands such as the info command. */ function grabEntirePackagexml() { if ($this->fullPackagexml) { return; } if (!$this->explicitVersion) { $fakedep = new \pear2\Pyrus\PackageFile\v2\Dependencies\Package( 'required', 'package', null, array('name' => $this->name, 'channel' => $this->channel, 'uri' => null, 'min' => null, 'max' => null, 'recommended' => null, 'exclude' => null, 'providesextension' => null, 'conflicts' => null), 0); $this->figureOutBestVersion($fakedep); } $pxml = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . strtolower($this->name) . '/package.' . $this->version['release'] . '.xml'); $this->fromArray(array('package' => $pxml)); $this->fullPackagexml = true; } /** * For unit testing purposes */ function getPHPVersion() { return phpversion(); } function getAllUpgrades($currentversion) { // set up release list if not done yet $this->rewind(); $ok = \pear2\Pyrus\Installer::betterStates($this->minimumStability, true); $ret = array(); foreach ($this->releaseList as $versioninfo) { if (isset($versioninfo['m'])) { // minimum PHP version required if (version_compare($versioninfo['m'], $this->getPHPVersion(), '>=')) { continue; } } if (version_compare($versioninfo['v'], $currentversion, '<=')) { continue; } if (!in_array($versioninfo['s'], $ok)) { // release is not stable enough continue; } $ret[] = $versioninfo; } return $ret; } /** * Figure out which version is best, and use this, or error out if none work * @param \pear2\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep * the composite of all dependencies on this package, as calculated * by {@link \pear2\Pyrus\Package\Dependency::getCompositeDependency()} */ function figureOutBestVersion(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $compositeDep, $versions = null, \pear2\Pyrus\PackageFile\v2\Dependencies\Package $compositeConflictingDep = null) { // set up release list if not done yet $this->rewind(); $ok = \pear2\Pyrus\Installer::betterStates($this->minimumStability, true); $v = $this->explicitVersion; $n = $this->channel . '/' . $this->name; $failIfExplicit = function($versioninfo) use ($v, $n) { if ($v && $versioninfo['v'] == $v) { throw new \pear2\Pyrus\Channel\Exception($n . ' Cannot be installed, it does not satisfy ' . 'all dependencies'); } }; foreach ($this->releaseList as $versioninfo) { if (isset(\pear2\Pyrus\Main::$options['force'])) { // found one if ($this->versionSet && $versioninfo['v'] != $this->version['release']) { // inform the installer we need to reset dependencies $this->version['release'] = $versioninfo['v']; return true; } $this->version['release'] = $versioninfo['v']; return; } if ($versions && !in_array($versioninfo['v'], $versions)) { continue; } if (!isset(\pear2\Pyrus\Main::$options['force']) && isset($versioninfo['m'])) { // minimum PHP version required if (version_compare($versioninfo['m'], $this->getPHPVersion(), '>=')) { $failIfExplicit($versioninfo); continue; } } if (!in_array($versioninfo['s'], $ok) && !isset(\pear2\Pyrus\Main::$options['force'])) { // release is not stable enough continue; } if ($this->explicitVersion && $versioninfo['v'] != $this->explicitVersion) { continue; } if (!$compositeDep->satisfied($versioninfo['v'])) { $failIfExplicit($versioninfo); continue; } if ($compositeConflictingDep && !$compositeConflictingDep->satisfied($versioninfo['v'])) { $failIfExplicit($versioninfo); continue; } $paranoia = \pear2\Pyrus\Main::getParanoiaLevel(); if (!$this->explicitVersion && $paranoia > 1) { // first, we check to see if we are upgrading if (isset(\pear2\Pyrus\Main::$options['upgrade'])) { // now we check to see if we are installed if (isset(\pear2\Pyrus\Config::current()->registry->package[$n])) { $installed = \pear2\Pyrus\Config::current() ->registry->info($this->name, $this->channel, 'apiversion'); $installed = explode('.', $installed); if (count($installed) == 2) { $installed[] = '0'; } if (count($installed) == 1) { $installed[] = '0'; $installed[] = '0'; } if (isset($this->parent->protocols->rest['REST1.3'])) { $api = $this->rest->retrieveCacheFirst( $this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . strtolower($this->name) . '/v2.' . $versioninfo['v'] . '.xml'); } else { throw new \pear2\Pyrus\Channel\Exception('Channel ' . $this->channel . ' does not support ' . 'a paranoia greater than 1'); } $api = explode('.', $api['a']); if (count($api) == 2) { $api[] = '0'; } if (count($api) == 1) { $api[] = '0'; $api[] = '0'; } if ($paranoia > 4) { $paranoia = 4; } switch ($paranoia) { case 4 : if ($installed != $api) { \pear2\Pyrus\Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has changed'); continue 2; } break; case 3 : if ($installed[0] == $api[0] && $installed[1] != $api[1]) { \pear2\Pyrus\Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API has added' . ' new features'); continue 2; } // break intentionally omitted case 2 : if ($installed[0] != $api[0]) { \pear2\Pyrus\Logger::log(0, 'Skipping ' . $this->channel . '/' . $this->name . ' version ' . $versioninfo['v'] . ', API breaks' . ' backwards compatibility'); continue 2; } break; } } } } // found one if ($this->versionSet && $versioninfo['v'] != $this->version['release']) { // inform the installer we need to reset dependencies $this->version['release'] = $versioninfo['v']; return true; } $this->version['release'] = $versioninfo['v']; return; } throw new \pear2\Pyrus\Channel\Exception('Unable to locate a package release for ' . $this->channel . '/' . $this->name . ' that can satisfy all dependencies'); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Remote REST iteration handler for package listing * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Channel; class Remotepackages implements \ArrayAccess, \Iterator { protected $parent; public $stability = null; protected $rest; protected $packageList; function __construct(\pear2\Pyrus\IChannel $channelinfo) { $this->parent = $channelinfo; if (!isset($this->parent->protocols->rest['REST1.0'])) { throw new \pear2\Pyrus\Channel\Exception('Cannot access remote packages without REST1.0 protocol'); } $this->rest = new \pear2\Pyrus\REST; } function offsetGet($var) { if ($var !== 'devel' && $var !== 'alpha' && $var !== 'beta' && $var !== 'stable') { throw new \pear2\Pyrus\Channel\Exception('Invalid stability ' . $var . ' requested, must be one of ' . 'devel, alpha, beta, stable'); } $a = clone $this; $a->stability = $var; return $a; } function offsetSet($var, $value) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } function offsetUnset($var) { throw new \pear2\Pyrus\Channel\Exception('remote channel info is read-only'); } function offsetExists($var) { // implement this } function valid() { return current($this->packageList); } function current() { if ($this->stability) { $info = current($this->packageList); $lowerpackage = $info[0]; $releases = $info[1]; } else { $lowerpackage = current($this->packageList); } $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'p/' . $lowerpackage . '/info.xml'); if (isset($releases)) { $pxml = new \pear2\Pyrus\Channel\Remotepackage($this->parent, $releases); } else { $pxml = new \pear2\Pyrus\Channel\Remotepackage($this->parent); } $pxml->channel = $info['c']; $pxml->name = $info['n']; $pxml->license = $info['l']; $pxml->summary = $info['s']; $pxml->description = $info['d']; return $pxml; } function getPackage($package) { $lowerpackage = strtolower($package); if (isset($this->parent->protocols->rest['REST1.3'])) { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . $lowerpackage . '/allreleases2.xml'); } else { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . $lowerpackage . '/allreleases.xml'); } if (!isset($info['r'][0])) { $info['r'] = array($info['r']); } // filter the package list for packages of this stability or better $ok = \pear2\Pyrus\Installer::betterStates($this->stability, true); $releases = array(); foreach ($info['r'] as $release) { if ($this->stability) { if (!in_array($release['s'], $ok)) { continue; } } if (!isset($release['m'])) { $release['m'] = '5.2.0'; } $releases[] = $release; } $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'p/' . $lowerpackage . '/info.xml'); $pxml = new \pear2\Pyrus\Channel\Remotepackage($this->parent, $releases); $pxml->channel = $info['c']; $pxml->name = $info['n']; $pxml->license = $info['l']; $pxml->summary = $info['s']; $pxml->description = $info['d']; return $pxml; } function key() { return key($this->packageList); } function next() { return next($this->packageList); } function rewind() { $this->packageList = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'p/packages.xml'); $this->packageList = $this->packageList['p']; if (!is_array($this->packageList)) { $this->packageList = array($this->packageList); } if (isset($this->stability)) { // filter the package list for packages of this stability or better $ok = \pear2\Pyrus\Installer::betterStates($this->stability, true); $filtered = array(); foreach ($this->packageList as $lowerpackage) { if (isset($this->parent->protocols->rest['REST1.3'])) { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.3']->baseurl . 'r/' . $lowerpackage . '/allreleases2.xml'); } else { $info = $this->rest->retrieveCacheFirst($this->parent->protocols->rest['REST1.0']->baseurl . 'r/' . $lowerpackage . '/allreleases.xml'); } if (!isset($info['r'][0])) { $info['r'] = array($info['r']); } $releases = array(); foreach ($info['r'] as $release) { if (!in_array($release['s'], $ok)) { continue; } if (!isset($release['m'])) { $release['m'] = '5.2.0'; } $releases[] = $release; } if (!count($releases)) { continue; } $filtered[] = array($lowerpackage, $releases); } $this->packageList = $filtered; } } }fromArray(parent::parse($data, $schema)); } else { $ret->fromArray(parent::parseString($data, $schema)); } } catch (\Exception $e) { throw new \pear2\Pyrus\ChannelFile\Exception('Invalid channel.xml', null, $e); } return $ret; } }info = $info; $this->parent = $parent; $this->index = $index; } function current() { $info = current($this->info['baseurl']); if ($info['_content'][strlen($info['_content'])-1] != '/') { return $info['_content'] . '/'; } return $info['_content']; } function rewind() { if (isset($this->info['baseurl'])) { reset($this->info['baseurl']); } } function key() { return $this->info['baseurl'][key($this->info['baseurl'])]['attribs']['type']; } function next() { return next($this->info['baseurl']); } function valid() { if (!isset($this->info['baseurl'])) { return false; } return current($this->info['baseurl']); } function count() { if (!isset($this->info['baseurl'])) { return 0; } return count($this->info['baseurl']); } function __get($var) { if (!isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use -> to access ' . 'REST protocols, use []'); } if ($var === 'baseurl') { if (isset($this->info['_content']) && $this->info['_content'][strlen($this->info['_content'])-1] != '/') { return $this->info['_content'] . '/'; } return $this->info['_content']; } throw new \pear2\Pyrus\ChannelFile\Exception('Unknown variable ' . $var); } function __set($var, $value) { if (!isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use -> to access ' . 'REST protocols, use []'); } if ($var === 'baseurl') { $this->info['_content'] = $value; return $this->save(); } throw new \pear2\Pyrus\ChannelFile\Exception('Unknown variable ' . $var); } function offsetGet($protocol) { if (isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use [] to access ' . 'baseurl, use ->'); } if (!isset($this->info['baseurl'])) { return new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols\REST( array('attribs' => array('type' => $protocol), '_content' => null), $this, 0); } foreach ($this->info['baseurl'] as $baseurl) { if (strtolower($baseurl['attribs']['type']) == strtolower($protocol)) { $ret = new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols\REST( $baseurl, $this, $protocol ); return $ret; } } return new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols\REST( array('attribs' => array('type' => $protocol), '_content' => null), $this, count($this->info['baseurl'])); } function offsetSet($protocol, $value) { if (isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use [] to access ' . 'baseurl, use ->'); } if (!($value instanceof self)) { throw new \pear2\Pyrus\ChannelFile\Exception('Can only set REST protocol ' . ' to a \pear2\Pyrus\ChannelFile\v1\Servers\Protocol\REST object'); } if (!isset($this->info['baseurl'])) { $this->info['baseurl'] = $value->getInfo(); return $this->save(); } foreach ($this->info['baseurl'] as $i => $baseurl) { if (strtolower($baseurl['attribs']['type']) == strtolower($protocol)) { $this->info['baseurl'][$i] = $value->getInfo(); return $this->save(); } } $this->info['baseurl'][] = $value->getInfo(); return $this->save(); } function offsetExists($protocol) { if (isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use [] to access ' . 'baseurl, use ->'); } foreach ($this->info['baseurl'] as $baseurl) { if (strtolower($baseurl['attribs']['type']) == strtolower($protocol)) { return true; } } return false; } function offsetUnset($protocol) { if (isset($this->index)) { throw new \pear2\Pyrus\ChannelFile\Exception('Cannot use [] to access ' . 'baseurl, use ->'); } foreach ($this->info['baseurl'] as $i => $baseurl) { if (strtolower($baseurl['attribs']['type']) == strtolower($protocol)) { unset($this->info['baseurl'][$i]); $this->info['baseurl'] = array_values($this->info['baseurl']); return $this->save(); } } } function getInfo() { return $this->info; } function save() { if ($this->parent instanceof self) { $this->parent[$this->info['attribs']['type']] = $this; return $this->parent->save(); } $info = $this->info; if (isset($info['baseurl']) && count($info['baseurl']) == 1) { $info['baseurl'] = $info['baseurl'][0]; } $this->parent->rawrest = $info; } } ?>_info = $info; $this->parent = $parent; } function __get($var) { switch($var){ case 'rest': case 'soap': case 'xmlrpc': $method = 'get' . $var; return $this->{$method}(); default: throw new \pear2\Pyrus\ChannelFile\Exception('Unknown protocol: ' . $var); } } function __set($var, $value) { switch($var){ case 'rest': case 'soap': case 'xmlrpc': $method = 'set' . $var; return $this->{$method}($value); default: throw new \pear2\Pyrus\ChannelFile\Exception('Unknown protocol: ' . $var); } } function setREST($value) { if ($value === null) { $this->parent->rest = null; return; } if (!($value instanceof Protocols\REST)) { throw new \pear2\Pyrus\ChannelFile\Exception('Can only set REST to ' . '\pear2\Pyrus\ChannelFile\v1\Servers\Protocols\REST object'); } $info = $value->getInfo(); if (!count($info)) { $this->parent->rest = null; } else { $this->parent->rest = $info; } } function getREST() { if (isset($this->_info['rest'])) { $info = $this->_info['rest']; } else { $info = array(); } return new Protocols\REST($info, $this->parent); } } ?> * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Class for a PEAR2 channel mirror * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelFile\v1; class Mirror extends \pear2\Pyrus\ChannelFile\v1 implements \pear2\Pyrus\Channel\IMirror { /** * Mapping of __get variables to method handlers * @var array */ protected $getMap = array( 'ssl' => 'getSSL', 'port' => 'getPort', 'server' => 'getChannel', 'alias' => 'getAlias', 'name' => 'getName', 'channel' => 'getChannel', 'mirror' => 'getServers', 'mirrors' => 'getServers', 'protocols' => 'getProtocols' ); private $_info; /** * Parent channel object * * @var \pear2\Pyrus\Channel */ protected $parentChannel; protected $parent; protected $index; function __construct($mirrorarray, $parent, $parentchannel, $index) { $this->_info = $mirrorarray; $this->parent = $parent; $this->parentChannel = $parentchannel; $this->index = $index; } function getChannel() { return $this->parentChannel->name; } /** * @return string|false */ function getName() { if (isset($this->_info['attribs']['host'])) { return $this->_info['attribs']['host']; } return false; } /** * @return int|80 port number to connect to */ function getPort() { if (isset($this->_info['attribs']['port'])) { return (int)$this->_info['attribs']['port']; } if ($this->getSSL()) { return 443; } return 80; } /** * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel */ function getSSL() { if (isset($this->_info['attribs']['ssl'])) { return true; } return false; } /** * Returns the protocols supported by the primary server for this channel * * @return \pear2\Pyrus\ChannelFile\v1\Servers\Protocols */ function getProtocols() { return new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols($this->_info, $this); } /** * Determines whether a channel supports Representational State Transfer (REST) protocols * for retrieving channel information * @return bool */ function supportsREST() { return isset($this->_info['rest']); } function setREST($rest) { if ($rest === null) { if (isset($this->_info['rest'])) { unset($this->_info['rest']); } return; } $this->_info['rest'] = $rest; $this->save(); } function setName($name) { if (empty($name)) { throw new \pear2\Pyrus\Channel\Exception('Mirror server must be non-empty'); } if (!$this->validChannelServer($name)) { throw new \pear2\Pyrus\Channel\Exception('Mirror server "' . $name . '" for channel "' . $this->getChannel() . '" is not a valid channel server'); } $this->_info['attribs']['host'] = $name; $this->save(); } function setPort($port) { $this->_info['attribs']['port'] = $port; $this->save(); } function setSSL($ssl = true) { if (!$ssl) { if (isset($this->_info['attribs']['ssl'])) { unset($this->_info['attribs']['ssl']); } } else { $this->_info['attribs']['ssl'] = 'yes'; } $this->save(); } /** * Empty all REST definitions */ function resetREST() { if (isset($this->_info['rest'])) { unset($this->_info['rest']); } $this->save(); } function getInfo() { return $this->_info; } function save() { $this->parent->setMirror($this->index, $this->_info); $this->parent->save(); } }info = $info; $this->parent = $parent; } function current() { $info = current($this->info['mirror']); return new \pear2\Pyrus\ChannelFile\v1\Mirror($info, $this, $this->parent, key($this->info['mirror'])); } function rewind() { if (!isset($this->info['mirror'])) { return; } reset($this->info['mirror']); } function key() { return key($this->info['mirror']); } function next() { return next($this->info['mirror']); } function valid() { if (!isset($this->info['mirror'])) { return false; } return current($this->info['mirror']); } function count() { if (!isset($this->info['mirror'])) { return 0; } return count($this->info['mirror']); } function offsetExists($mirror) { foreach ($this->info as $type=>$details) { if ($type == 'mirror' && isset($details[0]) && $details[0]['attribs']['host'] == $mirror) { return true; } } return false; } function offsetUnset($mirror) { if (!isset($this->info['mirror'])) { return; } foreach ($this->info['mirror'] as $i => $details) { if (isset($details['attribs']) && isset($details['attribs']['host']) && $details['attribs']['host'] == $mirror) { unset($this->info['mirror'][$i]); $this->info['mirror'] = array_values($this->info['mirror']); return $this->save(); } } } function offsetGet($mirror) { if (!isset($this->info['mirror'])) { return new \pear2\Pyrus\ChannelFile\v1\Mirror(array('attribs' => array('host' => $mirror)), $this, $this->parent, 0); } foreach ($this->info['mirror'] as $i => $details) { if (isset($details['attribs']) && isset($details['attribs']['host']) && $details['attribs']['host'] == $mirror) { return new \pear2\Pyrus\ChannelFile\v1\Mirror($details, $this, $this->parent, $i); } } return new \pear2\Pyrus\ChannelFile\v1\Mirror(array('attribs' => array('host' => $mirror)), $this, $this->parent, count($this->info['mirror'])); } function offsetSet($mirror, $value) { if ($value === null) { return $this->offsetUnset($mirror); } if (!($value instanceof \pear2\Pyrus\ChannelFile\v1\Mirror)) { throw new \pear2\Pyrus\ChannelFile\Exception('Can only set mirror to a ' . '\pear2\Pyrus\ChannelFile\v1\Mirror object'); } $info = $value->getInfo(); if ($mirror != $value->server) { $info['attribs']['host'] = $mirror; } foreach ($this->info['mirror'] as $i => $details) { if (isset($details['attribs']) && isset($details['attribs']['host']) && $details['attribs']['host'] == $mirror) { $this->setMirror($i, $info); return $this->save(); } } $this->setMirror(count($this->info['mirror']), $info); $this->save(); } function setMirror($index, $info) { $this->info['mirror'][$index] = $info; } function save() { $info = $this->info; if (!$info['mirror']) { return $this->parent->rawmirrors = null; } if (count($info['mirror']) === 1) { return $this->parent->rawmirrors = $info['mirror'][0]; } $this->parent->rawmirrors = $info['mirror']; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for a PEAR channel. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelFile; class v1 extends \pear2\Pyrus\ChannelFile implements \pear2\Pyrus\IChannelFile { /** * Supported channel.xml versions, for parsing * @var array */ protected $supportedVersions = array('1.0'); /** * Parsed channel information * @var array */ protected $channelInfo = array( 'attribs' => array( 'version' => '1.0', 'xmlns' => 'http://pear.php.net/channel-1.0', ), ); public $rootAttributes = array( 'version' => '1.0', 'xmlns' => 'http://pear.php.net/channel-1.0', 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', 'xsi:schemaLocation' => 'http://pear.php.net/channel-1.0 http://pear.php.net/dtd/channel-1.0.xsd' ); private $_xml; /** * Mapping of __get variables to method handlers * @var array */ protected $getMap = array( 'ssl' => 'getSSL', 'port' => 'getPort', 'suggestedalias' => 'getSuggestedAlias', 'alias' => 'getAlias', 'name' => 'getName', 'mirror' => 'getServers', 'mirrors' => 'getServers', 'protocols' => 'getProtocols' ); protected $setMap = array( 'name' => 'setName', 'ssl' => 'setSSL', 'summary' => 'setSummary', 'alias' => 'setAlias', 'localalias' => 'setLocalAlias', 'port' => 'setPort', 'rawrest' => 'setREST', 'rawmirrors' => 'setMirrors', ); function __construct(array $data = null) { if (null !== $data) { $this->fromArray($data); } } /** * Directly set the channel info. * * @param array $data The xml parsed data */ function fromArray($data) { if (isset($data['channel'])) { $this->channelInfo = $data['channel']; } else { $this->channelInfo = $data; } // Reset root attributes. $this->channelInfo['attribs'] = $this->rootAttributes; } /** * Validate the xml against the channel schema. * */ function validate() { if (!isset($this->_xml)) { $this->__toString(); } $a = new \pear2\Pyrus\XMLParser; $schema = \pear2\Pyrus\Main::getDataPath() . '/channel-1.0.xsd'; // for running out of svn if (!file_exists($schema)) { $schema = dirname(dirname(dirname(dirname(__FILE__)))) . '/data/channel-1.0.xsd'; } try { $a->parseString($this->_xml, $schema); return true; } catch (\Exception $e) { throw new \pear2\Pyrus\Channel\Exception('Invalid channel.xml', $e); } } /** * Returns the raw xml for the channel file. * * @return string */ function __toString() { return $this->_xml = (string) new \pear2\Pyrus\XMLWriter(array('channel'=>$this->channelInfo)); } /** * @return string|false */ protected function getName() { if (isset($this->channelInfo['name'])) { return $this->channelInfo['name']; } return false; } /** * @return int|80 port number to connect to */ protected function getPort() { if (isset($this->channelInfo['servers']['primary']['attribs']['port'])) { return (int)$this->channelInfo['servers']['primary']['attribs']['port']; } if ($this->getSSL()) { return 443; } return 80; } /** * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel */ protected function getSSL() { if (isset($this->channelInfo['servers']['primary']['attribs']['ssl'])) { return true; } return false; } function __get($var) { if (isset($this->getMap[$var])) { return $this->{$this->getMap[$var]}($var); } if ($var == 'remotepackages') { return new \pear2\Pyrus\Channel\Remotepackages($this); } elseif ($var == 'remotepackage') { return new \pear2\Pyrus\Channel\Remotepackage($this, false); } elseif ($var == 'remotecategories') { return new \pear2\Pyrus\Channel\Remotecategories($this); } if (!isset($this->channelInfo[$var])) { return null; } return $this->channelInfo[$var]; } /** * Returns the protocols supported by the primary server for this channel * * @return \pear2\Pyrus\ChannelFile\v1\Servers\Protocols */ protected function getProtocols() { if (isset($this->channelInfo['name']) && $this->channelInfo['name'] == '__uri') { throw new \pear2\Pyrus\Channel\Exception('__uri pseudo-channel has no protocols'); } if (!isset($this->channelInfo['servers']) || !isset($this->channelInfo['servers']['primary'])) { return new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols(array(), $this); } return new \pear2\Pyrus\ChannelFile\v1\Servers\Protocols($this->channelInfo['servers']['primary'], $this); } protected function getServers() { if ($this->channelInfo['name'] == '__uri') { throw new \pear2\Pyrus\Channel\Exception('__uri pseudo-channel cannot have mirrors'); } if (isset($this->channelInfo['servers'])) { $servers = $this->channelInfo['servers']; } else { $servers = array(); } return new \pear2\Pyrus\ChannelFile\v1\Servers($servers, $this); } /** * Determines whether a channel supports Representational State Transfer (REST) protocols * for retrieving channel information * * @return bool */ function supportsREST() { return isset($this->channelInfo['servers']['primary']['rest']); } function __set($var, $value) { if (isset($this->setMap[$var])) { return $this->{$this->setMap[$var]}($value); } if (method_exists($this, "set$var")) { $sv = "set$var"; $this->$sv($value); } } /** * Empty all REST definitions */ function resetREST() { if (isset($this->channelInfo['servers']['primary']['rest'])) { unset($this->channelInfo['servers']['primary']['rest']); } } /** * @param string * @return string|false * @error PEAR_CHANNELFILE_ERROR_NO_NAME * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME */ protected function setName($name) { if (empty($name)) { throw new \pear2\Pyrus\Channel\Exception('Primary server must be non-empty'); } if (!$this->validChannelServer($name)) { throw new \pear2\Pyrus\Channel\Exception('Primary server "' . $name . '" is not a valid channel server'); } $this->channelInfo['name'] = $name; } /** * Test whether a string contains a valid channel server. * @param string $ver the package version to test * @return bool */ static function validChannelServer($server) { if ($server == '__uri') { return true; } $regex = '/^[a-z0-9\-]+(?:\.[a-z0-9\-]+)*(\/[a-z0-9\-]+)*\\z/i'; return (bool) preg_match($regex, $server); } /** * Set the socket number (port) that is used to connect to this channel * @param integer */ protected function setPort($port) { if (isset($this->channelInfo['servers']) && isset($this->channelInfo['servers']['primary']) && !isset($this->channelInfo['servers']['primary']['attribs'])) { $this->channelInfo['servers']['primary'] = array_merge(array('attribs' => array('port' => $port)), $this->channelInfo['servers']['primary']); } else { $this->channelInfo['servers']['primary']['attribs']['port'] = $port; } } /** * Set the socket number (port) that is used to connect to this channel * @param bool Determines whether to turn on SSL support or turn it off */ protected function setSSL($ssl = true) { if ($ssl) { if (isset($this->channelInfo['servers']) && isset($this->channelInfo['servers']['primary']) && !isset($this->channelInfo['servers']['primary']['attribs'])) { $this->channelInfo['servers']['primary'] = array_merge(array('attribs' => array('ssl' => 'yes')), $this->channelInfo['servers']['primary']); } else { $this->channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; } } elseif (isset($this->channelInfo['servers']['primary']['attribs']['ssl'])) { unset($this->channelInfo['servers']['primary']['attribs']['ssl']); } } /** * @param string * @return boolean success * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY */ protected function setSummary($summary) { if (empty($summary)) { throw new \pear2\Pyrus\Channel\Exception('Channel summary cannot be empty'); } elseif (strpos(trim($summary), "\n") !== false) { throw new \pear2\Pyrus\Channel\Exception('Channel summary cannot be multi-line'); } $this->channelInfo['summary'] = $summary; return true; } protected function setLocalAlias($alias) { return $this->setAlias($alias, true); } /** * @param string * @param boolean determines whether the alias is in channel.xml or local * @return boolean success */ protected function setAlias($alias, $local = false) { if (!$this->validChannelServer($alias)) { throw new \pear2\Pyrus\Channel\Exception('Alias "' . $alias . '" is not a valid channel alias'); } $a = $local ? 'localalias' : 'suggestedalias'; $this->channelInfo[$a] = $alias; return true; } protected function getSuggestedAlias() { if (isset($this->channelInfo['suggestedalias'])) { return $this->channelInfo['suggestedalias']; } return ''; } /** * @return string */ protected function getAlias() { if (isset($this->channelInfo['localalias'])) { return $this->channelInfo['localalias']; } if (isset($this->channelInfo['suggestedalias'])) { return $this->channelInfo['suggestedalias']; } if (isset($this->channelInfo['name'])) { return $this->channelInfo['name']; } return ''; } /** * Set the package validation object if it differs from PEAR's default * The class must be includeable via changing _ in the classname to path separator, * but no checking of this is made. * @param string|false pass in false to reset to the default packagename regex * @return boolean success */ function setValidationPackage($validateclass, $version) { if (empty($validateclass)) { unset($this->channelInfo['validatepackage']); } $this->channelInfo['validatepackage'] = array('_content' => $validateclass); $this->channelInfo['validatepackage']['attribs'] = array('version' => $version); } protected function setREST($rest) { if ($rest === null) { $this->resetREST(); return; } $this->channelInfo['servers']['primary']['rest'] = $rest; } protected function setMirrors($mirrors) { if ($mirrors === null) { if (isset($this->channelInfo['servers']['mirror'])) { unset($this->channelInfo['servers']['mirror']); } return; } $this->channelInfo['servers']['mirror'] = $mirrors; } /** * Retrieve the name of the validation package for this channel * @return string|false */ function getValidationPackage() { if (!isset($this->channelInfo['validatepackage'])) { return array('attribs' => array('version' => 'default'), '_content' => 'PEAR_Validate'); } $info = $this->channelInfo['validatepackage']; if (!is_array($info)) { $info = array('attribs' => array('version' => 'default'), '_content' => $info); } return $info; } function getArray() { return $this->channelInfo; } /** * Retrieve the object that can be used for custom validation * @param string|false the name of the package to validate. If the package is * the channel validation package, PEAR_Validate is returned * @return \pear2\Pyrus\Validate|false false is returned if the validation package * cannot be located */ function getValidationObject($package = false) { if (isset($this->channelInfo['validatepackage'])) { if ($package == $this->channelInfo['validatepackage']['_content']) { // channel validation packages are always validated by \pear2\Pyrus\Validate $val = new \pear2\Pyrus\Validate; return $val; } $vclass = str_replace('.', '\\', $this->channelInfo['validatepackage']['_content']); $vclass = str_replace('PEAR_', 'pear2\Pyrus\\', $vclass); $vclass = str_replace('_', '\\', $vclass); if (!class_exists($vclass, true)) { throw new \pear2\Pyrus\ChannelFile\Exception( 'Validation object ' . $this->channelInfo['validatepackage']['_content'] . ' cannot be instantiated'); } $val = new $vclass; } else { $val = new \pear2\Pyrus\Validate; } return $val; } /** * This function is used by the channel updater and retrieves a value set by * the registry, or the current time if it has not been set * @return string */ function lastModified() { if (isset($this->channelInfo['_lastmodified'])) { return $this->channelInfo['_lastmodified']; } return time(); } function toChannelFile() { return $this; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a mirror within a Sqlite3 channel registry. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry\Mirror; class Sqlite3 extends \pear2\Pyrus\ChannelRegistry\Channel\Sqlite3 implements \pear2\Pyrus\Channel\IMirror { private $_channel; private $_parent; function __construct(SQLite3 $db, $mirror, \pear2\Pyrus\IChannel $parent) { if ($parent->name == '__uri') { throw new \pear2\Pyrus\ChannelRegistry\Exception('__uri channel cannot have mirrors'); } $this->_channel = $parent->name; parent::__construct($db, $this->_channel); $this->mirror = $mirror; $this->_parent = $parent; } function getChannel() { return $this->_channel; } function toChannelObject() { return $parent; } /** * @return string|false */ function getName() { return $this->mirror; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * A class for handling mirrors within an xml based channel registry. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry\Mirror; class Xml extends \pear2\Pyrus\Channel\Mirror { private $_parent; function __construct(&$mirrorarray, \pear2\Pyrus\IChannel $parent, \pear2\Pyrus\ChannelRegistry $reg) { parent::__construct($mirrorarray, $parent); $this->_parent = $reg; } public function toChannelObject() { $chan = new \pear2\Pyrus\Channel(new \pear2\Pyrus\ChannelFile((string) $this->parentChannel, true)); return $chan; } public function resetREST() { parent::resetREST(); $this->_parent->update($this->parentChannel); } public function setName($name) { parent::setName($name); $this->_parent->update($this->parentChannel); } public function setPort($port) { parent::setPort($port); $this->_parent->update($this->parentChannel); } public function setSSL($ssl = true) { parent::setSSL($ssl); $this->_parent->update($this->parentChannel); } public function setPath($protocol, $path) { parent::setPath($protocol, $path); $this->_parent->update($this->parentChannel); } public function addFunction($type, $version, $name) { parent::addFunction($type, $version, $name); $this->_parent->update($this->parentChannel); } public function setBaseUrl($resourceType, $url) { parent::setBaseURL($resourceType, $url); $this->_parent->update($this->parentChannel); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for Pyrus managed channel registries * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; abstract class Base implements \pear2\Pyrus\IChannelRegistry, \Iterator { protected $path; protected $readonly; protected $initialized; protected function lazyInit() { // lazy initialization if (!$this->initialized && 1 === $this->exists('pear.php.net')) { $this->initialized = true; $this->initDefaultChannels(); } else { $this->initialized = true; } } /** * Parse a package name, or validate a parsed package name array * @param string string of format * [channel://][channame/]pname[-version|-state][/group=groupname] * [http|https]://uri * * @return array */ public function parseName($param, $defaultchannel = 'pear2.php.net') { $saveparam = $param; $components = @parse_url((string) $param); if (isset($components['scheme'])) { if ($components['scheme'] == 'http' || $components['scheme'] == 'https') { // uri package $param = array('uri' => $param, 'channel' => '__uri'); return $param; } elseif($components['scheme'] != 'channel') { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parsePackageName(): only channel:// uris may ' . 'be downloaded, not "' . $param . '"', 'scheme'); } } if (!isset($components['path'])) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parsePackageName(): array $param ' . 'must contain a valid package name in "' . $param . '"', 'path'); } if (isset($components['host'])) { // remove the leading "/" $components['path'] = substr($components['path'], 1); } if (!isset($components['scheme'])) { if (strpos($components['path'], '/') !== false) { if ($components['path']{0} == '/') { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parsePackageName(): this is not ' . 'a package name, it begins with "/" in "' . $param . '"', 'invalid'); } $parts = explode('/', $components['path']); $components['host'] = array_shift($parts); if (count($parts) > 1) { $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } else { $components['path'] = implode('/', $parts); } } else { $components['host'] = $defaultchannel; } } else { if (strpos($components['path'], '/')) { $parts = explode('/', $components['path']); $components['path'] = array_pop($parts); $components['host'] .= '/' . implode('/', $parts); } } $param = array( 'package' => $components['path'] ); if (isset($components['host'])) { $param['channel'] = $components['host']; } if (isset($components['fragment'])) { $param['group'] = $components['fragment']; } if (isset($components['user'])) { $param['user'] = $components['user']; } if (isset($components['pass'])) { $param['pass'] = $components['pass']; } if (isset($components['query'])) { parse_str($components['query'], $param['opts']); } // check for extension $pathinfo = pathinfo($param['package']); if (isset($pathinfo['extension']) && in_array(strtolower($pathinfo['extension']), array('tgz', 'tar', 'zip', 'tbz', 'phar'))) { $param['extension'] = $pathinfo['extension']; $param['package'] = substr($pathinfo['basename'], 0, strlen($pathinfo['basename']) - strlen($pathinfo['extension']) - 1); } // check for version if (strpos($param['package'], '-')) { $test = explode('-', $param['package']); if (count($test) != 2) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parseName(): only one version/state ' . 'delimiter "-" is allowed in "' . $saveparam . '"', 'invalid'); } list($param['package'], $param['version']) = $test; } // validation $info = $this->exists($param['channel'], false); if (!$info) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('unknown channel "' . $param['channel'] . '" in "' . $saveparam . '"', 'channel', $param); } try { $chan = $this->get($param['channel'], false); } catch (\Exception $e) { throw new \pear2\Pyrus\ChannelRegistry\ParseException("Exception: corrupt registry, could not " . "retrieve channel " . $param['channel'] . " information", 'other', $e); } $param['channel'] = $chan->name; $validate = $chan->getValidationObject(false); $vpackage = $chan->getValidationPackage(); // validate package name if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parseName(): invalid package name "' . $param['package'] . '" in "' . $saveparam . '"', 'package'); } if (isset($param['group'])) { if (!\pear2\Pyrus\Validate::validGroupName($param['group'])) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parseName(): dependency group "' . $param['group'] . '" is not a valid group name in "' . $saveparam . '"', 'group'); } } if (isset($param['version'])) { // check whether version is actually a state if (in_array(strtolower($param['version']), $validate->getValidStates())) { $param['state'] = strtolower($param['version']); unset($param['version']); } else { if (!$validate->validVersion($param['version'])) { throw new \pear2\Pyrus\ChannelRegistry\ParseException('parseName(): "' . $param['version'] . '" is neither a valid version nor a valid state in "' . $saveparam . '"', 'version/state'); } } } return $param; } /** * @param array * @return string */ function parsedNameToString($parsed, $brief = false) { if (is_string($parsed)) { return $parsed; } if (is_object($parsed)) { $p = $parsed; if ($p->channel == '__uri') { $parsed = array( 'uri' => $p->uri, ); } else { $parsed = array( 'package' => $p->name, 'channel' => $p->channel, 'version' => $p->version['release'], ); } } if (isset($parsed['uri'])) { return $parsed['uri']; } if ($brief) { if ($channel = $this->get($parsed['channel'])->alias) { return $channel . '/' . $parsed['package']; } } $upass = ''; if (isset($parsed['user'])) { $upass = $parsed['user']; if (isset($parsed['pass'])) { $upass .= ':' . $parsed['pass']; } $upass = "$upass@"; } $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; if (isset($parsed['version']) || isset($parsed['state'])) { $ver = isset($parsed['version']) ? $parsed['version'] : ''; $ver .= isset($parsed['state']) ? $parsed['state'] : ''; $ret .= '-' . $ver; } if (isset($parsed['extension'])) { $ret .= '.' . $parsed['extension']; } if (isset($parsed['opts'])) { $ret .= '?'; foreach ($parsed['opts'] as $name => $value) { $parsed['opts'][$name] = urlencode($name) . '=' . urlencode($value); } $ret .= implode('&', $parsed['opts']); } if (isset($parsed['group'])) { $ret .= '#' . $parsed['group']; } return $ret; } function current() { return $this->get(current($this->channelList)); } function key() { return current($this->channelList); } function valid() { return current($this->channelList); } function next() { return next($this->channelList); } function rewind() { $this->channelList = $this->listChannels(); } public function getPearChannel() { return $this->getDefaultChannel('pear.php.net'); } public function getPear2Channel() { return $this->getDefaultChannel('pear2.php.net'); } public function getPeclChannel() { return $this->getDefaultChannel('pecl.php.net'); } public function getDocChannel() { return $this->getDefaultChannel('doc.php.net'); } public function getUriChannel() { return $this->getDefaultChannel('__uri'); } protected function getDefaultChannel($channel) { $xml = \pear2\Pyrus\Main::getDataPath() . '/default_channels/' . $channel . '.xml'; if (!file_exists($xml)) { $xml = dirname(dirname(dirname(__DIR__))).'/data/default_channels/' . $channel . '.xml'; } $parser = new \pear2\Pyrus\ChannelFile\Parser\v1; $info = $parser->parse($xml, true); return new \pear2\Pyrus\ChannelRegistry\Channel($this, $info->getArray()); } /** * Set up default channels, for uninitialized channel registries */ protected function initDefaultChannels() { $pear = $this->getPearChannel(); $pear2 = $this->getPear2Channel(); $pecl = $this->getPeclChannel(); $__uri = $this->getUriChannel(); $doc = $this->getDocChannel(); $this->add($pear); $this->add($pear2); $this->add($pecl); $this->add($doc); $this->add($__uri); } function exists($channel, $strict = true) { if (in_array($channel, $this->getDefaultChannels())) { return 1; } if (!$strict) { if (in_array($channel, $this->getDefaultChannelAliases())) { return 1; } } return false; } function channelFromAlias($alias) { $aliases = $this->getDefaultChannelAliases(); $channels = $this->getDefaultChannels(); if (in_array($alias, $aliases)) { $aliases = array_flip($aliases); return $channels[$aliases[$alias]]; } if (in_array($alias, $channels)) { return $alias; } throw new \pear2\Pyrus\ChannelFile\Exception('Unknown channel/alias: ' . $alias); } function getDefaultChannels() { return array('__uri', 'pear2.php.net', 'pear.php.net', 'pecl.php.net', 'doc.php.net'); } function getDefaultChannelAliases() { return array('__uri', 'pear2', 'pear', 'pecl', 'phpdocs'); } public function getPath() { return $this->path; } /** * @param string * @return int */ function packageCount($channel) { return count($this->getRegistry()->listPackages($channel)); } /** * @return \pear2\Pyrus\IRegistry */ function getRegistry() { $class = str_replace('Channel', '', get_class($this)); $ret = new $class($this->path, $this->readonly); return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ /** * A class that represents individual channels within a channel registry * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; class Channel extends \pear2\Pyrus\ChannelFile\v1 implements \pear2\Pyrus\IChannel { private $_parent; function __construct(\pear2\Pyrus\IChannelRegistry $parent, $data) { if (is_array($data) && !isset($data['channel']) && !isset($data['attribs'])) { $data = array_merge(array('attribs' => $this->rootAttributes), $data); } $this->_parent = $parent; parent::__construct($data); } function __get($var) { return parent::__get($var); } function __set($var, $value) { parent::__set($var, $value); $this->_parent->update($this); } function toChannelFile() { $ret = new \pear2\Pyrus\ChannelFile\v1; $ret->fromArray($this->getArray()); return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for Exceptions with a Pyrus channel registry. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; class Exception extends \pear2\Exception { } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for Exceptions when parsing channel registry. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; class ParseException extends \pear2\Exception { public $why; public $params; function __construct($message, $why, $params = array()) { $this->why = $why; $this->params = $params; parent::__construct($message); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/PEAR2/Pyrus */ /** * This is the central registry, that is used for all installer options, * stored in .reg files for PEAR 1 compatibility * * @category PEAR2 * @package PEAR2_Pyrus * @author Gregory Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/PEAR2/Pyrus */ namespace pear2\Pyrus\ChannelRegistry; class Pear1 extends \pear2\Pyrus\ChannelRegistry\Base { private $_channelPath; private $_aliasPath; function __construct($path, $readonly = false) { $this->readonly = $readonly; if (!file_exists($path . '/.registry') && basename($path) !== 'php') { $path = $path . DIRECTORY_SEPARATOR . 'php'; } $this->path = $path; if (isset(\pear2\Pyrus\Main::$options['packagingroot'])) { $path = \pear2\Pyrus\Main::prepend(\pear2\Pyrus\Main::$options['packagingroot'], $path); } $this->_channelPath = $path . DIRECTORY_SEPARATOR . '.channels'; $this->_aliasPath = $this->_channelPath . DIRECTORY_SEPARATOR . '.alias'; if (!file_exists($this->_channelPath) || !is_dir($this->_channelPath)) { if ($readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot initialize ' . 'PEAR1 channel registry, directory does not exist and registry is read-only'); } if (!@mkdir($this->_channelPath, 0755, true)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot initialize ' . 'PEAR1 channel registry, channel directory could not be initialized'); } } if (!file_exists($this->_aliasPath) || !is_dir($this->_aliasPath)) { if ($readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot initialize ' . 'PEAR1 channel registry, aliasdirectory does not exist and registry is read-only'); } if (!@mkdir($this->_aliasPath, 0755, true)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot initialize ' . 'PEAR1 channel registry, channel aliasdirectory could not be initialized'); } } if (1 === $this->exists('pear.php.net')) { $this->initialized = false; } else { $this->initialized = true; } } protected function channelFileName($channel) { return $this->_channelPath . DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($channel)) . '.reg'; } protected function channelAliasFileName($alias) { return $this->_channelPath . DIRECTORY_SEPARATOR . '.alias' . DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; } public function channelFromAlias($alias) { if (!$this->initialized) { return parent::channelFromAlias($alias); } $file = $this->channelAliasFileName($alias); if (file_exists($file)) { return file_get_contents($file); } return $alias; } public function add(\pear2\Pyrus\IChannel $channel, $update = false, $lastmodified = false) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add channel, registry is read-only'); } if (!is_writable($this->_channelPath)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add channel ' . $channel->name . ', channel registry path is not writable'); } $this->lazyInit(); $channel->validate(); $exists = $this->exists($channel->name); if ($exists && 1 !== $exists) { if (!$update) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add channel ' . $channel->name . ', channel already exists, use update to change'); } $checker = $this->get($channel->name); if ($channel->alias != $checker->alias) { if (file_exists($this->channelAliasFileName($checker->alias))) { @unlink($this->channelAliasFileName($checker->alias)); } } } elseif ($update) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: channel ' . $channel->name . ' is unknown'); } if ($channel->alias != $channel->name) { if (file_exists($this->channelAliasFileName($channel->alias)) && $this->channelFromAlias($channel->alias) != $channel->name) { $channel->alias = $channel->name; } $fp = @fopen($this->channelAliasFileName($channel->alias), 'w'); if (!$fp) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add/update channel ' . $channel->name . ', unable to open PEAR1 channel alias file'); } fwrite($fp, $channel->name); fclose($fp); } $fp = @fopen($this->channelFileName($channel->name), 'wb'); if (!$fp) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add/update channel ' . $channel->name . ', unable to open PEAR1 channel registry file'); } $info = (string) $channel; $parser = new \pear2\Pyrus\XMLParser; $info = $parser->parseString($info); $info = $info['channel']; if ($lastmodified) { $info['_lastmodified'] = $lastmodified; } else { $info['_lastmodified'] = date('r'); } fwrite($fp, serialize($info)); fclose($fp); return true; } public function update(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot update channel, registry is read-only'); } return $this->add($channel, true); } public function delete(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel, registry is read-only'); } $name = $channel->name; if (in_array($name, $this->getDefaultChannels())) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete default channel ' . $channel->name); } if (!$this->exists($name)) { return true; } $this->lazyInit(); if ($this->packageCount($name)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel ' . $name . ', packages are installed'); } @unlink($this->channelFileName($name)); @unlink($this->channelAliasFileName($channel->alias)); } public function get($channel, $strict = true) { $exists = $this->exists($channel, $strict); if (!$exists) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Channel ' . $channel . ' does not exist'); } if (1 === $exists) { // is a default channel not installed return $this->getDefaultChannel($channel); } $channel = $this->channelFromAlias($channel); $cont = file_get_contents($this->channelFileName($channel)); $a = @unserialize($cont); if (!$a || !is_array($a)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Channel ' . $channel . ' PEAR1 registry file is corrupt'); } try { $chan = new \pear2\Pyrus\ChannelRegistry\Channel($this, $a); if ($channel != '__uri') { $chan->validate(); } return $chan; } catch (\Exception $e) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Channel ' . $channel . ' PEAR1 registry file is invalid channel information', $e); } } public function exists($channel, $strict = true) { if (!$strict) { $channel = $this->channelFromAlias($channel); } $chan = $this->channelFileName($channel); if (file_exists($chan)) { return true; } return parent::exists($channel, $strict); } function listChannels() { if (!$this->initialized) { return $this->getDefaultChannels(); } $ret = array(); foreach (new \RegexIterator(new \DirectoryIterator($this->_channelPath), '/^(.+?)\.reg/', \RegexIterator::GET_MATCH) as $file) { if ($file[1] == '__uri') { $ret[] = '__uri'; } else { $ret[] = $this->get(str_replace('_', '/', $file[1]))->name; } } return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * An implementation of a Pyrus channel registry using Sqlite3 as the storage * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; class Sqlite3 extends \pear2\Pyrus\ChannelRegistry\Base { /** * The database resource * * @var SQLite3 */ static protected $databases = array(); /** * Initialize the registry * * @param unknown_type $path */ function __construct($path, $readonly = false) { $this->readonly = $readonly; $this->path = $path; if ($path && $path != ':memory:') { if (dirname($path . '.pear2registry') != $path) { $path = $path . DIRECTORY_SEPARATOR . '.pear2registry'; } else { $this->path = dirname($path); } } if ($path != ':memory:') { if (file_exists($path)) { $this->_init($path, $readonly); } else { $file = $path; while ($file && $file !== '.' && $file !== '/' && !is_writable($file)) { $file = dirname($file); } if (!$file || $file == '.') { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot create SQLite3 channel registry, registry is read-only'); } } } } protected function lazyInit() { // lazy initialization if (!$this->initialized) { $this->_init($this->path . '/.pear2registry', $this->readonly); } return parent::lazyInit(); } private function _init($path, $readonly) { if (isset(static::$databases[$this->path]) && static::$databases[$this->path]) { $this->initialized = true; return; } $dbpath = $path; if ($path != ':memory:' && isset(\pear2\Pyrus\Main::$options['packagingroot'])) { $dbpath = \pear2\Pyrus\Main::prepend(\pear2\Pyrus\Main::$options['packagingroot'], $path); } if (!$path) { $path = ':memory:'; } elseif ($path != ':memory:' && !file_exists(dirname($dbpath))) { if ($readonly) { throw new \pear2\Pyrus\Registry\Exception('Cannot create SQLite3 channel registry, registry is read-only'); } @mkdir(dirname($dbpath), 0755, true); } if ($readonly && $path != ':memory:' && !file_exists(dirname($dbpath))) { throw new \pear2\Pyrus\Registry\Exception('Cannot create SQLite3 channel registry, registry is read-only'); } static::$databases[$this->path] = new \SQLite3($dbpath); // hopefully this works if (static::$databases[$this->path]->lastErrorCode()) { $temp = static::$databases[$this->path]; unset(static::$databases[$this->path]); throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot open SQLite3 channel registry: ' . $temp->lastErrorMsg()); } $this->initialized = true; $sql = 'SELECT version FROM pearregistryversion'; if (@static::$databases[$this->path]->querySingle($sql) == '1.0.0') { $sql = 'SELECT COUNT(*) FROM channels'; if (!static::$databases[$this->path]->querySingle($sql)) { if ($readonly) { throw new \pear2\Pyrus\Registry\Exception('Cannot create SQLite3 channel registry, registry is read-only'); } $this->initDefaultChannels(); return; } return; } if ($readonly) { throw new \pear2\Pyrus\Registry\Exception('Cannot create SQLite3 channel registry, registry is read-only'); } $a = new \pear2\Pyrus\Registry\Sqlite3\Creator; $a->create(static::$databases[$this->path]); $this->initDefaultChannels(); } function exists($channel, $strict = true) { if (!$this->initialized) { return parent::exists($channel, $strict); } $sql = 'SELECT channel FROM channels WHERE alias = "' . static::$databases[$this->path]->escapeString($channel) . '"'; if (!$strict && $a = static::$databases[$this->path]->querySingle($sql)) { return true; } $sql = 'SELECT channel FROM channels WHERE channel = "' . static::$databases[$this->path]->escapeString($channel) . '"'; if ($a = static::$databases[$this->path]->querySingle($sql)) { return true; } return parent::exists($channel, $strict); } function add(\pear2\Pyrus\IChannel $channel, $update = false, $lastmodified = false) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add channel, registry is read-only'); } $this->lazyInit(); $sql = 'SELECT channel FROM channels WHERE channel = "' . static::$databases[$this->path]->escapeString($channel->name) . '"'; if (static::$databases[$this->path]->querySingle($sql)) { if (!$update) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: channel ' . $channel->name . ' has already been discovered'); } static::$databases[$this->path]->exec('BEGIN'); static::$databases[$this->path]->exec('DELETE FROM channel_servers WHERE channel = "' . static::$databases[$this->path]->escapeString($channel->name) . '"; DELETE FROM channel_server_rest WHERE channel = "' . static::$databases[$this->path]->escapeString($channel->name) . '"'); } elseif ($update) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: channel ' . $channel->name . ' is unknown'); } else { static::$databases[$this->path]->exec('BEGIN'); } static::$databases[$this->path]->enableExceptions(true); try { $this->_add($channel, $lastmodified, $update); } catch (\Exception $e) { static::$databases[$this->path]->enableExceptions(false); @static::$databases[$this->path]->exec('ROLLBACK'); throw new \pear2\Pyrus\Registry\Exception('Error: channel ' . $channel->name . ' could not be added to the SQLite3 registry', $e); } static::$databases[$this->path]->enableExceptions(false); } private function _add($channel, $lastmodified, $update) { $validate = $channel->getValidationPackage(); if ($update) { $sql = ' UPDATE channels set summary=:summary, suggestedalias=:suggestedalias, alias=:alias, validatepackageversion=:version, validatepackage=:package, lastmodified=:lastmodified WHERE channel=:name'; } else { $sql = ' INSERT INTO channels (channel, summary, suggestedalias, alias, validatepackageversion, validatepackage, lastmodified) VALUES( :name, :summary, :suggestedalias, :alias, :version, :package, :lastmodified )'; } $stmt = static::$databases[$this->path]->prepare($sql); $stmt->bindValue(':name', $cn = $channel->name); $stmt->bindValue(':summary', $channel->summary); $stmt->bindValue(':suggestedalias', $channel->suggestedalias); $stmt->bindValue(':alias', $channel->alias); $stmt->bindValue(':version', $validate['attribs']['version']); $stmt->bindValue(':package', $validate['_content']); $stmt->bindValue(':lastmodified', $channel->lastModified()); $stmt->execute(); $stmt->close(); $sql = ' INSERT INTO channel_servers (channel, server, ssl, port) VALUES( :channel, :server, :ssl, :port )'; $stmt = static::$databases[$this->path]->prepare($sql); $stmt->bindValue(':channel', $cn); $stmt->bindValue(':server', $cn); $stmt->bindValue(':ssl', $channel->ssl, SQLITE3_INTEGER); $stmt->bindValue(':port', $channel->port, SQLITE3_INTEGER); $stmt->execute(); $stmt->close(); if ($channel->name == '__uri') { // __uri pseudo-channel has no protocols or mirrors static::$databases[$this->path]->exec('COMMIT'); return; } foreach ($channel->protocols->rest as $type => $baseurl) { $sql = ' INSERT INTO channel_server_rest (channel, server, baseurl, type) VALUES( :channel, :server, :func, :attrib )'; $stmt = static::$databases[$this->path]->prepare($sql); $stmt->bindValue(':channel', $cn); $stmt->bindValue(':server', $cn); $stmt->bindValue(':func', $baseurl); $stmt->bindValue(':attrib', $type); $stmt->execute(); } $sql = ' INSERT INTO channel_servers (channel, server, ssl, port) VALUES( :channel, :server, :ssl, :port )'; $stmt = static::$databases[$this->path]->prepare($sql); foreach ($channel->mirrors as $mirror) { $ssl = 0; if ($mirror->ssl) { $ssl = 1; } $stmt->bindValue(':channel', $cn); $stmt->bindValue(':server', $mn = $mirror->name); $stmt->bindValue(':ssl', $ssl, SQLITE3_INTEGER); $stmt->bindValue(':port', $mirror->port, SQLITE3_INTEGER); $stmt->execute(); $sql = ' INSERT INTO channel_server_rest (channel, server, baseurl, type) VALUES( :channel, :server, :func, :attrib )'; $stmt1 = static::$databases[$this->path]->prepare($sql); foreach ($mirror->protocols->rest as $type => $baseurl) { $stmt1->bindValue(':channel', $cn); $stmt1->bindValue(':server', $mn); $stmt1->bindValue(':func', $baseurl); $stmt1->bindValue(':attrib', $type); $stmt1->execute(); } } static::$databases[$this->path]->exec('COMMIT'); } function update(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot update channel, registry is read-only'); } return $this->add($channel, true); } function get($channel, $strict = true) { $exists = $this->exists($channel, $strict); if (!$exists) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Unknown channel: ' . $channel); } $chan = $this->getChannelObject($this->channelFromAlias($channel)); return new \pear2\Pyrus\ChannelRegistry\Channel($this, $chan->getArray()); } function channelFromAlias($alias) { if (!$this->initialized) { return parent::channelFromAlias($alias); } $sql = 'SELECT channel FROM channels WHERE alias = "' . static::$databases[$this->path]->escapeString($alias) . '"'; if ($chan = static::$databases[$this->path]->querySingle($sql)) { return $chan; } $sql = 'SELECT channel FROM channels WHERE channel = "' . static::$databases[$this->path]->escapeString($alias) . '"'; if ($chan = static::$databases[$this->path]->querySingle($sql)) { return $chan; } throw new \pear2\Pyrus\ChannelFile\Exception('Unknown channel/alias: ' . $alias); } /** * @param string */ protected function getChannelObject($channel) { $channel = $this->channelFromAlias($channel); if (!$this->initialized) { if (in_array($channel, $this->getDefaultChannels())) { return $this->getDefaultChannel($channel); } throw new \pear2\Pyrus\ChannelFile\Exception('Unknown channel ' . $channel); } $sql = 'SELECT * FROM channels WHERE channel = "' . static::$databases[$this->path]->escapeString($channel) . '"'; $result = static::$databases[$this->path]->query($sql); if (!$result) { throw new \pear2\Pyrus\ChannelFile\Exception('Failed to query channels table'); } while ($res = $result->fetchArray(SQLITE3_ASSOC)) { break; } $ret = new \pear2\Pyrus\ChannelFile\v1; $ret->name = $channel; $ret->suggestedalias = $res['suggestedalias']; if ($res['alias']) { $ret->alias = $res['alias']; } $ret->summary = $res['summary']; $ret->setValidationPackage($res['validatepackage'], $res['validatepackageversion']); $ret->lastModified = $res['lastmodified']; $sql = 'SELECT channel, server, ssl, port FROM channel_servers WHERE channel = "' . static::$databases[$this->path]->escapeString($channel) . '"'; $result = static::$databases[$this->path]->query($sql); if (!$result) { throw new \pear2\Pyrus\ChannelFile\Exception('Failed to query mirrors table'); } while ($res = $result->fetchArray(SQLITE3_ASSOC)) { if ($res['server'] == $res['channel']) { $ret->port = $res['port']; $ret->ssl = $res['ssl']; } else { $ret->mirrors[$res['server']]->ssl = $res['ssl']; $ret->mirrors[$res['server']]->port = $res['port']; } } $sql = 'SELECT channel, server, baseurl, type FROM channel_server_rest WHERE channel= "' . static::$databases[$this->path]->escapeString($channel) . '"'; $result = static::$databases[$this->path]->query($sql); if (!$result) { throw new \pear2\Pyrus\ChannelFile\Exception('Failed to query rest table'); } while ($res = $result->fetchArray(SQLITE3_ASSOC)) { if ($res['server'] == $res['channel']) { $ret->protocols->rest[$res['type']]->baseurl = $res['baseurl']; } else { $ret->mirrors[$res['server']]->protocols->rest[$res['type']]->baseurl = $res['baseurl']; } } return $ret; } function delete(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel, registry is read-only'); } $name = $channel->name; if (in_array($name, $this->getDefaultChannels())) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete default channel ' . $channel->name); } $this->lazyInit(); if (!isset(static::$databases[$this->path])) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: no existing SQLite3 channel registry for ' . $this->path); } $sql = 'SELECT count(*) FROM packages WHERE channel = "' . static::$databases[$this->path]->escapeString($channel->name) . '"'; if (static::$databases[$this->path]->querySingle($sql)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel ' . $channel->name . ', packages are installed'); } $sql = 'DELETE FROM channels WHERE channel = "' . static::$databases[$this->path]->escapeString($channel->name) . '"'; static::$databases[$this->path]->enableExceptions(true); try { static::$databases[$this->path]->exec($sql); } catch (\Exception $e) { static::$databases[$this->path]->enableExceptions(false); throw new \pear2\Pyrus\Registry\Exception('Error: Deleting channel ' . $channel->name . ' failed: ' . $e->getMessage(), $e); } static::$databases[$this->path]->enableExceptions(false); } public function listChannels() { if (!$this->initialized) { return $this->getDefaultChannels(); } if (!isset(static::$databases[$this->path])) { throw new \pear2\Pyrus\ChannelRegistry\Exception( 'Error: no existing SQLite3 channel registry for ' . $this->path); } $ret = array(); $sql = 'SELECT channel FROM channels ORDER BY channel'; $res = static::$databases[$this->path]->query($sql); while ($chan = $res->fetchArray(SQLITE3_ASSOC)) { $ret[] = $chan['channel']; } return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * An implementation of a Pyrus channel registry within XML files. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\ChannelRegistry; class Xml extends \pear2\Pyrus\ChannelRegistry\Base { protected $channelpath; /** * Initialize the registry * * @param string $path */ function __construct($path, $readonly = false) { $this->readonly = $readonly; if (isset(\pear2\Pyrus\Main::$options['packagingroot'])) { $path = \pear2\Pyrus\Main::prepend(\pear2\Pyrus\Main::$options['packagingroot'], $path); } $this->path = $path; $this->channelpath = $path . DIRECTORY_SEPARATOR . '.xmlregistry' . DIRECTORY_SEPARATOR . 'channels'; if (1 === $this->exists('pear.php.net')) { $this->initialized = false; } else { $this->initialized = true; } } /** * Convert a name into a path-friendly name * * @param string $name */ private function _mung($name) { return str_replace(array('/', '\\'), array('##', '###'), $name); } private function _unmung($name) { return str_replace(array('##', '###'), array('/', '\\'), $name); } /** * Get the filename to store a channel * * @param \pear2\Pyrus\IChannel|string $channel Channel to save * * @return string */ protected function getChannelFile($channel) { if ($channel instanceof \pear2\Pyrus\IChannel) { $channel = $channel->name; } return $this->channelpath . DIRECTORY_SEPARATOR . 'channel-' . $this->_mung($channel) . '.xml'; } /** * Get the filename for a channel alias. * * @param string $alias Alias to save * * @return string */ protected function getAliasFile($alias) { return $this->channelpath . DIRECTORY_SEPARATOR . 'channelalias-' . $this->_mung($alias) . '.txt'; } function channelFromAlias($alias) { if (!$this->initialized) { return parent::channelFromAlias($alias); } if (file_exists($this->getAliasFile($alias))) { return file_get_contents($this->getAliasFile($alias)); } if (file_exists($this->getChannelFile($alias))) { return $alias; } throw new \pear2\Pyrus\ChannelRegistry\Exception('Unknown channel/alias: ' . $alias); } /** * Check if the channel has been discovered. * * @param string $channel Name of the channel * @param bool $strict Allow aliases or not * * @return bool */ function exists($channel, $strict = true) { if (file_exists($this->getChannelFile($channel))) { return true; } if ($strict) { return parent::exists($channel, $strict); } if (file_exists($this->getAliasFile($channel))) { return true; } return parent::exists($channel, $strict); } function add(\pear2\Pyrus\IChannel $channel, $update = false, $lastmodified = false) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot add channel, registry is read-only'); } $this->lazyInit(); $file = $this->getChannelFile($channel); if (@file_exists($file)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: channel ' . $channel->name . ' has already been discovered'); } if (!@is_dir(dirname($file))) { mkdir(dirname($file), 0755, true); } file_put_contents($file, (string) $channel); $alias = $channel->alias; file_put_contents($this->getAliasFile($alias), $channel->name); } function update(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot update channel, registry is read-only'); } $this->lazyInit(); $file = $this->getChannelFile($channel); if (!@file_exists($file)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Error: channel ' . $channel->name . ' is unknown'); } file_put_contents($file, (string) $channel); $alias = $channel->alias; file_put_contents($this->getAliasFile($alias), $channel->name); } function delete(\pear2\Pyrus\IChannel $channel) { if ($this->readonly) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel, registry is read-only'); } $name = $channel->name; if (in_array($name, $this->getDefaultChannels())) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete default channel ' . $channel->name); } $this->lazyInit(); if (!$this->exists($name)) { return true; } if ($this->packageCount($name)) { throw new \pear2\Pyrus\ChannelRegistry\Exception('Cannot delete channel ' . $name . ', packages are installed'); } @unlink($this->getChannelFile($channel)); @unlink($this->getAliasFile($channel->alias)); } function get($channel, $strict = true) { $exists = $this->exists($channel, $strict); if ($exists) { $channel = $this->channelFromAlias($channel); if (1 === $exists) { return $this->getDefaultChannel($channel); } else { $chan = new \pear2\Pyrus\ChannelFile($this->getChannelFile($channel)); } return new \pear2\Pyrus\ChannelRegistry\Channel($this, $chan->getArray()); } throw new \pear2\Pyrus\ChannelRegistry\Exception('Unknown channel: ' . $channel); } /** * List all discovered channels * * @return array */ function listChannels() { if (!$this->initialized) { return $this->getDefaultChannels(); } $ret = array(); foreach (new \RegexIterator(new \DirectoryIterator($this->channelpath), '/channel-(.+?)\.xml/', \RegexIterator::GET_MATCH) as $file) { $ret[] = $this->get($this->_unmung($file[1]))->name; } return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Pyrus configuration * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Config; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Pyrus's master configuration manager * * Unlike PEAR version 1.x, the new Pyrus configuration manager is tightly bound * to include_path, and will search through include_path for system configuration * Pyrus installations. * * The User configuration file will be looked for in these locations: * * Unix: * * - home directory * - current directory * * Windows: * * - local settings directory on windows for the current user. * This is looked up directly in the windows registry using COM * - current directory * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Config; class Snapshot extends \pear2\Pyrus\Config { /** * parse a configuration for a PEAR2 installation * * @param string $pearDirectory This can be either a single path, or a * PATH_SEPARATOR-separated list of directories * @param string $userfile */ public function __construct($snapshot, \pear2\Pyrus\Config $config = null) { self::constructDefaults(); if (!$config) { $config = \pear2\Pyrus\Config::current(); } $this->loadConfigFile($config->location, $snapshot); $this->pearDir = $config->location; } /** * Extract configuration from system + user configuration files * * Configuration is stored in XML format, in two locations. * * The system configuration contains all of the important directory * configuration variables like data_dir, and the location of php.ini and * the php executable php.exe or php. This configuration is tightly bound * to the repository, and cannot be moved. As such, php_dir is auto-defined * as dirname(/path/to/pear/.config), or /path/to/pear. * * Only 1 user configuration file is allowed, and contains user-specific * settings, including the locations where to download package releases * and where to cache files downloaded from the internet. If false is passed * in, \pear2\Pyrus\Config will attempt to guess at the config file location as * documented in the class docblock {@link \pear2\Pyrus\Config}. * @param string $pearDirectory * @param string|false $userfile */ protected function loadConfigFile($pearDirectory, $snapshot = null) { if (!file_exists($pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots')) { // no configurations - this may be an extracted-from-disk install. // in this case, we use the defaults, as this is intended return; } $snapshotdir = $pearDirectory . DIRECTORY_SEPARATOR . '.configsnapshots'; $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . $snapshot; if (!file_exists($snapshotfile)) { if (preg_match('/^\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}[-:]\\d{2}[-:]\\d{2}$/', $snapshot)) { // passed a date, locate a matching snapshot if (!strpos($snapshot, ':')) { // change YYYY-MM-DD HH-MM-SS to YYYY-MM-DD HH:MM:SS $snapshot = explode(' ', $snapshot); $snapshot[1] = str_replace('-', ':', $snapshot[1]); $snapshot = implode(' ', $snapshot); } $us = new \DateTime($snapshot); $dir = new \RegexIterator( new \RecursiveDirectoryIterator($snapshotdir), '/configsnapshot\\-\\d{4}\\-\\d{2}\\-\\d{2} \\d{2}\\-\\d{2}\\-\\d{2}.xml/', \RegexIterator::MATCH, \RegexIterator::USE_KEY); foreach ($dir as $match) { $matches[] = $match; } usort($matches, array($this, 'datediff')); unset($match); $found = false; foreach ($matches as $match) { $match = substr($match->getFileName(), strlen('configsnapshot-')); $match = str_replace('.xml', '', $match); $match = explode(' ', $match); $match[1] = str_replace('-', ':', $match[1]); $match = implode(' ', $match); $testdate = new \DateTime($match); if ($testdate > $us) { continue; } if ($testdate == $us) { // found a snapshot match $found = true; break; } if ($us > $testdate) { // we fall between these two snapshots, so use this one $found = true; break; } } if (!$found) { // no config snapshots return parent::loadConfigFile($pearDirectory); } $snapshotfile = $snapshotdir . DIRECTORY_SEPARATOR . 'configsnapshot-' . str_replace(':', '-', $match) . '.xml'; } } \pear2\Pyrus\Logger::log(5, 'Loading configuration snapshot ' . $snapshotfile . ' for ' . $pearDirectory); try { $this->helperLoadConfigFile($pearDirectory, $snapshotfile, 'snapshot'); } catch (\Exception $e) { // no config snapshots found, so simply load the existing config return parent::loadConfigFile($pearDirectory); } } function datediff($a, $b) { $a = str_replace(array('configsnapshot-', '.xml'), '', $a->getFileName()); $inf = explode(' ', $a); $a = str_replace($inf[1], str_replace('-', ':', $inf[1]), $a); $b = str_replace(array('configsnapshot-', '.xml'), '', $b->getFileName()); $inf = explode(' ', $b); $b = str_replace(' ' . $inf[1], ' ' . str_replace('-', ':', $inf[1]), $b); $us = new \DateTime($a); $diff = $us->diff(new \DateTime($b))->format("%r%s"); if (!$diff) return 0; if ($diff > 0) return 1; return -1; } /** * Save both the user configuration file and the system file * * If the userfile is not passed in, it is saved in the default * location which is either in ~/.pear/pearconfig.xml or on Windows * in the Documents and Settings directory * @param string $userfile path to alternate user configuration file */ function saveConfig($userfile = false) { } /** * Save a snapshot of the current config, and return the file name * * If the latest snapshot is the same as the existing configuration, * simply return the filename * @return string basename of the snapshot file of the current configuration */ static public function configSnapshot() { } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception for dependencies * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Dependency; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Dependency check for PEAR2 packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Dependency; class Validator { /** * @var \pear2\MultiErrors */ protected $errs; /** * One of the \pear2\Pyrus\Validate::* states * @see \pear2\Pyrus\Validate::NORMAL * @var integer */ var $_state; /** * @var \pear2\Pyrus\OSGuess */ var $_os; /** * Package to validate * @var \pear2\Pyrus\Package */ var $_currentPackage; /** * @param \pear2\Pyrus\Package * @param int installation state (one of \pear2\Pyrus\Validate::*) * @param \pear2\MultiErrors */ function __construct($package, $state = \pear2\Pyrus\Validate::INSTALLING, \pear2\MultiErrors $errs) { $this->_state = $state; $this->_currentPackage = $package; $this->errs = $errs; } function _getExtraString($dep) { $extra = ' ('; if ($dep->type != 'extension' && isset($dep->uri)) { return ''; } if (isset($dep->recommended)) { $extra .= 'recommended version ' . $dep->recommended; } else { if (isset($dep->min)) { $extra .= 'version >= ' . $dep->min; } if (isset($dep->max)) { if ($extra != ' (') { $extra .= ', '; } $extra .= 'version <= ' . $dep->max; } if (isset($dep->exclude)) { if (!is_array($dep->exclude)) { $dep->exclude = array($dep->exclude); } if ($extra != ' (') { $extra .= ', '; } $extra .= 'excluded versions: '; foreach ($dep->exclude as $i => $exclude) { if ($i) { $extra .= ', '; } $extra .= $exclude; } } } $extra .= ')'; if ($extra == ' ()') { $extra = ''; } return $extra; } /** * This makes unit-testing a heck of a lot easier */ function getPHP_OS() { return PHP_OS; } /** * This makes unit-testing a heck of a lot easier */ function getsysname() { $this->_os = new \pear2\Pyrus\OSGuess; return $this->_os->getSysname(); } /** * Specify a dependency on an OS. Use arch for detailed os/processor information * * There are two generic OS dependencies that will be the most common, unix and windows. * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix */ function validateOsDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Dep $dep) { if ($this->_state != \pear2\Pyrus\Validate::INSTALLING && $this->_state != \pear2\Pyrus\Validate::DOWNLOADING) { return true; } if ($dep->name == '*') { return true; // no one will do conflicts with *, so assume no conflicts } switch (strtolower($dep->name)) { case 'windows' : if ($dep->conflicts) { if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError("Cannot install %s on Windows"); } else { return $this->warning("warning: Cannot install %s on Windows"); } } } else { if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError("Can only install %s on Windows"); } else { return $this->warning("warning: Can only install %s on Windows"); } } } break; case 'unix' : $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); if ($dep->conflicts) { if (in_array(strtolower($this->getSysname()), $unices)) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError("Cannot install %s on any Unix system"); } else { return $this->warning( "warning: Cannot install %s on any Unix system"); } } } else { if (!in_array(strtolower($this->getSysname()), $unices)) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError("Can only install %s on a Unix system"); } else { return $this->warning( "warning: Can only install %s on a Unix system"); } } } break; default : if ($dep->conflicts) { if (strtolower($dep->name) == strtolower($this->getSysname())) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('Cannot install %s on ' . $dep->name . ' operating system'); } else { return $this->warning('warning: Cannot install %s on ' . $dep->name . ' operating system'); } } } else { if (strtolower($dep->name) != strtolower($this->getSysname())) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('Cannot install %s on ' . $this->getSysname() . ' operating system, can only install on ' . $dep->name); } else { return $this->warning('warning: Cannot install %s on ' . $this->getSysname() . ' operating system, can only install on ' . $dep->name); } } } } return true; } /** * This makes unit-testing a heck of a lot easier */ function matchSignature($pattern) { $this->_os = new \pear2\Pyrus\OSGuess; return $this->_os->matchSignature($pattern); } /** * Specify a complex dependency on an OS/processor/kernel version, * Use OS for simple operating system dependency. * * This is the only dependency that accepts an eregable pattern. The pattern * will be matched against the php_uname() output parsed by OS_Guess */ function validateArchDependency($dep) { if ($this->_state != \pear2\Pyrus\Validate::INSTALLING) { return true; } if ($this->matchSignature($dep->pattern)) { if ($dep->conflicts) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s Architecture dependency failed, cannot match "' . $dep->pattern . '"'); } return $this->warning('warning: %s Architecture dependency failed, ' . 'cannot match "' . $dep->pattern . '"'); } return true; } else { if ($dep->conflicts) { return true; } if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s Architecture dependency failed, does not ' . 'match "' . $dep->pattern . '"'); } return $this->warning('warning: %s Architecture dependency failed, does ' . 'not match "' . $dep->pattern . '"'); } } /** * This makes unit-testing a heck of a lot easier */ function extension_loaded($name) { return extension_loaded($name); } /** * This makes unit-testing a heck of a lot easier */ function phpversion($name = null) { if ($name !== null) { return phpversion($name); } else { return phpversion(); } } function validateExtensionDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $dep) { if ($this->_state != \pear2\Pyrus\Validate::INSTALLING && $this->_state != \pear2\Pyrus\Validate::DOWNLOADING) { return true; } $required = $dep->deptype == 'required'; $loaded = $this->extension_loaded($dep->name); $extra = $this->_getExtraString($dep); if (!isset($dep->min) && !isset($dep->max) && !isset($dep->recommended) && !isset($dep->exclude)) { if ($loaded) { if ($dep->conflicts) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s conflicts with PHP extension "' . $dep->name . '"' . $extra); } else { return $this->warning('warning: %s conflicts with PHP extension "' . $dep->name . '"' . $extra); } } return true; } else { if ($dep->conflicts) { return true; } if ($required) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep->name . '"' . $extra); } else { return $this->warning('warning: %s requires PHP extension "' . $dep->name . '"' . $extra); } } else { return $this->warning('%s can optionally use PHP extension "' . $dep->name . '"' . $extra); } } } if (!$loaded) { if ($dep->conflicts) { return true; } if (!$required) { return $this->warning('%s can optionally use PHP extension "' . $dep->name . '"' . $extra); } else { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep->name . '"' . $extra); } return $this->warning('warning: %s requires PHP extension "' . $dep->name . '"' . $extra); } } $version = (string) $this->phpversion($dep->name); if (empty($version)) { $version = '0'; } $fail = false; if (isset($dep->min)) { if (!version_compare($version, $dep->min, '>=')) { $fail = true; } } if (isset($dep->max)) { if (!version_compare($version, $dep->max, '<=')) { $fail = true; } } if ($fail && !$dep->conflicts) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PHP extension "' . $dep->name . '"' . $extra . ', installed version is ' . $version); } else { return $this->warning('warning: %s requires PHP extension "' . $dep->name . '"' . $extra . ', installed version is ' . $version); } } elseif (!isset($dep->exclude) && (isset($dep->min) || isset($dep->max)) && !$fail && $dep->conflicts) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s conflicts with PHP extension "' . $dep->name . '"' . $extra . ', installed version is ' . $version); } else { return $this->warning('warning: %s conflicts with PHP extension "' . $dep->name . '"' . $extra . ', installed version is ' . $version); } } if (isset($dep->exclude)) { // exclude ordinarily tells the installer "install anything but these versions" // when paired with conflicts, it becomes "install only these versions" $conflicts = $dep->conflicts; foreach ($dep->exclude as $exclude) { if (version_compare($version, $exclude, '==')) { if ($conflicts) { $fail = false; break; } goto conflict_error; } else { if ($conflicts) { $fail = true; } } } } if ($fail) { conflict_error: if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s is not compatible with version ' . $version . ' of PHP extension "' . $dep->name . '", installed version is ' . $version); } else { return $this->warning('warning: %s is not compatible with version ' . $version . ' of PHP extension "' . $dep->name . '", installed version is ' . $version); } } if (isset($dep->recommended)) { if (version_compare($version, $dep->recommended, '==')) { return true; } else { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s dependency: PHP extension ' . $dep->name . ' version "' . $version . '"' . ' is not the recommended version "' . $dep->recommended . '", but may be compatible, use --force to install'); } else { return $this->warning('warning: %s dependency: PHP extension ' . $dep->name . ' version "' . $version . '"' . ' is not the recommended version "' . $dep->recommended . '"'); } } } return true; } function validatePhpDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Dep $dep) { if ($this->_state != \pear2\Pyrus\Validate::INSTALLING && $this->_state != \pear2\Pyrus\Validate::DOWNLOADING) { return true; } $version = $this->phpversion(); $extra = $this->_getExtraString($dep); if (isset($dep->min)) { if (!version_compare($version, $dep->min, '>=')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PHP' . $extra . ', installed version is ' . $version); } else { return $this->warning('warning: %s requires PHP' . $extra . ', installed version is ' . $version); } } } if (isset($dep->max)) { if (!version_compare($version, $dep->max, '<=')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PHP' . $extra . ', installed version is ' . $version); } else { return $this->warning('warning: %s requires PHP' . $extra . ', installed version is ' . $version); } } } if (isset($dep->exclude)) { foreach ($dep->exclude as $exclude) { if (version_compare($version, $exclude, '==')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s is not compatible with PHP version ' . $exclude); } else { return $this->warning( 'warning: %s is not compatible with PHP version ' . $exclude); } } } } return true; } /** * This makes unit-testing a heck of a lot easier */ function getPEARVersion() { return '@PACKAGE_VERSION@' === '@'.'PACKAGE_VERSION@' ? '2.0.0' : '@PACKAGE_VERSION@'; } function validatePearinstallerDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Dep $dep) { $pearversion = $this->getPEARVersion(); $extra = $this->_getExtraString($dep); if (version_compare($pearversion, $dep->min, '<')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } else { return $this->warning('warning: %s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } } if (isset($dep->max)) { if (version_compare($pearversion, $dep->max, '>')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } else { return $this->warning('warning: %s requires PEAR Installer' . $extra . ', installed version is ' . $pearversion); } } } if (isset($dep->exclude)) { foreach ($dep->exclude as $exclude) { if (version_compare($exclude, $pearversion, '==')) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s is not compatible with PEAR Installer ' . 'version ' . $exclude); } else { return $this->warning('warning: %s is not compatible with PEAR ' . 'Installer version ' . $exclude); } } } } return true; } function validateSubpackageDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $dep, $params) { return $this->validatePackageDependency($dep, $params); } /** * @param array dependency information (2.0 format) * @param boolean whether this is a required dependency * @param array a list of downloaded packages to be installed, if any */ function validatePackageDependency(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $dep, $params) { if ($this->_state != \pear2\Pyrus\Validate::INSTALLING && $this->_state != \pear2\Pyrus\Validate::DOWNLOADING) { return true; } $required = $dep->deptype == 'required'; if (isset($dep->providesextension)) { if ($this->extension_loaded($dep->providesextension)) { $req = $required ? 'required' : 'optional'; $info = $dep->getInfo(); $info['name'] = $info['providesextension']; $subdep = new \pear2\Pyrus\PackageFile\v2\Dependencies\Package( $req, 'extension', null, $info, 0); $ret = $this->validateExtensionDependency($subdep); if ($ret === true) { return true; } } } if ($this->_state == \pear2\Pyrus\Validate::INSTALLING) { return $this->_validatePackageInstall($dep); } if ($this->_state == \pear2\Pyrus\Validate::DOWNLOADING) { return $this->_validatePackageDownload($dep, $params); } } function _validatePackageDownload(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $dep, $params) { $required = $dep->deptype === 'required'; $depname = \pear2\Pyrus\Config::parsedPackageNameToString(array('package' => $dep->name, 'channel' => $dep->channel), true); $found = false; foreach ($params as $param) { if ($param->name == $dep->name && $param->channel == $dep->channel) { $found = true; break; } } if ($found) { $version = $param->version['release']; $installed = false; $downloaded = true; } else { if (\pear2\Pyrus\Config::current()->registry->exists($dep->name, $dep->channel)) { $installed = true; $downloaded = false; $version = \pear2\Pyrus\Config::current()->registry->info($dep->name, $dep->channel, 'version'); } else { $version = 'not installed or downloaded'; $installed = false; $downloaded = false; } } $extra = $this->_getExtraString($dep); if (!isset($dep->min) && !isset($dep->max) && !isset($dep->recommended) && !isset($dep->exclude)) { if ($installed || $downloaded) { $installed = $installed ? 'installed' : 'downloaded'; if ($dep->conflicts) { $rest = ", $installed version is " . $version; if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); } else { return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); } } return true; } else { if ($dep->conflicts) { return true; } if ($required) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } else { return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } } else { return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } } } if (!$installed && !$downloaded) { if ($dep->conflicts) { return true; } if ($required) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } else { return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } } else { return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } } $fail = false; if (isset($dep->min)) { if (version_compare($version, $dep->min, '<')) { $fail = true; } } if (isset($dep->max)) { if (version_compare($version, $dep->max, '>')) { $fail = true; } } if ($fail && !$dep->conflicts) { $installed = $installed ? 'installed' : 'downloaded'; $dep = \pear2\Pyrus\Config::parsedPackageNameToString(array('package' => $dep->name, 'channel' => $dep->channel), true); if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s requires package "' . $depname . '"' . $extra . ", $installed version is " . $version); } else { return $this->warning('warning: %s requires package "' . $depname . '"' . $extra . ", $installed version is " . $version); } } elseif (!isset($dep->exclude) && (isset($dep->min) || isset($dep->max)) && !$fail && $dep->conflicts) { $installed = $installed ? 'installed' : 'downloaded'; if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . ', ' . $installed . ' version is ' . $version); } else { return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . ', ' . $installed . ' version is ' . $version); } } if (isset($dep->exclude)) { // exclude ordinarily tells the installer "install anything but these versions" // when paired with conflicts, it becomes "install only these versions" $conflicts = $dep->conflicts; foreach ($dep->exclude as $exclude) { if (version_compare($version, $exclude, '==')) { if ($conflicts) { $fail = false; break; } goto conflict_error; } else { if ($conflicts) { $fail = true; } } } } elseif ($dep->conflicts) { return true; } if ($fail) { conflict_error: $installed = $installed ? 'installed' : 'downloaded'; if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('%s is not compatible with version ' . $version . ' of package "' . $depname . '", ' . $installed . ' version is ' . $version); } else { return $this->warning('warning: %s is not compatible with version ' . $version . ' of package "' . $depname . '", ' . $installed . ' version is ' . $version); } } if (isset($dep->recommended)) { if (version_compare($version, $dep->recommended, '==')) { return true; } else { if (!$found && $installed) { $param = \pear2\Pyrus\Config::current()->registry->package[$dep->channel . '/' . $dep->name]; } if ($param) { $found = false; foreach ($params as $parent) { if ($parent->name == $this->_currentPackage['package'] && $parent->channel == $this->_currentPackage['channel']) { $found = true; break; } } if ($found) { if ($param->isCompatible($parent)) { return true; } } } $installed = $installed ? 'installed' : 'downloaded'; if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force']) && !isset(\pear2\Pyrus\Main::$options['loose'])) { return $this->raiseError('%s dependency package "' . $depname . '" ' . $installed . ' version ' . $version . ' is not the recommended version ' . $dep->recommended . ', but may be compatible, use --force to install'); } else { return $this->warning('warning: %s dependency package "' . $depname . '" ' . $installed . ' version ' . $version . ' is not the recommended version ' . $dep->recommended); } } } return true; } function _validatePackageInstall($dep) { return $this->_validatePackageDownload($dep, array()); } function validatePackageUninstall($dep, $param) { if ($dep->conflicts) { return true; // uninstall OK - these packages conflict (probably installed with --force) } $required = $dep->deptype == 'required'; $depname = \pear2\Pyrus\Config::parsedPackageNameToString(array('package' => $dep->name, 'channel' => $dep->channel), true); $extra = $this->_getExtraString($dep); if (!isset($dep->min) && !isset($dep->max) && !isset($dep->exclude)) { if ($required) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError('"' . $depname . '" is required by ' . 'installed package %s' . $extra); } else { return $this->warning('warning: "' . $depname . '" is required by ' . 'installed package %s' . $extra); } } else { return $this->warning('"' . $depname . '" can be optionally used by ' . 'installed package %s' . $extra); } } $version = $param->version['release']; $fail = false; if (isset($dep->min)) { if (version_compare($version, $dep->min, '>=')) { $fail = true; } else { goto nofail; } } if (isset($dep->max)) { if (version_compare($version, $dep->max, '<=')) { $fail = true; } } nofail: if (isset($dep->exclude)) { $fail = true; foreach ($dep->exclude as $exclude) { if (version_compare($version, $exclude, '==')) { // rare case - we conflict with the installed package, // so uninstalling is just fine $fail = false; break; } } } if ($fail) { if ($required) { if (!isset(\pear2\Pyrus\Main::$options['nodeps']) && !isset(\pear2\Pyrus\Main::$options['force'])) { return $this->raiseError($depname . $extra . ' is required by installed package' . ' "%s"'); } else { return $this->warning('warning: ' . $depname . $extra . ' is required by installed package "%s"'); } } else { return $this->warning($depname . $extra . ' can be optionally used by installed package' . ' "%s"'); } } return true; } /** * validate a downloaded package against installed packages * * @param $pkg downloaded package package.xml object * @param array $params full list of packages to install * @return bool */ function validateDownloadedPackage(\pear2\Pyrus\IPackageFile $pkg, $params = array()) { $me = $pkg->channel . '/' . $pkg->name; $reg = \pear2\Pyrus\Config::current()->registry; $deppackages = $reg->getDependentPackages($pkg); $fail = false; if ($deppackages) { $actual = array(); // first, remove packages that will be installed foreach ($deppackages as $package) { foreach ($params as $packd) { if (strtolower($packd->name) == strtolower($package->name) && $packd->channel == $package->channel) { \pear2\Pyrus\Logger::log(3, 'skipping installed package check of "' . \pear2\Pyrus\Config::parsedPackageNameToString( array('channel' => $package->channel, 'package' => $package->name), true) . '", version "' . $packd->version['release'] . '" will be ' . 'downloaded and installed'); continue 2; } } $actual[] = $package; } foreach ($actual as $package) { $checker = new \pear2\Pyrus\Dependency\Validator( array('channel' => $package->channel, 'package' => $package->name), $this->_state, $this->errs); foreach ($params as $packd) { $deps = $package->dependencies['required']->package; if (isset($deps[$me])) { $ret = $checker->_validatePackageDownload($deps[$me], array($pkg, $package)); } $deps = $package->dependencies['required']->subpackage; if (isset($deps[$me])) { $ret = $checker->_validatePackageDownload($deps[$me], array($pkg)); } $deps = $package->dependencies['optional']->package; if (isset($deps[$me])) { $ret = $checker->_validatePackageDownload($deps[$me], array($pkg, $package)); } $deps = $package->dependencies['optional']->subpackage; if (isset($deps[$me])) { $ret = $checker->_validatePackageDownload($deps[$me], array($pkg)); } } } } if (count($this->errs->E_ERROR)) { return $this->raiseError( '%s cannot be installed, conflicts with installed packages'); } return true; } function raiseError($msg) { if (isset(\pear2\Pyrus\Main::$options['ignore-errors'])) { return $this->warning($msg); } $this->errs->E_ERROR[] = new \pear2\Pyrus\Dependency\Exception(sprintf($msg, \pear2\Pyrus\Config::parsedPackageNameToString( $this->_currentPackage, true))); return false; } function warning($msg) { $this->errs->E_WARNING[] = new \pear2\Pyrus\Dependency\Exception(sprintf($msg, \pear2\Pyrus\Config::parsedPackageNameToString( $this->_currentPackage, true))); return true; } } ?> * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Bit String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class BitString extends \pear2\Pyrus\DER { const TAG = 0x03; protected $value = false; protected $bitcount = 0; function __construct($string = '', $bits = 0) { $this->setValue($string, $bits); } function setValue($string, $bits = 0) { if (is_string($string)) { if (preg_match('/[01]+/', $string)) { $this->value = $string; $this->bitcount = strlen($string); return; } } $string = decbin(intval($string)); if (!$bits) { $bits = strlen($string); $extra = 8 - $bits % 8; if ($extra === 8) { $extra = 0; } $bits += $extra; $string = str_repeat('0', $extra) . $string; } if (strlen($string) < $bits) { $string = str_repeat('0', $bits - strlen($string)); } elseif (strlen($string) < $bits) { $string = substr($string, strlen($string) - $bits); } $this->bitcount = $bits; $this->value = $string; } function serialize() { // pad the string with zeros $extra = 8 - strlen($this->value) % 8; if ($extra === 8) { $extra = 0; } $string = $this->value . str_repeat('0', $extra); $string = base_convert($string, 2, 16); if (strlen($string) % 2) { $string = '0' . $string; } $hexlen = strlen($string) / 2; $value = ''; for ($i = 0; $i < $hexlen; $i++) { $byte = hexdec(substr($string, $i * 2, 2)); $value .= chr($byte); } // note the number of padding bits applied $value = chr($extra) . $value; return $this->prependTLV($value, strlen($value)); } function parse($data, $location) { $ret = parent::parse($data, $location); $unusedbits = ord($this->value[0]); $value = substr($this->value, 1); $str = ''; $strlen = strlen($value); for ($i = 0; $i < $strlen; $i++) { if ($i == $strlen - 1) { $binary = substr(decbin(ord($value[$i])), 0, 8 - $unusedbits); } else { $binary = decbin(ord($value[$i])); } $str .= $binary; } $this->value = $str; return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule BMPString * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class BMPString extends \pear2\Pyrus\DER\String { const TAG = 0x1E; function setValue($string) { $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule boolean value * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Boolean extends \pear2\Pyrus\DER { const TAG = 0x01; protected $value = false; function __construct($value = false) { $this->value = $value; } function setValue($value) { $this->value = (bool) $value; } function serialize() { $bool = $this->value ? chr(0xFF) : chr(0x00); return $this->prependTLV($bool, 1); } function parse($data, $location) { $ret = parent::parse($data, $location); $this->value = (bool) ord($this->value); return $ret; } function valueToString() { return $this->value ? 'TRUE' : 'FALSE'; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Context-sensitive abstract Choice * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Choice extends \pear2\Pyrus\DER\Sequence { } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IA5String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; abstract class Constructed extends \pear2\Pyrus\DER { function parse($data, $location) { list($location, $length) = $this->decodeLength($data, $location); $data = substr($data, $location, $length); $location += $length; parent::parseFromString($data, $this); return $location; } function valueToString() { return ''; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Integer * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Enumerated extends \pear2\Pyrus\DER\Integer { const TAG = 0x0A; } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception when DER values are not representable * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Exception extends \pear2\Exception { } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule External * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class External extends \pear2\Pyrus\DER { const TAG = 0x08; } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Octet String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class GeneralizedTime extends \pear2\Pyrus\DER\UTCTime { const TAG = 0x18; function serialize() { $value = $this->value->format('YmdHis'); $value .= 'Z'; return $this->prependTLV($value, strlen($value)); } function valueToString() { return $this->value->format('YmdHis') . 'Z'; } function parse($data, $location) { $ret = \pear2\Pyrus\DER::parse($data, $location); $this->value = new \DateTime($this->value); return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IA5String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class IA5String extends \pear2\Pyrus\DER\String { const TAG = 0x16; function setValue($string) { if (preg_match('/[^\000-\177]/', $string)) { throw new \pear2\Pyrus\DER\Exception('Invalid IA5 String value, can only contain ASCII'); } $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Integer * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Integer extends \pear2\Pyrus\DER { const TAG = 0x02; protected $value; function __construct($int = 0) { $this->setValue($int); } function setValue($int) { if (!is_string($int)) { $this->value = intval($int); } else { $this->value = $int; } } function serialize() { if (is_string($this->value)) { return $this->prependTLV($value, strlen($value)); } if ($this->value < 0) { $hexvalue = dechex(-$this->value); } else { $hexvalue = dechex($this->value); } if (strlen($hexvalue) % 2) { $hexvalue = '0' . $hexvalue; } $hexlen = strlen($hexvalue) / 2; $value = ''; for ($i = 0; $i < $hexlen; $i++) { $byte = hexdec(substr($hexvalue, $i * 2, 2)); if ($this->value < 0) { // ones complement $byte ^=0xFF; if ($i == $hexlen - 1) { // add 1 to LSB for twos complement $byte += 1; } if ($i == 0) { if (($byte & 0x80) !== 0x80) { // we must have a leading 0xFF if the number doesn't // start with a leading bit, otherwise we become non-negative $value .= "\777"; } } } if ($this->value > 0 && !$i) { if (($byte & 0x80) === 0x80) { // leading 0 so that this is not interpreted as a negative number $value .= "\0"; } } $value .= chr($byte); } return $this->prependTLV($value, strlen($value)); } function parse($data, $location) { $ret = parent::parse($data, $location); $value = $this->value; $int = 0; $negative = ($value[0] & 0x80) === 0x80; if ($negative) { $value[strlen($value) - 1] = ord($value[strlen($value) - 1]) - 1; for ($i = 0; $i < strlen($value); $i++) { $value[$i] = ord($value[$i]) ^ 0xFF; } } for ($i = 0; $i < strlen($value); $i++) { $int <<= 8; $int += ord($value[$i]); } $this->value = $negative ? -$int : $int; return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Null value * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Null extends \pear2\Pyrus\DER { const TAG = 0x05; function serialize() { return $this->prependTLV('', 0); } function valueToString() { return ''; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IA5String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class NumericString extends \pear2\Pyrus\DER\String { const TAG = 0x12; function setValue($string) { if (!preg_match('/^[0-9 ]+\\z/', $string)) { throw new \pear2\Pyrus\DER\Exception('Invalid Numeric String value, can only contain digits and space'); } $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Object identifier * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class ObjectIdentifier extends \pear2\Pyrus\DER { const TAG = 0x06; protected $value = ''; protected $map = array( '1.2.840.113549.1.1.1' => 'RSA encryption', '1.2.840.113549.1.1.5' => 'SHA-1 checksum with RSA encryption', '1.2.840.113549.1.9.1' => 'Email (for use in signatures)', '1.3.6.1.5.5.7.48.1' => 'OCSP', '1.3.6.1.5.5.7.48.1.1' => 'OCSP basic response', '1.3.6.1.5.5.7.48.1.2' => 'OCSP nonce', '1.3.14.3.2.26' => 'SHA-1 hash algorithm', '2.5.4.3' => 'Common Name', '2.5.4.6' => 'Country Name', '2.5.4.7' => 'Locality (City) Name', '2.5.4.8' => 'State/Province Name', '2.5.4.10' => 'Organization Name', '2.5.4.11' => 'Organization Web Site', '2.5.29.37' => 'Extended Key Usage', '2.5.29.17' => 'Subject Alternative Name', '2.5.29.19' => 'Basic Constraints - can it be a CA?' ); function __construct($value = '') { if ($value) { $this->setValue($value); } } function setValue($value) { if (!is_string($value)) { throw new \pear2\Pyrus\DER\Exception('Object Identifier must be a string'); } $value = explode('.', $value); foreach ($value as $val) { if (!preg_match('/[0-9]+/', $val)) { throw new \pear2\Pyrus\DER\Exception('Object Identifier must be a period-delimited string of numbers'); } } $this->value = $value; } function serialize() { $obj = $this->value; $value = chr($obj[0] * 40 + $obj[1]); $obj = array_slice($obj, 2); foreach ($obj as $node) { if ($node > 127) { // value is encoded in base 128, all significant bits set to 1 except // the last one, which is set to 0 $node = intval($node); $components = array(); while ($node) { $components[] = $node % 128; $node = floor($node / 128); } $components = array_reverse($components); $componentcount = count($components); for ($i = 0; $i < $componentcount; $i++) { if ($i != $componentcount - 1) { $components[$i] |= 0x80; } $value .= chr($components[$i]); } } else { $value .= chr((int) $node); } } return $this->prependTLV($value, strlen($value)); } function parse($data, $location) { $ret = parent::parse($data, $location); $value = $this->value; $start = ord($value[0]); $first = floor($start / 40); $second = $start - $first * 40; $this->value = array($first, $second); $strlen = strlen($value); $long = false; $val = 0; for ($i = 1; $i < $strlen; $i++) { $current = ord($value[$i]); if (($current & 0x80) == 0x80) { if (!$long) { $long = true; $val = $current & 0x7F; continue; } } elseif ($long) { $long = false; $val <<= 7; $val |= $current; $this->value[] = $val; $val = 0; continue; } if ($long) { $val <<= 7; $val |= $current & 0x7F; } else { $this->value[] = $current; } } return $ret; } function valueToString() { $ret = implode('.', $this->value); if (isset($this->map[$ret])) { $ret .= ' [' . $this->map[$ret] . ']'; } return $ret; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IASN.1 schema * * This is used to name components and to retrieve context-specific types * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class OCSPRequest extends \pear2\Pyrus\DER { protected function __construct($developerCert) { $this->setSchema($this->getSchema()); $ocsprequest = $this->OCSPRequest->tbsRequest->requestListSeq->reqCert; $ocsprequest->hashAlgorithm->algorithm = '1.3.14.3.2.26'; // SHA-1 $ocsprequest->hashAlgorithm->parameters = null; if (!file_exists($developerCert)) { throw new \pear2\Pyrus\DER\Exception('Developer certificate ' . $developerCert . ' does not exist'); } $info = openssl_x509_parse(file_get_contents($developerCert)); if (!isset($info['serialNumber']) || !isset($info['issuer']) || !isset($info['issuer']['OU'])) { throw new \pear2\Pyrus\DER\Exception('Cannot process developer Certificate ' . $developerCert . ', missing key fields'); } if ($info['issuer']['OU'] != 'http://www.cacert.org') { // other issuers are picky about who they allow to verify, // so we only accept certs from cacert throw new \pear2\Pyrus\DER\Exception('Cannot verify certificate, ' . 'it is not from cacert.org'); } $ocsprequest->issuerNameHash = pack('C*', '8ba4c9cb172919453ebb8e730991b925f2832265'); $ocsprequest->issuerKeyHash = pack('C*', '16b5321bd4c7f3e0e68ef3bdd2b03aeeb23918d1'); $ocsprequest->serialNumber = $info['serialNumber']; $this->requestExtensions->Inner->Extension->extnID = '1.3.6.1.5.5.7.48.1.2'; // OCSP nonce $this->requestExtensions->Inner->Extension->extnValue = md5($info['serialNumber'] . time(), true); echo $this; } protected function getSchema() { if (isset($types['ocsprequest'])) { return $types['OCSPRequest']; } $types = \pear2\Pyrus\DER\Schema::types(); if (!isset($types['anothername'])) { \pear2\Pyrus\DER\Schema::addType('AnotherName', \pear2\Pyrus\DER\Schema::factory() ->sequence('AnotherName') ->objectIdentifier('type-id') ->any('value', 0)); } if (!isset($types['generalname'])) { \pear2\Pyrus\DER\Schema::addType('GeneralName', \pear2\Pyrus\DER\Schema::factory() ->choice('GeneralName') ->option('otherName', 'AnotherName') ->option('rfc822Name', 'IA5String') ->option('dNSName', 'IA5String') ->option('x400Address', 'AnotherName') // ORaddress, I'm lazy ->option('dNSName', 'IA5String')); } if (!isset($types['algorithmidentifier'])) { \pear2\Pyrus\DER\Schema::addType('AlgorithmIdentifier', \pear2\Pyrus\DER\Schema::factory() ->sequence('AlgorithmIdentifier') ->objectIdentifier('algorithm') ->any('parameters')); } if (!isset($types['certid'])) { \pear2\Pyrus\DER\Schema::addType('CertID', \pear2\Pyrus\DER\Schema::factory() ->sequence('CertID') ->algorithmIdentifier('hashAlgorithm') ->octetString('issuerNameHash') ->octetString('issuerKeyHash') ->integer('serialNumber')); } if (!isset($types['extensions'])) { \pear2\Pyrus\DER\Schema::addType('Extensions', $extensions = \pear2\Pyrus\DER\Schema::factory() ->sequence('Extensions') ->sequence('Inner') ->sequence('Extension')->setMultiple() ->objectIdentifier('extnID') ->boolean('critical') ->octetString('extnValue') ->end() ->end()); $extensions->Inner->Extension->critical->setOptional(); } if (!isset($types['request'])) { \pear2\Pyrus\DER\Schema::addType('Request', $request = \pear2\Pyrus\DER\Schema::factory() ->sequence('Request') ->certID('reqCert') ->extensions('singleRequestExtensions', 0)); $request->singleRequestExtensions->setOptional(); } if (!isset($types['tbsrequest'])) { \pear2\Pyrus\DER\Schema::addType('TBSRequest', $tbs = \pear2\Pyrus\DER\Schema::factory() ->sequence('TBSRequest') ->integer('version', 0) ->generalName('requestorName', 1) ->sequence('requestListSeq') ->request('requestList') ->end() ->extensions('requestExtensions', 2) ); $tbs->version->setOptional(); $tbs->requestorName->setOptional(); $tbs->test->requestList->setMultiple(); $tbs->requestExtensions->setOptional(); } $schema = new \pear2\Pyrus\DER\Schema; $schema ->sequence('OCSPRequest') ->TBSRequest('tbsRequest'); \pear2\Pyrus\DER\Schema::addType('OCSPRequest', $schema); return $schema; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Octet String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class OctetString extends \pear2\Pyrus\DER { const TAG = 0x04; protected $value; function __construct($string = '') { $this->setValue($string); } function setValue($string) { $this->value = $string; } function serialize() { return $this->prependTLV($this->value, strlen($this->value)); } function valueToString() { return bin2hex($this->value); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Parses a Distinguished Encoding Rule binary string into a DER object * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Parser { } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Octet String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class PrintableString extends \pear2\Pyrus\DER\String { const TAG = 0x13; function setValue($string) { if (strlen($string) && !preg_match('/^[a-zA-Z0-9\'()+,\-\\.\/:=?]+\\z/', $string)) { throw new \pear2\Pyrus\DER\Exception('Invalid Printable string value ' . $string . ', can only contain letters, digits, space and' . ' these punctuations: \' ( ) + , - . / : = ?'); } $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IASN.1 schema * * This is used to name components and to retrieve context-specific types * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Schema extends \pear2\Pyrus\DER { static protected $types = array(); protected $name; protected $parent; protected $tag; protected $optional = false; protected $multiple = false; protected $class; protected $lastfind = false; function __construct(\pear2\Pyrus\DER\Schema $parent = null, $tag = 0, $type = '') { $this->parent = $parent; $this->tag = $tag; $this->class = $type; } function setOptional() { $this->optional = true; return $this; } function setMultiple() { $this->multiple = true; return $this; } function setName($name) { $this->name = $name; } function setTag($tag) { $this->tag = $tag; } function setClass($class) { $this->class = $class; } function multiple() { return $this->multiple; } function optional() { return $this->optional; } function __call($func, $args) { if ($func == 'choice') { if (isset($args[0])) { if (isset($args[1])) { $obj = new \pear2\Pyrus\DER\SchemaChoice($this, $args[0], $args[1]); } else { $obj = new \pear2\Pyrus\DER\SchemaChoice($this, $args[0]); } $this->objs[$args[0]] = $obj; return $obj; } else { return new \pear2\Pyrus\DER\SchemaChoice($this); } } if (!isset($args[0])) { throw new \pear2\Pyrus\DER\Exception('Invalid schema, element must be named'); } $name = $args[0]; if ($func == 'any') { if (isset($args[1])) { $obj = new \pear2\Pyrus\DER\Schema($this, 0x80 | $args[1], 'any'); } else { $obj = new \pear2\Pyrus\DER\Schema($this, 0, 'any'); } } elseif (isset(self::$types[strtolower($func)])) { $obj = clone self::$types[strtolower($func)]; $obj->setParent($this); if (isset($args[1])) { if ($obj->parentSchema()) { $obj->setTag(0x80 | 0x20 | $args[1]); } else { $obj->setTag(0x80 | $args[1]); } } } else { $class = 'pear2\Pyrus\DER\\' . ucfirst($func); if (!class_exists($class, 1)) { throw new \pear2\Pyrus\DER\Exception('Unknown type ' . $func . ' at ' . $this->path()); } if (!isset($args[1])) { $tag = $class::TAG; } else { $tag = $args[1] | 0x80; if (strtolower($func) == 'set' || strtolower($func) == 'sequence') { $tag |= 0x20; } } $obj = new \pear2\Pyrus\DER\Schema($this, $tag, $class); } $this->objs[$name] = $obj; $obj->setName($name); if ($obj->parentSchema() && !isset(self::$types[strtolower($func)])) { return $obj; } else { return $this; } } function __clone() { foreach ($this->objs as $i => $obj) { $this->objs[$i] = clone $obj; $obj->setParent($this); } } function parentSchema() { if ($this instanceof \pear2\Pyrus\DER\SchemaChoice) { return true; } if ($this->class === 'pear2\Pyrus\DER\Sequence') { return true; } if ($this->class === 'pear2\Pyrus\DER\Set') { return true; } return false; } function setParent(\pear2\Pyrus\DER\Schema $parent) { $this->parent = $parent; } function end() { return $this->parent; } static function addType($name, \pear2\Pyrus\DER\Schema $schema) { self::$types[strtolower($name)] = $schema; } static function types() { return self::$types; } function __get($var) { if ($var === 'types') { return self::$types; } if ($var == 'name') { return $this->name; } if ($var == 'tag') { return $this->tag; } if ($var == 'type') { return $this->class; } if (isset($this->objs[$var])) { return $this->objs[$var]; } throw new \pear2\Pyrus\DER\Exception('Unknown schema element ' . $var); } function findTag($tag) { if ($this->tag === $tag) { return $this; } return false; } function resetLastFind() { $this->lastfind = false; } function find($tag) { foreach ($this->objs as $index => $obj) { if ($this->lastfind && $index != $this->lastfind) { continue; } if ($this->lastfind) { if ($obj->multiple() && $this->lastfind == $index) { if ($test = $obj->findTag($tag)) { return $test; } } $this->lastfind = false; continue; } if ($obj->type === 'any') { if (($tag & 0x80) === 0x80) { // context-sensitive tag, do best guess if (($tag & 0x20) == 0x20) { $tag = \pear2\Pyrus\DER\Sequence::TAG; } else { $tag = \pear2\Pyrus\DER\OctetString::TAG; } } if (!isset($this->tagMap[$tag])) { throw new \pear2\Pyrus\DER\Exception('Unknown tag: ' . dechex($tag) . ' at ' . $this->path()); } $type = $this->tagMap[$tag]; $ret = new \pear2\Pyrus\DER\Schema($this->parent, $tag, $type); $ret->setName($obj->name); $this->lastfind = $index; return $ret; } if ($test = $obj->findTag($tag)) { $this->lastfind = $index; if ($test->name != $index) { $test = clone $test; $test->setName($index); } return $test; } if (!$obj->optional()) { if (isset($this->tagMap[$tag])) { $tag = '"' . str_replace('pear2\Pyrus\DER\\', '', $this->tagMap[$tag]) . '" (0x' . dechex($tag) . ')'; } else { $tag = dechex($tag); } throw new \pear2\Pyrus\DER\Exception('Invalid DER document, required tag ' . $index . ' not found, instead requested ' . 'tag value ' . $tag . ' at ' . $this->path()); } } if (isset($this->tagMap[$tag])) { $tag = '"' . str_replace('pear2\Pyrus\DER\\', '', $this->tagMap[$tag]) . '" (0x' . dechex($tag) . ')'; } else { $tag = dechex($tag); } throw new \pear2\Pyrus\DER\Exception('Invalid DER document, no matching elements for tag ' . $tag . ' at ' . $this->path()); } function path() { if ($this->parent && $this->parent->path()) { return $this->parent->path() . '->' . $this->name; } return $this->name; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IASN.1 schema Choice * * This is used to name components and to retrieve context-specific types * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class SchemaChoice extends \pear2\Pyrus\DER\Schema { protected $options = array(); function __construct(\pear2\Pyrus\DER\Schema $parent = null, $name = null, $tag = null) { $this->parent = $parent; if ($name !== null) { $this->name = $name; } if ($tag !== null) { $this->tag = 0x80 | $tag; } } function findTag($tag) { if ($tag === $this->tag) { return $this; } foreach ($this->objs as $obj) { if ($obj instanceof self) { if ($test = $obj->findTag($tag)) { if (!$test->class) { $test->setClass('pear2\Pyrus\DER\Choice'); } return $test; } } else { if ($obj->tag === $tag) { return $obj; } } } return false; } function option($name, $type, $index = null) { if (null === $index) { $this->$type($name, count($this->objs)); } else { $this->$type($name, $index); } return $this; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Sequence * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Sequence extends \pear2\Pyrus\DER\Constructed { const TAG = 0x30; function serialize() { $internals = parent::serialize(); return $this->prependTLV($internals, strlen($internals)); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Set * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class Set extends \pear2\Pyrus\DER\Constructed { const TAG = 0x31; function serialize() { $internals = parent::serialize(); return $this->prependTLV($internals, strlen($internals)); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule IA5String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; abstract class String extends \pear2\Pyrus\DER { protected $value; function __construct($string = '') { $this->setValue($string); } abstract function setValue($string); function serialize() { return $this->prependTLV($this->value, strlen($this->value)); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule UniversalString * * No unicode ucs-2 -> utf-8 is attempted, you're on your own * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class UniversalString extends \pear2\Pyrus\DER\String { const TAG = 0x1C; function setValue($string) { $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule UTC Time * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class UTCTime extends \pear2\Pyrus\DER { const TAG = 0x17; protected $value; function __construct(\DateTime $date = null) { $this->setValue($date); } function setValue(\DateTime $date = null) { if ($date === null) { $date = date_create(); } $date->setTimezone(new \DateTimeZone('UTC')); $this->value = $date; } function serialize() { $value = $this->value->format('ymdHis'); $value .= 'Z'; return $this->prependTLV($value, strlen($value)); } function parse($data, $location) { $ret = parent::parse($data, $location); // Y2K issues if ($this->value[0] < 5) { $this->value = '20' . $this->value; } else { $this->value = '19' . $this->value; } $this->value = new \DateTime($this->value); return $ret; } function valueToString() { if ($this->value instanceof \DateTime) { return $this->value->format('ymdHis') . 'Z'; } else { return ''; } } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule UTF8String * * No encoding check made, be sure the string really is UTF-8 * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class UTF8String extends \pear2\Pyrus\DER\String { const TAG = 0x0C; function setValue($string) { $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Represents a Distinguished Encoding Rule Octet String * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DER; class VisibleString extends \pear2\Pyrus\DER\String { const TAG = 0x1A; function setValue($string) { $this->value = $string; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception for directedgraph * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DirectedGraph; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Class to represent vertices within the dependency directed graph. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\DirectedGraph; class Vertex implements \ArrayAccess, \Countable, \Iterator { const WHITE = \pear2\Pyrus\DirectedGraph::WHITE; const GRAY = \pear2\Pyrus\DirectedGraph::GRAY; const BLACK = \pear2\Pyrus\DirectedGraph::BLACK; protected $color = self::WHITE; public $data; protected $connections = array(); /** * Encapsulate data within a directed graph vertex * * @param object $data */ function __construct($data) { if (!is_object($data)) { throw new \pear2\Pyrus\DirectedGraph\Exception('data must be an object, was ' . gettype($data)); } $this->data = $data; } /** * Connect to another vertex * * @param \pear2\Pyrus\DirectedGraph\Vertex $to */ function connect(\pear2\Pyrus\DirectedGraph\Vertex $to) { $this->connections[spl_object_hash($to)] = $to; } /** * Set the color of a visited node * * WHITE = unvisited, GRAY = visited, BLACK = finished * * @param self::WHITE|self::GRAY|self::BLACK|null $color if null, return the current color * @return int */ function color($color = null) { if ($color === null) { return $this->color; } $this->color = $color; } function count() { $count = count($this->connections); foreach ($this->connections as $node) { if ($node->color() != self::WHITE) { --$count; } } return $count; } function offsetGet($var) { return $this->connections[$var]; } function offsetSet($var, $value) { if ($value instanceof \pear2\Pyrus\DirectedGraph\Vertex) { $this->connect($value); } } function offsetExists($var) { return isset($this->connections[$var]); } function offsetUnset($var) { unset($this->connections[$var]); } function current() { return current($this->connections); } function next() { return next($this->connections); } function key() { return key($this->connections); } function valid() { return current($this->connections); } function rewind() { reset($this->connections); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * user-customizable configuration role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Cfg extends \pear2\Pyrus\Installer\Role\Common { protected $md5 = null; /** * Do any unusual setup here * @param PEAR_Installer * @param PEAR_PackageFile_v2 * @param array file attributes * @param string file name */ function setup($installer, $pkg, $atts, $file) { if (!($package = $installer->wasInstalled($pkg->name, $pkg->channel))) { return; } if (isset($package->files[$file]) && isset($package->files[$file]['attribs']['md5sum'])) { $this->md5 = $package->files[$file]['attribs']['md5sum']; } } function getRelativeLocation(\pear2\Pyrus\IPackageFile $pkg, \pear2\Pyrus\PackageFile\v2Iterator\FileTag $file, $retDir = false) { if ($this->md5 === null) { return parent::getRelativeLocation($pkg, $file, $retDir); } $info = parent::getRelativeLocation($pkg, $file, $retDir); $path = \pear2\Pyrus\Config::current()->cfg_dir . DIRECTORY_SEPARATOR; if ($retDir) { $filepath = $info[1]; } else { $filepath = $info; } if (@file_exists($path .$filepath)) { // configuration has already been installed, check for modifications // made by the user $md5 = md5_file($path .$filepath); $newmd5 = $pkg->files[$file->packagedname]['attribs']; if (!isset($newmd5['md5sum'])) { $newmd5 = md5_file($pkg->getFilePath($file->packagedname)); } else { $newmd5 = $newmd5['md5sum']; } // first check to see if the user modified the file // next check to see if the config file changed from the last installed version // if both tests are satisfied, install the new file under another name and display a warning if ($md5 !== $this->md5 && $md5 !== $newmd5) { // configuration has been modified, so save our version as // configfile.new-version $old = $filepath; $filepath .= '.new-' . $pkg->version['release']; \pear2\Pyrus\Logger::log(0, "WARNING: configuration file $old is being installed as $filepath, " . "you should manually merge in changes to the existing configuration file"); } } if ($retDir) { $info[1] = $filepath; } else { $info = $filepath; } return $info; } } ?> cfg pear2\Pyrus\Installer\Role\Cfg php extsrc extbin zendextsrc zendextbin 1 cfg_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for all installation roles. * * This class allows extensibility of file roles. Packages with complex * customization can now provide custom file roles along with the possibility of * adding configuration values to match. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Common { /** * @var PEAR_Config * @access protected */ protected $config; /** * @var array */ protected $info; /** * @param \pear2\Pyrus\Config */ function __construct(\pear2\Pyrus\Config $config, $info) { $this->config = $config; $this->info = $info; } /** * Retrieve configuration information about a file role from its XML info * * @param string $role role name * @return array */ static function getInfo($role) { return \pear2\Pyrus\Installer\Role::getInfo($role); } /** * Get a location that can be used in an tag to work with * the PEAR Installer. * @param \pear2\Pyrus\Package $pkg * @param array $atts * @return string */ function getCompatibleInstallAs(\pear2\Pyrus\IPackageFile $pkg, $atts) { $location = $this->getPackagingLocation($pkg, $atts); $location = explode('/', $location); array_shift($location); if (!$this->info['honorsbaseinstall']) { array_shift($location); } $location = implode('/', $location); return $location; } /** * Retrieve the location a packaged file should be placed in a package * * @param \pear2\Pyrus\Package $pkg * @param array $atts * @return string */ function getPackagingLocation(\pear2\Pyrus\IPackageFile $pkg, $atts) { if (!$pkg->isNewPackage()) { return $atts['name']; } $role = $this->info['name']; $file = $atts['name']; // strip role from file path // so src/Path/To/File.php becomes Path/To/File.php, // data/package.xsd becomes package.xsd $newpath = $file; if ($role === 'php') { if (strpos($newpath, 'src') === 0) { $newpath = substr($newpath, 4); } } elseif (strpos($newpath, $role) === 0) { $newpath = substr($newpath, strlen($role) + 1); } if ($newpath === false) { $newpath = $file; } if ($newpath) { if ($newpath[0] == '/') { $newpath = substr($newpath, 1); } $file = $newpath; } if ($this->info['honorsbaseinstall']) { $dest_dir = $role; if (array_key_exists('baseinstalldir', $atts)) { if ($atts['baseinstalldir'] != '/') { $dest_dir .= '/' . $atts['baseinstalldir']; } if (strlen($atts['baseinstalldir'])) { $dest_dir .= '/'; } } else { $dest_dir .= '/'; } } elseif ($this->info['unusualbaseinstall']) { $dest_dir = $role . '/' . $pkg->name . '/' . $pkg->channel . '/'; if (array_key_exists('baseinstalldir', $atts)) { if (strlen($atts['baseinstalldir']) && $atts['baseinstalldir'] != '/') { $dest_dir .= $atts['baseinstalldir']; if (strlen($atts['baseinstalldir'])) { $dest_dir .= '/'; } } } else { if (dirname($file) != '.') { $dest_dir .= dirname($file) . '/'; } } } else { $dest_dir = $role . '/' . $pkg->name. '/' . $pkg->channel . '/'; } return $dest_dir . $file; } function getRelativeLocation(\pear2\Pyrus\IPackageFile $pkg, \pear2\Pyrus\PackageFile\v2Iterator\FileTag $file, $retDir = false) { if (!$this->info['locationconfig']) { return false; } if ($this->info['honorsbaseinstall']) { $dest_dir = ''; if ($file->baseinstalldir) { $dest_dir .= $file->baseinstalldir; } } elseif ($this->info['unusualbaseinstall']) { if (!$pkg->isNewPackage()) { // Place files using the old doc dir structure $dest_dir = $pkg->name; } else { $dest_dir = $pkg->name . DIRECTORY_SEPARATOR . $pkg->channel; } if ($file->baseinstalldir) { $dest_dir .= DIRECTORY_SEPARATOR . $file->baseinstalldir; } } else { $dest_dir = $pkg->name . DIRECTORY_SEPARATOR . $pkg->channel; } if (dirname($file->name) != '.' && empty($file['install-as'])) { $newpath = dirname($file->name); if ($pkg->isNewPackage()) { // strip role from file path // so php/Path/To/File.php becomes Path/To/File.php, // data/package.xsd becomes package.xsd $r = strtolower(str_replace('pear2\Pyrus\Installer\Role\\', '', get_class($this))); if ($r === 'php') { if (strpos($newpath, 'src') === 0) { $newpath = substr($newpath, 4); if ($newpath === false) { $newpath = ''; } } } if (strpos($newpath, $r) === 0) { $newpath = substr($newpath, strlen($r) + 1); if ($newpath === false) { $newpath = ''; } } $r = $pkg->name . DIRECTORY_SEPARATOR . $pkg->channel; if (strpos($newpath, $r) === 0) { // Trim off extra channel and package name directories $newpath = substr($newpath, strlen($r) + 1); if ($newpath === false) { $newpath = ''; } } } if ($dest_dir && $newpath) { $dest_dir .= DIRECTORY_SEPARATOR; } $dest_dir .= $newpath; } if ($dest_dir) { $dest_dir .= DIRECTORY_SEPARATOR; } $dest_file = $dest_dir; if (empty($file['install-as'])) { $dest_file .= basename($file->name); } else { $dest_file .= $file['install-as']; } if ($retDir) { // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; list($dest_dir, $dest_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), array($dest_dir, $dest_file)); if ($dest_file[0] == DIRECTORY_SEPARATOR) { $dest_file = substr($dest_file, 1); } return array($dest_dir, $dest_file); } // Clean up the DIRECTORY_SEPARATOR mess $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; $dest_file = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $dest_file); if ($dest_file[0] == DIRECTORY_SEPARATOR) { $dest_file = substr($dest_file, 1); } return $dest_file; } /** * Get the name of the configuration variable that specifies the location of this file * @return string|false */ function getLocationConfig() { return $this->info['locationconfig']; } /** * Do any unusual setup here * @param PEAR_Installer * @param PEAR_PackageFile_v2 * @param array file attributes * @param string file name */ function setup($installer, $pkg, $atts, $file) { } final function packageTimeValidate(\pear2\Pyrus\Package $package, array $fileXml) { if (!isset($this->info['validationmethod'])) { return true; } if (!method_exists($this, $this->info['validationmethod'])) { \pear2\Pyrus\Logger::log(0, 'WARNING: custom role ' . $this->info['name'] . ' specifies non-existing validation method ' . $this->info['validationmethod']); return true; } return $this->{$this->info['validationmethod']}($package, $fileXml); } function isExecutable() { return $this->info['executable']; } function isInstallable() { return $this->info['installable']; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Custom task xml file role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Customcommand extends \pear2\Pyrus\Installer\Role\Data { function validate(\pear2\Pyrus\IPackage $package, array $file) { $parser = new \pear2\Pyrus\XMLParser; $schemapath = \pear2\Pyrus\Main::getDataPath(); if (!file_exists(\pear2\Pyrus\Main::getDataPath() . '/customcommand-2.0.xsd')) { $schemapath = realpath(__DIR__ . '/../../../../data'); } $taskschema = $schemapath . '/customcommand-2.0.xsd'; try { $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema); } catch (\Exception $e) { throw new \pear2\Pyrus\Installer\Role\Exception('Invalid custom command definition file,' . ' file does not conform to the schema', $e); } } } ?> customcommand pear2\Pyrus\Installer\Role\Customcommand validate php extsrc extbin zendextsrc zendextbin 1 data_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Custom role xml file role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Customrole extends \pear2\Pyrus\Installer\Role\Data { function validate(\pear2\Pyrus\IPackage $package, array $file) { $parser = new \pear2\Pyrus\XMLParser; $schemapath = \pear2\Pyrus\Main::getDataPath(); if (!file_exists(\pear2\Pyrus\Main::getDataPath() . '/customrole-2.0.xsd')) { $schemapath = realpath(__DIR__ . '/../../../../data'); } $taskschema = $schemapath . '/customrole-2.0.xsd'; try { $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema); } catch (\Exception $e) { throw new \pear2\Pyrus\Installer\Role\Exception('Invalid custom role definition file,' . ' file does not conform to the schema', $e); } } } ?> customrole pear2\Pyrus\Installer\Role\Customrole validate php extsrc extbin zendextsrc zendextbin 1 data_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Custom task xml file role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Customtask extends \pear2\Pyrus\Installer\Role\Data { function validate(\pear2\Pyrus\IPackage $package, array $file) { $parser = new \pear2\Pyrus\XMLParser; $schemapath = \pear2\Pyrus\Main::getDataPath(); if (!file_exists(\pear2\Pyrus\Main::getDataPath() . '/customtask-2.0.xsd')) { $schemapath = realpath(__DIR__ . '/../../../../data'); } $taskschema = $schemapath . '/customtask-2.0.xsd'; try { $taskinfo = $parser->parse($package->getFilePath($file['attribs']['name']), $taskschema); } catch (\Exception $e) { throw new \pear2\Pyrus\Installer\Role\Exception('Invalid custom task definition file,' . ' file does not conform to the schema', $e); } } } ?> customtask pear2\Pyrus\Installer\Role\Customtask validate php extsrc extbin zendextsrc zendextbin 1 data_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Data role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Data extends \pear2\Pyrus\Installer\Role\Common {} ?> data pear2\Pyrus\Installer\Role\Data php extsrc extbin zendextsrc zendextbin 1 data_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Doc role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Doc extends \pear2\Pyrus\Installer\Role\Common {} ?> doc pear2\Pyrus\Installer\Role\Doc php extsrc extbin zendextsrc zendextbin 1 doc_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception for roles * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Ext role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Ext extends \pear2\Pyrus\Installer\Role\Common {} ?> ext pear2\Pyrus\Installer\Role\Ext extbin zendextbin 1 ext_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * php role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Php extends \pear2\Pyrus\Installer\Role\Common {} ?> php pear2\Pyrus\Installer\Role\Php php extsrc extbin zendextsrc zendextbin 1 php_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Script role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Script extends \pear2\Pyrus\Installer\Role\Common {} ?> script pear2\Pyrus\Installer\Role\Script php extsrc extbin zendextsrc zendextbin 1 bin_dir 1 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Src role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Src extends \pear2\Pyrus\Installer\Role\Common {} ?> src pear2\Pyrus\Installer\Role\Src extsrc zendextsrc 1 src_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Test role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Test extends \pear2\Pyrus\Installer\Role\Common {} ?> test pear2\Pyrus\Installer\Role\Test php extsrc extbin zendextsrc zendextbin 1 test_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * www role * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer\Role; class Www extends \pear2\Pyrus\Installer\Role\Common {} ?> www pear2\Pyrus\Installer\Role\Www php extsrc extbin zendextsrc zendextbin 1 www_dir 1 * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Pyrus installer * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for installation roles for files. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Installer; class Role { static private $_roles; /** * Set up any additional configuration variables that file roles require * * Never call this directly, it is called by the PEAR_Config constructor * @param \pear2\Pyrus\Config * @access private * @static */ public static function initializeConfig(\pear2\Pyrus\Config $config) { if (!isset(self::$_roles)) { self::registerRoles(); } foreach (self::$_roles as $class => $info) { if (!$info['config_vars']) { continue; } $config->addConfigValue($info['config_vars']); } } /** * @param string package type * @param string role name * @static */ static function factory($packagetype, $role) { if (!isset(self::$_roles)) { self::registerRoles(); } if (!in_array($role, self::getValidRoles($packagetype))) { throw new \pear2\Pyrus\Installer\Exception('Invalid role ' . $role . 'requested for package type ' . $packagetype); } $class = self::$_roles[$role]['class']; return new $class(\pear2\Pyrus\Config::current(), self::$_roles[$role]); } /** * Get a list of file roles that are valid for the particular release type. * * For instance, src files serve no purpose in regular php releases. * @param string * @param bool clear cache * @return array * @static */ static function getValidRoles($release, $clear = false) { if (!isset(self::$_roles)) { self::registerRoles(); } static $ret = array(); if ($clear) { $ret = array(); } if (isset($ret[$release])) { return $ret[$release]; } $ret[$release] = array(); foreach (self::$_roles as $role => $okreleases) { if (in_array($release, $okreleases['releasetypes'])) { $ret[$release][] = $role; } } return $ret[$release]; } /** * Get a list of roles that require their files to be installed * * Most roles must be installed, but src and package roles, for instance * are pseudo-roles. src files are compiled into a new extension. Package * roles are actually fully bundled releases of a package * @param bool clear cache * @return array * @static */ static function getInstallableRoles($clear = false) { if (!isset(self::$_roles)) { self::registerRoles(); } static $ret; if ($clear) { unset($ret); } if (!isset($ret)) { $ret = array(); foreach (self::$_roles as $role => $okreleases) { if ($okreleases['installable']) { $ret[] = $role; } } } return $ret; } /** * Return an array of roles that are affected by the baseinstalldir attribute * * Most roles ignore this attribute, and instead install directly into: * PackageName/filepath * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php * @param bool clear cache * @return array * @static */ static function getBaseinstallRoles($clear = false) { if (!isset(self::$_roles)) { self::registerRoles(); } static $ret; if ($clear) { unset($ret); } if (!isset($ret)) { $ret = array(); foreach (self::$_roles as $role => $okreleases) { if ($okreleases['honorsbaseinstall']) { $ret[] = $role; } } } return $ret; } /** * Scan through the Command directory looking for classes * and see what commands they implement. * @param string which directory to look for classes, defaults to * the Installer/Roles subdirectory of * the directory from where this file (__FILE__) is * included. * * @return bool TRUE on success, a PEAR error on failure * @access public * @static */ static function registerRoles($dir = null) { self::$_roles = array(); $parser = new \pear2\Pyrus\XMLParser; if ($dir === null) { $dir = __DIR__ . '/Role'; } if (!file_exists($dir) || !is_dir($dir)) { throw new \pear2\Pyrus\Installer\Role\Exception("registerRoles: opendir($dir) failed"); } $dp = @opendir($dir); if (empty($dp)) { throw new \pear2\Pyrus\Installer\Role\Exception("registerRoles: opendir($dir) failed"); } $schemapath = \pear2\Pyrus\Main::getDataPath() . '/customrole-2.0.xsd'; if (!file_exists($schemapath)) { $schemapath = realpath(__DIR__ . '/../../../data/customrole-2.0.xsd'); } while ($entry = readdir($dp)) { if ($entry{0} == '.' || substr($entry, -4) != '.xml') { continue; } $role = strtolower(basename($entry, '.xml')); // List of roles if (!isset(self::$_roles[$role])) { $file = "$dir/$entry"; $data = $parser->parse($file, $schemapath); $data = $data['role']; if (!is_array($data['releasetypes'])) { $data['releasetypes'] = array($data['releasetypes']); } self::$_roles[$role] = $data; } } closedir($dp); $roles = self::$_roles; ksort($roles); self::$_roles = $roles; self::getBaseinstallRoles(true); self::getInstallableRoles(true); self::getValidRoles('****', true); return true; } static function registerCustomRole($info) { self::$_roles[$info['name']] = $info; $roles = self::$_roles; ksort($roles); self::$_roles = $roles; self::getBaseinstallRoles(true); self::getInstallableRoles(true); self::getValidRoles('****', true); if (isset($info['configvar'])) { if (!isset($info['configvar'][0])) { $info['configvar'] = array($info['configvar']); } foreach ($info['configvar'] as $configvar) { $default = $configvar['default']; if (false !== strpos($default, 'temp_dir . DIRECTORY_SEPARATOR . '.configdefault.php'; if (!file_exists(dirname($tmp))) { mkdir(dirname($tmp), 0755, true); } file_put_contents($tmp, $default); $getDefault = function() use ($tmp) { include $tmp; return $default; }; $default = $getDefault(); } \pear2\Pyrus\Config::addConfigValue($configvar['name'], $default, $configvar['configtype']); } } } /** * Retrieve configuration information about a file role from its XML info * * @param string $role Role Classname, as in "\pear2\Pyrus\Installer\Role\Data" * @return array */ static function getInfo($role) { if (!isset(self::$_roles)) { self::registerRoles(); } if (empty(self::$_roles[$role])) { throw new \pear2\Pyrus\Installer\Role\Exception('Unknown Role: "' . $role . '"'); } return self::$_roles[$role]; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for package creator * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Creator; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Class which iterates over all the tasks to perform for package creation. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Creator; class TaskIterator extends \FilterIterator { private $_inner; private $_parent; private $_tasksNs; private $_installphase; protected $lastversion; function __construct(array $arr, \pear2\Pyrus\IPackage $parent, $phase, $lastversion = null) { $this->_parent = $parent; $this->_tasksNs = $this->_parent->getTasksNs(); $this->_installphase = $phase; $this->lastversion = $lastversion; parent::__construct($this->_inner = new \ArrayIterator($arr)); } function accept() { if (!$this->_inner->valid()) { return false; } if ($this->_inner->key() == 'attribs') { return false; } $key = parent::key(); if (strpos($key, $this->_tasksNs . ':') !== 0) { return false; } $task = \pear2\Pyrus\Task\Common::getTask(parent::key()); if (0 == $task::PHASE & $this->_installphase) { // skip tasks that won't run in this installphase return false; } if ($this->_installphase == \pear2\Pyrus\Task\Common::INSTALL && $this->_parent->isPreProcessed()) { $info = $this->current(); if ($info->isPreProcessed()) { // some tasks are pre-processed at package-time return false; } } return true; } function key() { return str_replace($this->_tasksNs . ':', '', parent::key()); } function current() { $xml = parent::current(); if (isset($xml[0])) { $tasks = array(); $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), parent::key()); $task = str_replace(' ', '/', ucwords($task)); $task = str_replace('/', '_', $task); $task = '\pear2\Pyrus\Task\\' . $task; foreach ($xml as $info) { $attribs = array(); if (isset($xml['attribs'])) { $attribs = $xml['attribs']; } $tasks[] = new $task($this->_parent, $this->_installphase, $info, $attribs, $this->lastversion); } $attribs = isset($this->_inner['attribs']) ? array($this->_inner['attribs']) : $this->_inner; // use proxy for multiple tasks return new \pear2\Pyrus\Task\MultipleProxy($this->_parent, $tasks, $attribs, $this->key()); } $attribs = array(); if (isset($xml['attribs'])) { $attribs = $xml['attribs']; } $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), parent::key()); $task = str_replace(' ', '/', ucwords($task)); $task = str_replace('/', '_', $task); $task = '\pear2\Pyrus\Task\\' . $task; return new $task($this->_parent, $this->_installphase, $xml, $attribs, $this->lastversion); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Class to represent vertices within the dependency directed graph. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Dependency\Set; class Exception extends \pear2\Exception { } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Class to represent vertices within the dependency directed graph. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Dependency\Set; class PackageTree { /** * Optional dependencies that won't be installed * * Informational list of optional depenndencies that * will not be installed without the --optionaldeps flag * @var array */ protected static $optionalDeps = array(); static protected $availableVersionsMap = array(); static protected $localPackages = array(); static protected $allNodes = array(); static protected $allDeps = array(); static protected $errors = array(); protected $parent; protected $set; protected $node; protected $name; protected $compositeDep; protected $compositeConflicts; protected $versionsAvailable = array(); protected $allVersions = array(); protected $children = array(); protected $allchildren = array(); protected $firstVersion; static protected $dirtyMap = array(); function __construct(\pear2\Pyrus\Package\Dependency\Set $set, \pear2\Pyrus\Package $node, PackageTree $parent = null) { $this->set = $set; $this->node = $node; $this->parent = $parent; $this->name = $node->channel . '/' . $node->name; if ($node->isRemote() && $node->isAbstract()) { if ($node->getExplicitVersion()) { $this->firstVersion = $node->getExplicitVersion(); if (isset(static::$availableVersionsMap[$this->name])) { $rebuild = true; } else { $rebuild = false; } $this->allVersions = $this->versionsAvailable = array($node->version['release']); $this->setAvailableVersionsMap(); if ($rebuild) { $this->rebuild($this->name); } self::register($this); return; } if (isset(self::$availableVersionsMap[$this->name])) { $this->allVersions = $this->versionsAvailable = self::$availableVersionsMap[$this->name]; } else { while (!($node instanceof \pear2\Pyrus\Channel\RemotePackage)) { $node = $node->getInternalPackage(); } foreach ($node->getReleaseList() as $info) { $this->allVersions[] = $info['v']; $this->versionsAvailable[] = $info['v']; } if (null === $parent) { return $this->findParentVersion(); } $this->setAvailableVersionsMap(); } } else { $this->versionsAvailable = array($node->version['release']); $this->allVersions = array($node->version['release']); $this->setAvailableVersionsMap(); } self::register($this); } protected function findParentVersion() { $notset = true; do { if (!$this->determineInitialVersion()) { array_pop($this->versionsAvailable); } else { $notset = false; } } while ($notset && count($this->versionsAvailable)); if (count($this->versionsAvailable)) { $this->setAvailableVersionsMap(); self::register($this); return; } throw new Exception('Unable to find a compatible release for ' . $this->name); } static function setLocalPackages(array $packages) { self::$optionalDeps = array(); self::$errors = array(); self::$localPackages = array(); self::$availableVersionsMap = array(); self::$localPackages = $packages; } function synchronize() { if (isset($this->compositeDep)) { if (!$this->compositeDep->equals($this->set->getCompositeDependency($this->node)) || !$this->compositeConflicts->equals($this->set->getCompositeDependency($this->node, true))) { if (null === $this->parent) { $this->findParentVersion(); } else { // tell rebuildIfNecessary() that rebuilding is necessary $this->versionsAvailable = array(); $this->rebuildIfNecessary($this->name); } } } foreach ($this->children as $child) { $child->synchronize(); } } static function resetDirtyMap() { self::$dirtyMap = array(); } protected function setAvailableVersionsMap() { if (!isset(self::$availableVersionsMap[$this->name])) { self::$availableVersionsMap[$this->name] = $this->versionsAvailable; } elseif (self::$availableVersionsMap[$this->name] != $this->versionsAvailable) { self::$dirtyMap[$this->name] = true; self::$availableVersionsMap[$this->name] = $this->versionsAvailable; } } static protected function register($obj) { self::$allNodes[$obj->name][] = $obj; } static protected function unregister($obj) { if (!isset(self::$allNodes[$obj->name])) { throw new Exception('Internal error: ' . $obj->name . ' is ' . 'being unregistered, but is not registered'); } foreach (self::$allNodes[$obj->name] as $i => $test) { if ($test === $obj) { unset(self::$allNodes[$obj->name][$i]); if (!count(self::$allNodes[$obj->name])) { unset(self::$allNodes[$obj->name]); } return; } } } static function dirtyNodes() { return array_keys(self::$dirtyMap); } /** * Rebuild if necessary * * @param string $nodename eg: pear.php.net/Spreadsheet_Excel_Writer */ function rebuildIfNecessary($nodename) { if ($this->name == $nodename) { if ($this->versionsAvailable != self::$availableVersionsMap[$this->name]) { $this->prune(); $this->versionsAvailable = self::$availableVersionsMap[$this->name]; if (!count($this->versionsAvailable)) { $this->throwDepFailException(); } if ($this->node->isRemote()) { $this->node->resetConcreteVersion(); } if (!$this->determineInitialVersion()) { $this->throwDepFailException(); } // check to see if the new version now is the same as what we have installed if ($this->isUpgradeable()) { $installedversion = \pear2\Pyrus\Config::current()->registry->info($this->node->name, $this->node->channel, 'version'); if ($installedversion === $this->node->version['release']) { $this->prune(); $this->parent->removeChild($this); return; } } $this->populate(); } } else { foreach ($this->children as $child) { $child->rebuildIfNecessary($nodename); } } } function has($name) { if ($this->name == $name) { return true; } foreach ($this->children as $child) { if ($child->has($name)) { return true; } } return false; } function prune() { foreach ($this->children as $child) { $child->prune(); $this->removeChild($child); } } function throwDepFailException() { if (isset(self::$errors[$this->name])) { $extra = implode("\n", self::$errors[$this->name]); } throw new Exception('No versions of ' . $this->name . ' or of its dependencies that can be installed because of' . $extra); } function getUnsatisfiedString() { $dep = $this->set->getCompositeDependency($this->node); $conflicting = $this->set->getCompositeDependency($this->node, true); $unsatisfied = array_merge($dep->getUnsatisfiedSources($this->version['release']), $conflicting->getUnsatisfiedSources($this->version['release'])); $fullinfo = ''; foreach ($unsatisfied as $dep) { $fullinfo .= $dep->getPackageFile()->channel . '/' . $dep->getPackageFile()->name . " depends on: $dep\n"; } return ":\n$fullinfo"; } protected function determineInitialVersion($returnFalseOnVersionChange = false) { if (!$this->node->isRemote()) { // anything downloaded or local is good return true; } $this->compositeDep = $dep = $this->set->getCompositeDependency($this->node); $this->compositeConflicts = $conflicting = $this->set->getCompositeDependency($this->node, true); if (!count($this->versionsAvailable)) { $this->throwDepFailException(); } try { if (true === $this->node->figureOutBestVersion($dep, $this->versionsAvailable, $conflicting)) { // we just changed version from a previously calculated version, // so restart if ($returnFalseOnVersionChange) { return false; } return true; } } catch (\pear2\Pyrus\Channel\Exception $e) { if ($this->parent) { $this->parent->saveError($this); } return false; } return true; } function saveError(PackageTree $child) { if (!isset(self::$errors[$this->name])) { self::$errors[$this->name] = array(); } if (!isset(self::$errors[$this->name][$this->version['release']])) { self::$errors[$this->name][$this->version['release']] = ''; } self::$errors[$this->name][$this->version['release']] .= $child->getUnsatisfiedString(); } function removeThisVersion() { $available = array_flip(self::$availableVersionsMap[$this->name]); unset($available[$this->node->version['release']]); $old = $this->versionsAvailable; $this->versionsAvailable = array_flip($available); $this->setAvailableVersionsMap(); // reset so we get re-built $this->versionsAvailable = $old; } /** * Populate the dependency tree with the selected version or an explicit version */ function populate() { $this->populateBranch(); foreach ($this->children as $child) { if (!$child->determineInitialVersion(true)) { $this->removeThisVersion(); return false; } } foreach ($this->children as $child) { if (!$child->populate()) { return false; } } return true; } protected function populateBranch() { $package = $this->node; foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['required']->$p as $dep) { self::$dirtyMap[$dep->channel . '/' . $dep->name] = true; if ($dep->conflicts) { continue; } $this->retrieve($dep); } } if ($package->requestedGroup) { foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['group']->{$package->requestedGroup}->$p as $dep) { self::$dirtyMap[$dep->channel . '/' . $dep->name] = true; $this->retrieve($dep); } } } foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['optional']->$p as $dep) { if (!isset(\pear2\Pyrus\Main::$options['optionaldeps'])) { if (!isset(static::$optionalDeps[$dep->channel . '/' . $dep->name])) { static::$optionalDeps[$dep->channel . '/' . $dep->name] = array(); } static::$optionalDeps[$dep->channel . '/' . $dep->name][$package->channel . '/' .$package->name] = 1; continue; } self::$dirtyMap[$dep->channel . '/' . $dep->name] = true; $this->retrieve($dep); } } } static function getUnusedOptionalDeps() { return self::$optionalDeps; } static function getPHPVersion() { return phpversion(); } /** * Check to see if any packages in the list of packages to be installed * satisfy this dependency, and return one if found, otherwise * instantiate a new dependency package object * @return \pear2\Pyrus\IPackage|NULL */ function retrieve(\pear2\Pyrus\PackageFile\v2\Dependencies\Package $info) { if (isset(self::$localPackages[$info->channel . '/' . $info->name]) || $this->childProcessed($info->channel . '/' . $info->name)) { // we can safely ignore this dependency, an explicit local // package is being installed, and we will use it // or the dependency has been previously processed, and we will // simply result in a duplicate return; } $reg = \pear2\Pyrus\Config::current()->registry; // first check to see if the dependency is installed $canupgrade = false; if (isset($reg->package[$info->channel . '/' . $info->name])) { if (!isset(\pear2\Pyrus\Main::$options['upgrade'])) { // we don't attempt to upgrade a dep unless we're upgrading return; } $version = $reg->info($info->name, $info->channel, 'version'); $stability = $reg->info($info->name, $info->channel, 'state'); if ($this->node->isRemote() && $this->node->getExplicitState()) { $installedstability = \pear2\Pyrus\Installer::betterStates($stability); $parentstability = \pear2\Pyrus\Installer::betterStates($this->node->getExplicitState()); if (count($parentstability) > count($installedstability)) { $stability = $this->node->getExplicitState(); } } else { $installedstability = \pear2\Pyrus\Installer::betterStates($stability); $prefstability = \pear2\Pyrus\Installer::betterStates(\pear2\Pyrus\Config::current()->preferred_state); if (count($prefstability) > count($installedstability)) { $stability = \pear2\Pyrus\Config::current()->preferred_state; } } // see if there are new versions in our stability or better if (isset($info->uri)) { return; } $remote = new \pear2\Pyrus\Channel\Remotepackage(\pear2\Pyrus\Config::current() ->channelregistry[$info->channel], $stability); $found = false; foreach ($remote[$info->name] as $remoteversion => $rinfo) { if (version_compare($remoteversion, $version, '<=')) { continue; } if (version_compare($rinfo['minimumphp'], static::getPHPversion(), '>')) { continue; } // found one, so upgrade is possible if dependencies pass $found = true; break; } // the installed package version satisfies this dependency, don't do anything if (!$found) { return; } $canupgrade = true; } if (isset($info->uri)) { $ret = new \pear2\Pyrus\Package\Remote($info->uri); // set up the basics $ret->name = $info->name; $ret->uri = $info->uri; $this->addChild($ret); return; } if ($this->node->isRemote() && $this->node->getExplicitState()) { // pass the same explicit state to the child dependency $ret = new \pear2\Pyrus\Package\Remote($info->channel . '/' . $info->name . '-' . $this->node->getExplicitState()); if ($canupgrade) { $ret->setUpgradeable(); } $this->addChild($ret); return; } $ret = new \pear2\Pyrus\Package\Remote($info->channel . '/' . $info->name); if ($canupgrade) { $ret->setUpgradeable(); } $this->addChild($ret); return; } protected function addChild($obj) { $child = new self($this->set, $obj, $this); $this->children[] = $child; } protected function removeChild($obj) { foreach ($this->children as $i => $test) { if ($obj === $test) { unset($this->children[$i]); $this->children = array_values($this->children); break; } } self::unregister($obj); $this->top()->unprocessChild($obj); } /** * This method stops dependency cycles from causing infinite recursion. */ protected function childProcessed($obj) { if ($this->parent) { return $this->parent->childProcessed($obj); } if ($obj instanceof self) { $name = $obj->name(); } else { $name = $obj; } if (isset($this->allchildren[$name])) { return true; } $this->allchildren[$name] = true; return false; } protected function unprocessChild($obj) { unset($this->allchildren[$obj->name()]); } function name() { return $this->name; } function top() { if (!$this->parent) { return $this; } return $this->parent->top(); } function getPackageSet($fromParent = array()) { if (!$fromParent && $this->parent) { return $this->parent->getPackageSet(); } $ret = $fromParent; if (!$this->parent) { $ret[$this->name] = $this; } foreach ($this->children as $child) { $ret[$child->name()] = $child; $ret = $child->getPackageSet($ret); } return $ret; } function getDependencies(array $deps, $name) { foreach ($this->getPackageSet() as $package) { if ($package->channel . '/' . $package->name == $name || ($package->isRemote() && !$package->hasConcreteVersion())) { continue; } foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['required']->$p as $dep) { if ($dep->channel . '/' . $dep->name != $name) { continue; } $deps[] = $dep; } } if ($package->requestedGroup) { foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['group']->{$package->requestedGroup}->$p as $dep) { if ($dep->channel . '/' . $dep->name != $name) { continue; } $deps[] = $dep; } } } foreach (array('package', 'subpackage') as $p) { foreach ($package->dependencies['optional']->$p as $dep) { if ($dep->channel . '/' . $dep->name != $name) { continue; } $deps[] = $dep; } } } return $deps; } function __call($func, $args) { return call_user_func_array(array($this->node, $func), $args); } function __get($var) { if ($var == 'node') { return $this->node; } return $this->node->$var; } function __set($var, $value) { $this->node->$var = $value; } function __toString() { return $this->toString(); } protected function toString($pad = '') { $ret = $pad . $this->name . '-' . $this->version['release'] . ":\n"; $deps = ''; foreach ($this->node->dependencies['required']->package as $dep) { $deps .= " ${pad}dep: $dep\n"; } foreach ($this->node->dependencies['required']->subpackage as $dep) { $deps .= " ${pad}dep: $dep\n"; } foreach ($this->node->dependencies['optional']->package as $dep) { $deps .= " ${pad}dep: $dep\n"; } foreach ($this->node->dependencies['optional']->subpackage as $dep) { $deps .= " ${pad}dep: $dep\n"; } foreach ($this->children as $child) { $deps .= $child->toString("$pad "); } if (!$deps) { return $pad . $this->name . '-' . $this->version['release'] . ";\n"; } return $ret . $deps; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Implements a set of dependency trees, and manipulates the trees to combine * them into a unique set of package releases to download * * This structure allows us to properly determine the best version, if any, * of a package that satisfies all dependencies of both packages to download and * installed packages. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Dependency; class Set { protected $packageTrees = array(); protected $duplicates = array(); protected $optionalDeps = array(); function __construct(array $packages) { Set\PackageTree::setLocalPackages($packages); foreach ($packages as $package) { $tree = new Set\PackageTree($this, $package); $this->packageTrees[] = $tree; while (!$tree->populate()) { $this->refine(); } //echo $tree; // uncomment to get a map of each separate dep tree } } function retrieveAllPackages() { $ret = array(); $this->optionalDeps = Set\PackageTree::getUnusedOptionalDeps(); foreach ($this->packageTrees as $tree) { foreach ($tree->getPackageSet() as $package) { $ret[$package->name()] = $package->node; if (isset($this->optionalDeps[$package->name()])) { unset($this->optionalDeps[$package->name()]); } } } return $ret; } function synchronizeDeps() { foreach ($this->packageTrees as $tree) { $tree->synchronize(); //echo $tree; // uncomment to get a map of each separate dep tree } } function refine() { $dirty = Set\PackageTree::dirtyNodes(); while (count($dirty)) { foreach ($dirty as $i => $node) { foreach ($this->packageTrees as $package) { if (!$package->has($node)) { continue; } $package->rebuildIfNecessary($node); } $dirty[$i] = null; } $dirty = array_filter($dirty); } } function getIgnoredOptionalDeps() { return $this->optionalDeps; } function getDependencies(\pear2\Pyrus\Package $info) { $deps = array(); foreach ($this->packageTrees as $tree) { $deps = $tree->getDependencies($deps, $info->channel . '/' . $info->name); } return array_merge($deps, $this->getDependenciesOn($info)); } function getDependenciesOn($info) { $name = $info->name; $channel = $info->channel; $packages = \pear2\Pyrus\Config::current()->registry ->getDependentPackages($info->getPackageFileObject()); $ret = array(); foreach ($packages as $package) { $deps = $package->dependencies; foreach (array('package', 'subpackage') as $type) { foreach (array('required', 'optional') as $required) { foreach ($deps[$required]->$type as $dep) { if ($dep->channel != $channel || $dep->name != $name) { continue; } $ret[] = $dep; } } } } return $ret; } /** * Return a composite dependency on the package, as defined by combining * all dependencies on this package into one. * * As an example, for these dependencies: * *
     * P1 version >= 1.2.0
     * P1 version <= 3.0.0, != 2.3.2
     * P1 version >= 1.1.0, != 1.2.0
     * 
* * The composite dependency is * *
     * P1 version >= 1.2.0, <= 3.0.0, != 2.3.2, 1.2.0
     * 
* @param pear2\Pyrus\Package $info * @param bool $conflicting if true, return a composite dependency, if any */ function getCompositeDependency(\pear2\Pyrus\Package $info, $conflicting = false) { $deps = $this->getDependencies($info); if (!count($deps)) { $dep = new \pear2\Pyrus\PackageFile\v2\Dependencies\Package( 'required', 'package', null, array('name' => $info->name, 'channel' => $info->channel, 'uri' => null, 'min' => null, 'max' => null, 'recommended' => null, 'exclude' => null, 'providesextension' => null, 'conflicts' => null), 0); $dep->setCompositeSources(array()); return $dep; } $compdep = array('name' => $info->name, 'channel' => $info->channel, 'uri' => null, 'min' => null, 'max' => null, 'recommended' => null, 'exclude' => null, 'providesextension' => null, 'conflicts' => null); $initial = true; $recommended = null; $min = null; $max = null; $useddeps = array(); foreach ($deps as $actualdep) { if ($conflicting) { if (!$actualdep->conflicts) { continue; } $compdep['conflicts'] = ''; } elseif ($actualdep->conflicts) { continue; } $useddeps[] = $actualdep; $deppackage = $actualdep->getPackageFile()->channel . '/' . $actualdep->getPackageFile()->name; if ($initial) { if ($actualdep->min) { $compdep['min'] = $actualdep->min; $min = $deppackage; } if ($actualdep->max) { $compdep['max'] = $actualdep->max; $max = $deppackage; } if ($actualdep->recommended) { $compdep['recommended'] = $actualdep->recommended; $recommended = $deppackage; } $compdep['exclude'] = $actualdep->exclude; $initial = false; continue; } if (isset($compdep['recommended']) && isset($actualdep->recommended) && $actualdep->recommended != $compdep['recommended']) { throw new \pear2\Pyrus\Package\Exception('Cannot install ' . $info->channel . '/' . $info->name . ', two dependencies conflict (different recommended values for ' . $deppackage . ' and ' . $recommended . ')'); } if ($compdep['max'] && $actualdep->min && version_compare($actualdep->min, $compdep['max'], '>')) { throw new \pear2\Pyrus\Package\Exception('Cannot install ' . $info->channel . '/' . $info->name . ', two dependencies conflict (' . $deppackage . ' min is > ' . $max . ' max)'); } if ($compdep['min'] && $actualdep->max && version_compare($actualdep->max, $compdep['min'], '<')) { throw new \pear2\Pyrus\Package\Exception('Cannot install ' . $info->channel . '/' . $info->name . ', two dependencies conflict (' . $deppackage . ' max is < ' . $min . ' min)'); } if ($actualdep->min) { if ($compdep['min']) { if (version_compare($actualdep->min, $compdep['min'], '>')) { $compdep['min'] = $actualdep->min; $min = $deppackage; } } else { $compdep['min'] = $actualdep->min; $min = $deppackage; } } if ($actualdep->max) { if ($compdep['max']) { if (version_compare($actualdep->max, $compdep['max'], '<')) { $compdep['max'] = $actualdep->max; $max = $deppackage; } } else { $compdep['max'] = $actualdep->max; $max = $deppackage; } } if ($actualdep->recommended) { $compdep['recommended'] = $actualdep->recommended; $recommended = $deppackage; } if ($actualdep->exclude) { if (!$compdep['exclude']) { $compdep['exclude'] = array(); foreach ($actualdep->exclude as $exclude) { $compdep['exclude'][] = $exclude; } continue; } foreach ($actualdep->exclude as $exclude) { if (in_array($exclude, $compdep['exclude'])) { continue; } $compdep['exclude'][] = $exclude; } } } $dep = new \pear2\Pyrus\PackageFile\v2\Dependencies\Package( 'required', 'package', null, $compdep, 0); $dep->setCompositeSources($useddeps); return $dep; } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Phar packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Phar; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Tar packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Tar; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Zip packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package\Zip; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Base class for representing a package in Pyrus * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package; abstract class Base implements \pear2\Pyrus\IPackage { protected $archive; protected $packagefile; /** * The original source of this package * * This is a chain documenting the steps it took to get this * package instantiated, for instance Tar->Abstract * @var \pear2\Pyrus\IPackage */ protected $from; function __construct(\pear2\Pyrus\PackageFile $packagefile, $parent = null) { $this->packagefile = $packagefile; $this->from = $parent; } function isStatic() { return true; } /** * Used to determine whether a package is designed for Pyrus, or for the PEAR installer * * @return bool */ function isNewPackage() { return version_compare($this->dependencies['required']->pearinstaller->min, '2.0.0a1', '>='); } function isUpgradeable() { if (!isset(\pear2\Pyrus\Main::$options['upgrade'])) { // we don't attempt to upgrade a dep unless we're upgrading return false; } $reg = \pear2\Pyrus\Config::current()->registry; $version = $reg->info($this->name, $this->channel, 'version'); if (version_compare($this->version['release'], $version, '<=')) { return !isset(\pear2\Pyrus\Main::$options['force']); } return true; } function isPlugin() { foreach ($this->installcontents as $file) { if ($file->role === 'customrole' || $file->role === 'customtask' || $file->role === 'customcommand') { return true; } } return false; } /** * This test tells the installer whether to run any package-info * replacement tasks. * * The XML package has not had any package-info transformations. Packages * in tar/zip/phar format have had package-info replacements. * @return bool if false, the installer will run all packag-einfo replacements */ function isPreProcessed() { return true; } function setFrom(\pear2\Pyrus\IPackage $from) { $this->from = $from; } function getFrom() { if ($this->from) { return $this->from->getFrom(); } return $this; } /** * Sort files/directories for removal * * Files are always removed first, followed by directories in * path order * @param unknown_type $a * @param unknown_type $b * @return unknown */ static function sortstuff($a, $b) { // files can be removed in any order if (is_file($a) && is_file($b)) return 0; if (is_dir($a) && is_file($b)) return 1; if (is_dir($b) && is_file($a)) return -1; $countslasha = substr_count($a, DIRECTORY_SEPARATOR); $countslashb = substr_count($b, DIRECTORY_SEPARATOR); if ($countslasha > $countslashb) return -1; if ($countslashb > $countslasha) return 1; // if not subdirectories, tehy can be removed in any order return 0; } /** * Create vertices/edges of a directed graph for dependencies of this package * * Iterate over dependencies and create edges from this package to those it * depends upon * @param \pear2\Pyrus\DirectedGraph $graph * @param array $packages channel/package indexed array of \pear2\Pyrus\Package objects */ function makeConnections(\pear2\Pyrus\DirectedGraph $graph, array $packages) { $graph->add($this->getFrom()); foreach (array('required', 'optional') as $required) { foreach (array('package', 'subpackage') as $package) { foreach ($this->dependencies[$required]->$package as $d) { if ($d->conflicts) { continue; } if (isset($packages[$d->channel . '/' . $d->name])) { $graph->connect($this, $packages[$d->channel . '/' . $d->name]); } } } } foreach ($this->dependencies['group'] as $group) { foreach (array('package', 'subpackage') as $package) { foreach ($group->$package as $d) { if ($d->conflicts) { continue; } if (isset($packages[$d->channel . '/' . $d->name])) { $graph->connect($this, $packages[$d->channel . '/' . $d->name]); } } } } } function offsetExists($offset) { return $this->packagefile->info->hasFile($offset); } function offsetGet($offset) { if (strpos($offset, 'contents://') === 0) { return $this->getFileContents(substr($offset, 11)); } return $this->packagefile->info->getFile($offset); } function offsetSet($offset, $value) { return; } function offsetUnset($offset) { return; } function getPackageFile() { return $this->packagefile; } function __call($func, $args) { // delegate to the internal object return call_user_func_array(array($this->packagefile->info, $func), $args); } function __get($var) { if ($var === 'archivefile') { return $this->archive; } return $this->packagefile->info->$var; } function __set($var, $value) { if ($var === 'archivefile') { return $this->archive = $value; } return $this->packagefile->info->$var = $value; } function getValidator() { return $this->packagefile->info->getValidator(); } function toArray($forpackaging = false) { return $this->packagefile->info->toArray($forpackaging); } function __toString() { return $this->packagefile->__toString(); } function validate($state = \pear2\Pyrus\Validate::NORMAL) { $validator = $this->packagefile->getValidator(); if (!$validator->validate($this, $state)) { throw new \pear2\Pyrus\PackageFile\Exception('Invalid package.xml', $validator->getErrors()); } } function getPackageFileObject() { return $this->packagefile; } function getFileContents($file, $asstream = false) { if (!isset($this[$file])) { throw new \pear2\Pyrus\Package\Exception('file ' . $file . ' is not in this package'); } if ($asstream) { $fp = fopen($this->getFilePath($file), 'rb'); return $fp; } else { $ret = file_get_contents($this->getFilePath($file)); if (!$ret) { $ret = ''; } return $ret; } } function getTask($file, $name) { if (is_string($file)) { $fileAttribs = $this->files[$file]; } elseif (is_array($file)) { $fileAttribs = $file; } $taskclass = \pear2\Pyrus\Task\Common::getTask($name); return new $taskclass($this, \pear2\Pyrus\Task\Common::PACKAGE, $fileAttribs, $fileAttribs['attribs'], null); } } * @copyright 2009 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ /** * Class for cloning (exact copies with hash intact if possible) packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2009 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ namespace pear2\Pyrus\Package; class Cloner { protected $hash; protected $signature_algo; protected $file; protected $outfile = false; protected $phar; protected $tar; protected $tgz; protected $zip; protected $ext; function __construct($base, $outdirectory = null) { try { $p = new \PharData($base); } catch (\Exception $e) { try { $p = new \Phar($base); } catch (\Exception $ee) { throw $e; } } $this->phar = $p; if ($p->isFileFormat(\Phar::PHAR)) { $this->phar = $p; } elseif ($p->isFileFormat(\Phar::TAR) && !$p->isCompressed()) { $this->tar = $p; } elseif ($p->isFileFormat(\Phar::ZIP)) { $this->zip = $p; } $sig = $p->getSignature(); if ($sig) { $this->hash = $sig['hash']; $this->signature_algo = $sig['hash_type']; } $info = pathinfo($base); $this->file = $info['dirname'] . DIRECTORY_SEPARATOR . $info['filename']; $this->ext = substr($info['filename'], strpos($info['filename'], '.')); if ($outdirectory) { $this->outfile = realpath($outdirectory) . DIRECTORY_SEPARATOR . $info['filename']; copy($base, $this->outfile . '.' . $info['extension']); } } function toTgz() { if (isset($this->tgz)) { return; } if (isset($this->tar)) { if (file_exists($this->file . '.tgz')) { try { $p = new \PharData($this->file . '.tgz'); } catch (\Exception $e) { } if ($p->getSignature() === $this->tar->getSignature()) { $this->tgz = $p; if ($this->outfile) { copy($this->file . '.tgz', $this->outfile . '.tgz'); } return; } unset($p); \Phar::unlinkArchive($this->file . '.tgz'); } $fp = fopen($this->file . '.tar', 'rb'); $gp = gzopen($this->file . '.tgz', 'wb'); stream_copy_to_stream($fp, $gp); fclose($fp); fclose($gp); $this->tgz = new \PharData($this->file . '.tgz'); if ($this->outfile) { copy($this->file . '.tgz', $this->outfile . '.tgz'); } return; } // by process of elimination, the phar is in zip format if (file_exists($this->file . '.tgz')) { \Phar::unlinkArchive($this->file . '.tgz'); unlink($this->file . '.tgz'); } $this->tgz = $this->zip->convertToData(\Phar::TAR, \Phar::GZ, $this->ext . '.tgz'); if ($this->outfile) { copy($this->file . '.tgz', $this->outfile . '.tgz'); } $this->zip = new \PharData($this->file . '.zip'); } function toTar() { if (isset($this->tar)) { return; } if (isset($this->tgz)) { if (file_exists($this->file . '.tar')) { try { $p = new \PharData($this->file . '.tar'); } catch (\Exception $e) { } if ($p->getSignature() === $this->phar->getSignature()) { $this->tar = $p; if ($this->outfile) { copy($this->file . '.tar', $this->outfile . '.tar'); } return; } unset($p); \Phar::unlinkArchive($this->file . '.tar'); } $fp = gzopen($this->file . '.tgz', 'rb'); $gp = fopen($this->file . '.tar', 'wb'); stream_copy_to_stream($fp, $gp); fclose($fp); fclose($gp); $this->tar = new \PharData($this->file . '.tar'); return; } if (isset($this->zip)) { if (file_exists($this->file . '.tar')) { \Phar::unlinkArchive($this->file . '.tar'); } $this->tar = $this->zip->convertToData(\Phar::TAR, \Phar::NONE, $this->ext . '.tar'); $this->tar->setSignatureAlgorithm(\Phar::SHA1); if ($this->outfile) { copy($this->file . '.tar', $this->outfile . '.tar'); } $this->zip = new \PharData($this->file . '.zip'); return; } // by process of elimination, the phar is in phar format if (file_exists($this->file . '.tar')) { \Phar::unlinkArchive($this->file . '.tar'); } $this->tar = $this->phar->convertToData(\Phar::TAR, \Phar::NONE, $this->ext . '.tar'); $this->tar->setSignatureAlgorithm(\Phar::SHA1); if ($this->outfile) { copy($this->file . '.tar', $this->outfile . '.tar'); } $this->phar = new \Phar($this->file . '.phar'); } function toZip() { if (isset($this->zip)) { return; } if (file_exists($this->file . '.zip')) { try { $p = new \PharData($this->file . '.zip'); } catch (\Exception $e) { } if ($p->getMetadata() && is_string($p->getMetadata()) && isset($p[$p->getMetadata()])) { if (isset($this->tar)) { $test = $this->tar; } elseif (isset($this->tgz)) { $test = $this->tgz; } else { $test = $this->phar; } if ($p->getMetadata() === $test->getMetadata()) { try { // do both store the same package.xml and are they // identical package.xml? if ($p[$p->getMetadata()]->getContent() == $test[$p->getMetadata()]->getContent()) { $this->zip = $p; // yes if ($this->outfile) { copy($this->file . '.zip', $this->outfile . '.zip'); } return; } } catch (\Exception $e) { } } } unset($p); \Phar::unlinkArchive($this->file . '.zip'); } if (isset($this->tar)) { if (file_exists($this->file . '.zip')) { \Phar::unlinkArchive($this->file . '.zip'); unlink($this->file . '.zip'); } $this->zip = $this->tar->convertToData(\Phar::ZIP, \Phar::NONE, $this->ext . '.zip'); if ($this->outfile) { copy($this->file . '.zip', $this->outfile . '.zip'); } $this->tar = new \PharData($this->file . '.tar'); return; } if (isset($this->tgz)) { if (file_exists($this->file . '.zip')) { \Phar::unlinkArchive($this->file . '.zip'); unlink($this->file . '.zip'); } $this->zip = $this->tgz->convertToData(\Phar::ZIP, \Phar::NONE, $this->ext . '.zip'); if ($this->outfile) { copy($this->file . '.zip', $this->outfile . '.zip'); } $this->tgz = new \PharData($this->file . '.tgz'); return; } // by process of elimination, the phar is in phar format if (file_exists($this->file . '.zip')) { \Phar::unlinkArchive($this->file . '.zip'); unlink($this->file . '.zip'); } $this->zip = $this->phar->convertToData(\Phar::ZIP, \Phar::NONE, $this->ext . '.zip'); if ($this->outfile) { copy($this->file . '.zip', $this->outfile . '.zip'); } $this->phar = new \Phar($this->file . '.phar'); } function toPhar() { if (isset($this->phar)) { return; } if (file_exists($this->file . '.phar')) { try { $p = new \Phar($this->file . '.phar'); } catch (\Exception $e) { } if ($p->getSignature() === $this->phar->getSignature()) { $this->phar = $p; if ($this->outfile) { copy($this->file . '.phar', $this->outfile . '.phar'); } return; } unset($p); \Phar::unlinkArchive($this->file . '.phar'); } if (isset($this->tar)) { if ($this->signature_algo == \Phar::OPENSSL) { throw new Exception('Cannot create tar archive, signature is OpenSSL, ' . 'you must directly create it using the package command'); } if (file_exists($this->file . '.phar')) { \Phar::unlinkArchive($this->file . '.phar'); unlink($this->file . '.phar'); } $this->phar = $this->tar->convertToExecutable(\Phar::PHAR, \Phar::NONE, $this->ext . '.phar'); if ($this->outfile) { copy($this->file . '.phar', $this->outfile . '.phar'); } $this->tar = new \PharData($this->file . '.tar'); return; } if (isset($this->tgz)) { if ($this->signature_algo == \Phar::OPENSSL) { throw new Exception('Cannot create tar archive, signature is OpenSSL, ' . 'you must directly create it using the package command'); } if (file_exists($this->file . '.phar')) { \Phar::unlinkArchive($this->file . '.phar'); unlink($this->file . '.phar'); } $this->phar = $this->tar->convertToExecutable(\Phar::PHAR, \Phar::NONE, $this->ext . '.phar'); if ($this->outfile) { copy($this->file . '.phar', $this->outfile . '.phar'); } $this->tgz = new \PharData($this->file . '.tgz'); return; } // by process of elimination, the phar is in zip format if (file_exists($this->file . '.phar')) { \Phar::unlinkArchive($this->file . '.phar'); unlink($this->file . '.phar'); } $this->phar = $this->tar->convertToExecutable(\Phar::PHAR, \Phar::NONE, $this->ext . '.phar'); if ($this->outfile) { copy($this->file . '.phar', $this->outfile . '.phar'); } $this->zip = new \PharData($this->file . '.zip'); } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Create packages using provided renderers. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package; class Creator { const VERSION = '@PACKAGE_VERSION@'; private $_creators; private $_handles = array(); protected $prepend; /** * Begin package creation * * @param array|\pear2\Pyrus\Package\ICreator $creators */ function __construct($creators, $pear2ExceptionPath = false, $pear2AutoloadPath = false, $pear2MultiErrorsPath = false) { if (!$pear2ExceptionPath) { if (!($pear2Exception = @fopen('pear2/Exception.php', 'r', true))) { throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/Exception.php, please' . ' pass in the path to the constructor'); } } else { if ($a = realpath($pear2ExceptionPath)) { $pear2ExceptionPath = $a; } if (dirname($pear2ExceptionPath) == dirname($pear2ExceptionPath . 'test')) { $pear2ExceptionPath .= '/'; } if (!($pear2Exception = @fopen($pear2ExceptionPath . 'Exception.php', 'r'))) { throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/Exception.php' . ' in ' . $pear2ExceptionPath); } } if (!$pear2AutoloadPath) { if (!($pear2Autoload = @fopen('pear2/Autoload.php', 'r', true))) { fclose($pear2Exception); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/Autoload.php, please' . ' pass in the path to the constructor'); } } else { if ($a = realpath($pear2AutoloadPath)) { $pear2AutoloadPath = $a; } if (dirname($pear2AutoloadPath) == dirname($pear2AutoloadPath . 'test')) { $pear2AutoloadPath .= '/'; } if (!($pear2Autoload = @fopen($pear2AutoloadPath . 'Autoload.php', 'r'))) { fclose($pear2Exception); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/Autoload.php' . ' in ' . $pear2AutoloadPath); } } if (!$pear2MultiErrorsPath) { if (!($pear2MultiErrors = @fopen('pear2/MultiErrors.php', 'r', true))) { fclose($pear2Exception); fclose($pear2Autoload); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/MultiErrors.php, please' . ' pass in the path to the constructor'); } if (!($pear2MultiErrorsException = @fopen('pear2/MultiErrors/Exception.php', 'r', true))) { fclose($pear2Exception); fclose($pear2Autoload); fclose($pear2MultiErrors); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/MultiErrors/Exception.php, please' . ' pass in the path to the constructor'); } } else { if ($a = realpath($pear2MultiErrorsPath)) { $pear2MultiErrorsPath = $a; } if (dirname($pear2MultiErrorsPath) == dirname($pear2MultiErrorsPath . 'test')) { $pear2MultiErrorsPath .= '/'; } if (!($pear2MultiErrors = @fopen($pear2MultiErrorsPath . 'MultiErrors.php', 'r'))) { fclose($pear2Exception); fclose($pear2Autoload); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/MultiErrors.php' . ' in ' . $pear2MultiErrorsPath . 'MultiErrors.php'); } if (!($pear2MultiErrorsException = @fopen($pear2MultiErrorsPath . 'MultiErrors/Exception.php', 'r'))) { fclose($pear2Exception); fclose($pear2Autoload); fclose($pear2MultiErrors); throw new \pear2\Pyrus\Package\Exception('Cannot locate pear2/MultiErrors/Exception.php' . ' in ' . $pear2MultiErrorsPath . 'MultiErrors/Exception.php'); } } $this->_handles['php/pear2/Autoload.php'] = $pear2Autoload; $this->_handles['php/pear2/MultiErrors.php'] = $pear2MultiErrors; $this->_handles['php/pear2/MultiErrors/Exception.php'] = $pear2MultiErrorsException; $this->_handles['php/pear2/Exception.php'] = $pear2Exception; if ($creators instanceof \pear2\Pyrus\Package\ICreator) { $this->_creators = array($creators); } elseif (is_array($creators)) { foreach ($creators as $creator) { if ($creator instanceof \pear2\Pyrus\Package\ICreator) { continue; } throw new \pear2\Pyrus\Package\Creator\Exception('Invalid ' . 'PEAR2 package creator passed into \pear2\Pyrus\Package\Creator'); } $this->_creators = $creators; } else { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid ' . 'PEAR2 package creator passed into \pear2\Pyrus\Package\Creator'); } } /** * Render packages from the creators passed into the constructor. * * This will take any package source and an array mapping internal * path => file name and create new packages in the formats requested. * * All files in package.xml will have the string @PACKAGE_VERSION@ * automatically replaced with the current package's version * @param \pear2\Pyrus\Package $package * @param array $extrafiles */ function render(\pear2\Pyrus\Package $package, array $extrafiles = array()) { foreach ($this->_creators as $creator) { $creator->init(); } $this->prepend = $prepend = $package->name . '-' . $package->version['release']; if ($package->isNewPackage()) { $packagexml = $prepend . '/.xmlregistry/packages/' . str_replace('/', '!', $package->channel) . '/' . $package->name . '/' . $package->version['release'] . '-info.xml'; } else { if ($package->isOldAndCrustyCompatible()) { $packagexml = 'package2.xml'; $old = file_get_contents('package.xml'); } else { $packagexml = 'package.xml'; } } if (self::VERSION === '@' . 'PACKAGE_VERSION@') { // we're running straight from SVN, so pretend to be 2.0.0 $package->packagerversion = '2.0.0'; } else { $package->packagerversion = self::VERSION; } // get packaging package.xml $packageingstr = (string) new \pear2\Pyrus\XMLWriter($package->toArray(true)); foreach ($this->_creators as $creator) { $creator->addFile($packagexml, $packageingstr); } if ($package->isOldAndCrustyCompatible()) { foreach ($this->_creators as $creator) { $creator->addFile('package.xml', $old); } } if ($package->getInternalPackage() instanceof \pear2\Pyrus\Package\Xml) { // check for package_compatible.xml if ($package->isNewPackage() && file_exists($package->getFilePath('package_compatible.xml'))) { foreach ($this->_creators as $creator) { $creator->addFile('package.xml', file_get_contents($package->getFilePath('package_compatible.xml'))); } } } $packagingloc = \pear2\Pyrus\Config::current()->temp_dir . DIRECTORY_SEPARATOR . 'pyrpackage'; if (file_exists($packagingloc)) { foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($packagingloc, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST) as $file) { if (is_dir($file)) { rmdir($file); } elseif (is_file($file)) { unlink($file); } } } else { mkdir($packagingloc, 0777, true); } // $packageat is the relative path within the archive // $info is an array of format: // array('attribs' => array('name' => ...)[, 'tasks:blah' ...]) $alreadyPackaged = array(); $globalreplace = array('attribs' => array('from' => '@' . 'PACKAGE_VERSION@', 'to' => 'version', 'type' => 'package-info')); foreach ($package->packagingcontents as $packageat => $info) { $role = \pear2\Pyrus\Installer\Role::factory($package->getPackageType(), $info['attribs']['role']); try { $role->packageTimeValidate($package, $info); } catch (\Exception $e) { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid file ' . $packageat . ': ' . $e->getMessage(), $e); } $packageat = str_replace('\\', '/', $packageat); $packageat = str_replace('//', '/', $packageat); if ($packageat[0] === '/' || (strlen($packageat) > 2 && ($packageat[1] === ':' && $packageat[2] == '/'))) { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid path, cannot' . ' save a root path ' . $packageat); } if (preg_match('@^\.\.?/|/\.\.?\\z|/\.\./@', $packageat)) { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid path, cannot' . ' use directory reference . or .. ' . $packageat); } $alreadyPackaged[$packageat] = true; $packageat = $prepend . '/' . $packageat; $contents = $package->getFileContents($info['attribs']['name'], true); if (!file_exists(dirname($packagingloc . DIRECTORY_SEPARATOR . $packageat))) { mkdir(dirname($packagingloc . DIRECTORY_SEPARATOR . $packageat), 0777, true); } $fp = fopen($packagingloc . DIRECTORY_SEPARATOR . $packageat, 'wb+'); ftruncate($fp, 0); stream_copy_to_stream($contents, $fp); fclose($contents); rewind($fp); if ($package->isNewPackage() && $info['attribs']['role'] == 'php') { if (isset($info['tasks:replace'])) { if (isset($info['tasks:replace'][0])) { $info['tasks:replace'][] = $globalreplace; } else { $info['tasks:replace'] = array($info['tasks:replace'], $globalreplace); } } else { $info['tasks:replace'] = $globalreplace; } } if (isset(\pear2\Pyrus\Config::current()->registry->package[$package->channel . '/' . $package->name])) { $version = \pear2\Pyrus\Config::current()->registry->info($package->name, $package->channel, 'version'); } else { $version = null; } foreach (new \pear2\Pyrus\Package\Creator\TaskIterator($info, $package, \pear2\Pyrus\Task\Common::PACKAGE, $version) as $task) { // do pre-processing of file contents try { $task->startSession($fp, $packageat); } catch (\Exception $e) { // TODO: handle exceptions } } fclose($fp); } foreach ($this->_creators as $creator) { $creator->addDir($packagingloc); } if ($package->isNewPackage()) { $this->addPEAR2Stuff($alreadyPackaged); } $this->addExtraFiles($extrafiles); foreach ($this->_creators as $creator) { $creator->close(); } foreach (new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($packagingloc, \RecursiveDirectoryIterator::SKIP_DOTS), \RecursiveIteratorIterator::CHILD_FIRST) as $file) { if (is_dir($file)) { rmdir($file); } elseif (is_file($file)) { unlink($file); } } rmdir($packagingloc); } protected function addPEAR2Stuff($alreadyPackaged) { foreach ($this->_creators as $creator) { $creator->mkdir($this->prepend . '/php/pear2'); } foreach ($this->_handles as $path => $stream) { if (isset($alreadyPackaged[$path])) { continue; // we're packaging this package } foreach ($this->_creators as $creator) { $creator->addFile($this->prepend . '/' . $path, $stream); } fclose($stream); } foreach ($this->_creators as $creator) { if (isset($alreadyPackaged['php/pear2/MultiErrors/Exception.php'])) { continue; // we're packaging MultiErrors package } $creator->mkdir($this->prepend . '/php/pear2/MultiErrors'); $creator->addFile($this->prepend . '/php/pear2/MultiErrors/Exception.php', " $filename) { if (is_object($filename)) { if ($filename instanceof \pear2\Pyrus\Package) { foreach ($filename->packagingcontents as $path => $info) { foreach ($this->_creators as $creator) { $creator->mkdir(dirname($this->prepend . '/' . $path)); $fp = $filename->getFileContents($info['attribs']['name'], true); $creator->addFile($this->prepend . '/' . $path, $fp); fclose($fp); } } continue; } else { throw new Exception('Invalid extra file object, must be ' . 'a \pear2\Pyrus\Package object'); } } $path = str_replace('\\', '/', $path); $path = str_replace('//', '/', $path); if ($path[0] === '/' || (strlen($path) > 2 && ($path[1] === ':' && $path[2] == '/'))) { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid path, cannot' . ' save a root path ' . $path); } if (preg_match('@^\.\.?/|/\.\.?\\z|/\.\./@', $path)) { throw new \pear2\Pyrus\Package\Creator\Exception('Invalid path, cannot' . ' use directory reference . or .. ' . $path); } if (isset($alreadyPackaged[$path])) { throw new \pear2\Pyrus\Package\Creator\Exception('Path ' . $path . 'has already been added, and cannot be overwritten'); } $alreadyPackaged[$path] = true; if (!@file_exists($filename) || !($fp = @fopen($filename, 'rb'))) { throw new \pear2\Pyrus\Package\Creator\Exception('Extra file ' . $filename . ' does not exist or cannot be read'); } foreach ($this->_creators as $creator) { $creator->mkdir(dirname($this->prepend . '/' . $path)); $creator->addFile($this->prepend . '/' . $path, $fp); } fclose($fp); } } } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for Packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package; class Exception extends \pear2\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Interface for a Package creator. * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package; interface ICreator { /** * save a file inside this package * @param string relative path within the package * @param string|resource file contents or open file handle */ function addFile($path, $filename); /** * Add everything within a directory and all subdirectories * @param string path to the directory to add */ function addDir($path); /** * Initialize the package creator */ function init(); /** * Create an internal directory, creating parent directories as needed * @param string $dir */ function mkdir($dir); /** * Finish saving the package */ function close(); } * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ /** * Exception class for installed packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/wsvn/PEARSVN/Pyrus/ */ namespace pear2\Pyrus\Package; class InstalledException extends \pear2\Pyrus\Package\Exception {} * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version SVN: $Id$ * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ /** * Class for phar packages * * @category PEAR2 * @package PEAR2_Pyrus * @author Greg Beaver * @copyright 2008 The PEAR Group * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @link http://svn.pear.php.net/PEAR2/Pyrus/ */ namespace pear2\Pyrus\Package; class Phar extends \pear2\Pyrus\Package\Base { static private $_tempfiles = array(); private $_tmpdir; private $_BCpackage = false; /** * @param string $package path to package file */ function __construct($package, \pear2\Pyrus\Package $parent) { $package = realpath($package); if (!$package) { throw new \pear2\Pyrus\Package\Phar\Exception( 'Phar package ' . $package . ' does not exist'); } if (!class_exists('Phar')) { throw new \pear2\Pyrus\Package\Phar\Exception( 'Phar extension is not available'); } $this->archive = $package; try { if (\Phar::isValidPharFilename($package, 1)) { $phar = new \Phar($package, \RecursiveDirectoryIterator::KEY_AS_FILENAME); $pxml = 'phar://' . $package . '/' . $phar->getMetaData(); } else { $phar = new \PharData($package, \RecursiveDirectoryIterator::KEY_AS_FILENAME); if ($phar->getMetaData()) { $pxml = 'phar://' . $package . '/' . $phar->getMetaData(); } else { $pxml = false; } } } catch (\Exception $e) { throw new \pear2\Pyrus\Package\Phar\Exception('Could not open Phar archive ' . $package, $e); } $package = str_replace('\\', '/', $package); try { if ($pxml === false) { $info = pathinfo($package); $internal = $info['filename']; if (isset($phar[$internal . '/.xmlregistry'])) { if ($phar instanceof \PharData) { $iterate = new \PharData('phar://' . $package . '/' . $internal . '/.xmlregistry'); } else { $iterate = new \Phar('phar://' . $package . '/' . $internal . '/.xmlregistry'); } foreach (new \RecursiveIteratorIterator($iterate, \RecursiveIteratorIterator::LEAVES_ONLY) as $file) { $filename = $file->getFileName(); // default to new package.xml if (preg_match('@^(.+)\-package.xml$@', $filename)) {