<?php
class AppController extends Controller{
var $components = Array ( 'SwiftMailer' , 'Auth' , 'Email' , 'Session' , 'Facebook.Connect' , 'Uploader.Uploader' , 'FormKeeper.FormKeeper' , 'Recaptcha.Captcha' => array ( 'private_key' => '6LcDt8sSAAAAAEnkcMKDiFX1QtIovebWAH9lUDEm' ,
'public_key' => '6LcDt8sSAAAAAHggUKIrTj6zNQx4jkNU0raWlO_Y' ) , 'Cookie' ) ;
var $helpers = array ( 'Html' , 'Form' , 'PaypalIpn.Paypal' , 'Session' , 'Facebook.Facebook' , 'FormKeeper.FormKeeper' , 'Recaptcha.CaptchaTool' ) ; var $uses = array ( 'Reservation' , 'Topic' ) ;
function beforeFilter( ) {
//$this->set('facebook_user', $this->Connect->user());
define ( 'RESERVATION_FEE' , '.12' ) ; $this -> Auth -> allow ( 'signup' , 'validateform' , 'create' , 'display' ) ; // controller actions unauthenticated users have access too, which then renders the view
$this -> Auth -> authError = 'You must have an account to view this page. Please sign in or sign up for an account' ;
$this -> Auth -> loginError = 'Incorrect username/password combination' ;
//debug($this->Auth->user());
$this -> set ( 'searchbar' , 0 ) ;
if ( $this -> Auth -> isAuthorized ( ) )
{
$this -> set ( 'auth' , '1' ) ;
$messages = $this -> Topic -> find ( 'count' , array ( 'conditions' => array ( 'Topic.viewed' => '0' , 'Topic.to_user' => $this -> Auth -> user ( 'id' ) ) ) ) ; $bookings = $this -> Reservation -> find ( 'count' , array ( 'conditions' => array ( 'Reservation.status' => '1' , 'Reservation.host_id' => $this -> Auth -> user ( 'id' ) ) ) ) ; $this -> set ( 'messagesCount' , $messages ) ;
$this -> set ( 'reservationsCount' , $bookings ) ;
}
else {
$this -> set ( 'auth' , '0' ) ;
}
$this -> Auth -> loginRedirect = array ( 'controller' => 'messages' , 'action' => 'mymessages' ) ;
}
function afterPaypalNotification( $txnId ) {
//Here is where you can implement code to apply the transaction to your app.
//for example, you could now mark an order as paid, a subscription, or give the user premium access.
//retrieve the transaction using the txnId passed and apply whatever logic your site needs.
$transaction = ClassRegistry:: init ( 'PaypalIpn.InstantPaymentNotification' ) -> findById ( $txnId ) ;
$this -> log ( $transaction [ 'InstantPaymentNotification' ] [ 'id' ] , 'paypal' ) ;
//Tip: be sure to check the payment_status is complete because failure transactions
// are also saved to our database for review.
if ( $transaction [ 'InstantPaymentNotification' ] [ 'payment_status' ] == 'Pending' && $transaction [ 'InstantPaymentNotification' ] [ 'pending_reason' ] == 'authorization' ) {
$reservationId = $transaction [ 'InstantPaymentNotification' ] [ 'item_number' ] ;
$this -> log ( $reservationId , 'paypal' ) ; $this -> Reservation -> id = $reservationId ;
$reservation = $this -> Reservation -> find ( 'first' , array ( 'Reservation.id' => $reservationId ) ) ;
if ( $transaction [ 'InstantPaymentNotification' ] [ 'mc_gross' ] == $reservation [ 'Reservation' ] [ 'total_amount' ] ) {
$this -> Reservation -> saveField ( 'status' , 1 , array ( 'callbacks' => 'false' , 'validate' => 'false' ) ) ; } else {
$this -> Reservation -> saveField ( 'status' , 4 , array ( 'callbacks' => 'false' , 'validate' => 'false' ) ) ; $this -> sendEmail ( "support@reservationresources.com" , "ID# " . $reservationId . " Payment amounts don't match!" , "payment" ) ;
}
$this -> sendEmail ( "harry@reservationresources.com" , "PAYMENT NOTIFICATION " . $reservationId , "payment" ) ;
}
else {
//Oh no, better look at this transaction to determine what to do; like email a decline letter.
}
}
function _PPHttpPost( $methodName_ , $nvpStr_ ) {
$this -> autoRender = false ;
$environment = 'sandbox' ; // or 'beta-sandbox' or 'live'
// Set up your API credentials, PayPal end point, and API version.
$API_UserName = urlencode ( 'invoice_api1.reservationresources.com' ) ; $API_Password = urlencode ( 'REQ6BD9BD3BHEZB3' ) ; $API_Signature = urlencode ( 'A9Ewuf-6vQ6w3KC6MRDfkJjmvTFgAeDiXfKaIz4nBx1D5tDvq1cSyvCs' ) ;
$API_UserName = urlencode ( 'shahru_1322843474_biz_api1.gmail.com' ) ; $API_Signature = urlencode ( 'AafdLz1r6EWooI64eLNUccpog7G0AxeVDUzI.vjZ.0BI5Ch0mGLGkfBp' ) ;
$API_Endpoint = "https://a...content-available-to-author-only...l.com/nvp" ;
if ( "sandbox" === $environment || "beta-sandbox" === $environment ) {
$API_Endpoint = "https://api-3t.$environment .paypal.com/nvp" ;
}
// Set the curl parameters.
// Turn off the server and peer verification (TrustManager Concept).
// Set the API operation, version, and API signature in the request.
$nvpreq = "METHOD=$methodName_ &VERSION=$version &PWD=$API_Password &USER=$API_UserName &SIGNATURE=$API_Signature $nvpStr_ " ;
// Set the request as a POST FIELD for curl.
// Get response from the server.
if ( ! $httpResponse ) {
}
// Extract the response details.
$httpResponseAr = explode ( "&" , $httpResponse ) ;
$httpParsedResponseAr = array ( ) ; foreach ( $httpResponseAr as $i => $value ) {
$httpParsedResponseAr [ $tmpAr [ 0 ] ] = $tmpAr [ 1 ] ;
}
}
exit ( "Invalid HTTP Response for POST request($nvpreq ) to $API_Endpoint ." ) ; }
return $httpParsedResponseAr ;
/* Set request-specific fields.
$authorizationID = urlencode('example_authorization_id');
$amount = urlencode('example_amount');
$currency = urlencode('USD'); // or other currency ('GBP', 'EUR', 'JPY', 'CAD', 'AUD')
$completeCodeType = urlencode('Complete'); // or 'NotComplete'
$invoiceID = urlencode('example_invoice_id');
$note = urlencode('example_note');
// Add request-specific fields to the request string.
$nvpStr="&AUTHORIZATIONID=$authorizationID&AMT=$amount&COMPLETETYPE=$completeCodeType&CURRENCYCODE=$currency&NOTE=$note";
// Execute the API operation; see the PPHttpPost function above.
$httpParsedResponseAr = PPHttpPost('DoCapture', $nvpStr);
if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])) {
exit('Capture Completed Successfully: '.print_r($httpParsedResponseAr, true));
} else {
exit('DoCapture failed: ' . print_r($httpParsedResponseAr, true));
}
*/
}
function deleteimage( $name = null , $property = null ) { //pick up here image handling 11/29/11
$this -> autoRender = false ;
if ( $this -> Uploader -> delete ( 'user_photos/' . $this -> Auth -> user ( 'id' ) . '/' . $property . '/' . $name ) && $this -> Uploader -> delete ( 'user_photos/' . $this -> Auth -> user ( 'id' ) . '/' . $property . '/resized/' . $name ) ) {
return true ;
}
else {
return false ;
}
}
/*
the following 2 functions adds images to a property.
the reason why i had to create 2 functions is becuase they array come in diffrently
based upon if there adding images for the first time or just adding new images to an already
existing property
*/
function uploadpropertypics( $id = null ) {
$this -> autoRender = false ;
$folder = new Folder( 'user_photos/' . DS. $this -> Auth -> user ( 'id' ) . DS. $id , true ) ;
$resized = new Folder( 'user_photos/' . DS. $this -> Auth -> user ( 'id' ) . DS. $id . DS. 'resized' , true ) ;
$this -> Uploader -> uploadDir = '/user_photos' . DS. $this -> Auth -> user ( 'id' ) . DS. $id . '/' ;
for ( $i = 1 ; $i < count ( $this -> data [ 'Images' ] ) ; $i ++ ) { //debug(count($this->data['Images']));
//debug($this->Uploader->tempDir);
if ( $data = $this -> Uploader -> upload ( 'Images.file' . $i ) ) {
$scale = $this -> Uploader -> resize ( array ( 'width' => 890 , 'append' => 'scaled' , 'quality' => 100 ) ) ; $this -> Uploader -> move ( $scale , 'user_photos/' . $this -> Auth -> user ( 'id' ) . '/' . $id . '/resized/' . $data [ 'name' ] , false ) ;
}
}
}
$this -> redirect ( array ( 'controller' => 'properties' , 'action' => 'viewproperty' , $id ) ) ;
function addphotos( $id = null , $path = null ) {
$this -> autoRender = false ;
$folder = new Folder( 'user_photos/' . DS. $this -> Auth -> user ( 'id' ) . DS. $id , true ) ;
$resized = new Folder( 'user_photos/' . DS. $this -> Auth -> user ( 'id' ) . DS. $id . DS. 'resized' , true ) ;
$this -> Uploader -> uploadDir = $path ;
for ( $i = 1 ; $i < count ( $this -> data [ 'Images' ] ) ; $i ++ ) {
if ( $data = $this -> Uploader -> upload ( 'file' . $i ) ) {
$scale = $this -> Uploader -> scale ( array ( 'width' => 890 , 'append' => 'scaled' ) ) ;
$this -> Uploader -> move ( $scale , 'user_photos/' . DS. $this -> Auth -> user ( 'id' ) . DS. $id . '/resized/' . $data [ 'name' ] , false ) ;
}
}
}
function cleanString( $msg = NULL )
{
preg_match ( "/[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})/i" , $msg , $matches ) ; return false ;
$unclean = "" ;
$k = 0 ;
for ( $i = 0 ; $i < strlen ( $msg ) ; $i ++ ) {
if ( $k < 7 )
{
$k = 0 ;
{
for ( $j = $i ; $j < strlen ( $msg ) ; $j ++ ) {
{
$k ++;
}
else
$k = 0 ;
$i = $j ;
//Pushes the larger for loop to continue where this one left off after checking numbers in a row
}
}
}
else
}
if ( $k < 7 )
return true ;
else
return false ; //UNCLEAN STRING
}
function sendEmail( $email , $subject , $layout ) {
/*$this->Email->reset();
$this->Email->to = $email;
$this->Email->subject = $subject;
$this->Email->replyTo = 'support@reservationresources.com';
$this->Email->from = 'Reservation Resources <noreply@reservationresources.com>';
//debug($this->Email);
$this->Email->template = $layout; // note no '.ctp'
//Send as 'html', 'text' or 'both' (default is 'text')
$this->Email->sendAs = 'html'; // because we like to send pretty mail
//Do not pass any args to send()
$this->Email->send();
ONLY WORKS FOR ONE EMAIL FOR SOME REASON
*/
//Function is copy + pasted in Profiles / verify && Users / forgotpassword && Harries/sendEmail
$this -> SwiftMailer -> smtpType = 'tls' ;
$this -> SwiftMailer -> smtpHost = 'smtp.gmail.com' ;
$this -> SwiftMailer -> smtpPort = 587 ;
$this -> SwiftMailer -> smtpUsername = 'support@reservationresources.com' ;
$this -> SwiftMailer -> smtpPassword = 'hARRY1234%^' ;
$this -> SwiftMailer -> sendAs = 'html' ;
$this -> SwiftMailer -> from = 'support@reservationresources.com' ;
$this -> SwiftMailer -> fromName = 'Support Team' ;
$this -> SwiftMailer -> to = $email ;
//set variables to template as usual
try {
if ( ! $this -> SwiftMailer -> send ( $layout , $subject ) ) {
$this -> log ( "Error sending email" ) ; }
}
catch( Exception $e ) {
$this -> log ( "Failed to send email: " . $e -> getMessage ( ) ) ; }
}
}
?>
PD9waHAKCQpjbGFzcyBBcHBDb250cm9sbGVyIGV4dGVuZHMgQ29udHJvbGxlcnsKCQl2YXIgJGNvbXBvbmVudHMgPSBBcnJheSgnU3dpZnRNYWlsZXInLCAnQXV0aCcsICdFbWFpbCcsICdTZXNzaW9uJywgJ0ZhY2Vib29rLkNvbm5lY3QnLCAnVXBsb2FkZXIuVXBsb2FkZXInLCAnRm9ybUtlZXBlci5Gb3JtS2VlcGVyJywgJ1JlY2FwdGNoYS5DYXB0Y2hhJyA9PiBhcnJheSggCgkJJ3ByaXZhdGVfa2V5JyA9PiAnNkxjRHQ4c1NBQUFBQUVua2NNS0RpRlgxUXRJb3ZlYldBSDlsVURFbScsCgkJJ3B1YmxpY19rZXknID0+ICc2TGNEdDhzU0FBQUFBSGdnVUtJclRqNnpOUXg0amtOVTByYVdsT19ZJyksJ0Nvb2tpZScpOwoJCXZhciAkaGVscGVycyA9IGFycmF5KCdIdG1sJywnRm9ybScsJ1BheXBhbElwbi5QYXlwYWwnLCAnU2Vzc2lvbicsICdGYWNlYm9vay5GYWNlYm9vaycsICdGb3JtS2VlcGVyLkZvcm1LZWVwZXInLCAnUmVjYXB0Y2hhLkNhcHRjaGFUb29sJyk7IAoJCXZhciAkdXNlcyA9IGFycmF5KCdSZXNlcnZhdGlvbicsICdUb3BpYycpOwoJCQoJCWZ1bmN0aW9uIGJlZm9yZUZpbHRlcigpewoJCSAgIAoJCSAgLy8kdGhpcy0+c2V0KCdmYWNlYm9va191c2VyJywgJHRoaXMtPkNvbm5lY3QtPnVzZXIoKSk7CgkKCQkJZGVmaW5lKCdSRVNFUlZBVElPTl9GRUUnLCcuMTInKTsKCQkJJHRoaXMtPkF1dGgtPmFsbG93KCdzaWdudXAnLCd2YWxpZGF0ZWZvcm0nLCdjcmVhdGUnLCdkaXNwbGF5Jyk7Ly8gY29udHJvbGxlciBhY3Rpb25zIHVuYXV0aGVudGljYXRlZCB1c2VycyBoYXZlIGFjY2VzcyB0b28sIHdoaWNoIHRoZW4gcmVuZGVycyB0aGUgdmlldwoJCQkkdGhpcy0+QXV0aC0+YXV0aEVycm9yID0gJ1lvdSBtdXN0IGhhdmUgYW4gYWNjb3VudCB0byB2aWV3IHRoaXMgcGFnZS4gUGxlYXNlIHNpZ24gaW4gb3Igc2lnbiB1cCBmb3IgYW4gYWNjb3VudCc7CgkJCSR0aGlzLT5BdXRoLT5sb2dpbkVycm9yID0gJ0luY29ycmVjdCB1c2VybmFtZS9wYXNzd29yZCBjb21iaW5hdGlvbic7CgkJCS8vZGVidWcoJHRoaXMtPkF1dGgtPnVzZXIoKSk7CgkJCSR0aGlzLT5zZXQoJ3NlYXJjaGJhcicsMCk7CgkJCWlmKCR0aGlzLT5BdXRoLT5pc0F1dGhvcml6ZWQoKSkKCQkJewoJCQkJJHRoaXMtPnNldCgnYXV0aCcsJzEnKTsKCQkJCSRtZXNzYWdlcyA9ICR0aGlzLT5Ub3BpYy0+ZmluZCgnY291bnQnLCBhcnJheSgnY29uZGl0aW9ucycgPT4gYXJyYXkoJ1RvcGljLnZpZXdlZCcgPT4gJzAnLCAnVG9waWMudG9fdXNlcic9PiR0aGlzLT5BdXRoLT51c2VyKCdpZCcpKSkpOwoJCQkJJGJvb2tpbmdzID0gJHRoaXMtPlJlc2VydmF0aW9uLT5maW5kKCdjb3VudCcsIGFycmF5KCdjb25kaXRpb25zJyA9PiBhcnJheSgnUmVzZXJ2YXRpb24uc3RhdHVzJyA9PiAnMScsICdSZXNlcnZhdGlvbi5ob3N0X2lkJz0+JHRoaXMtPkF1dGgtPnVzZXIoJ2lkJykpKSk7CgkJCQkkdGhpcy0+c2V0KCdtZXNzYWdlc0NvdW50JywgJG1lc3NhZ2VzKTsKCQkJCSR0aGlzLT5zZXQoJ3Jlc2VydmF0aW9uc0NvdW50JywgJGJvb2tpbmdzKTsKCQkJCQoJCQl9CgkJCWVsc2V7CgkJCQkkdGhpcy0+c2V0KCdhdXRoJywnMCcpOwoJCQl9CgkJCQkkdGhpcy0+QXV0aC0+bG9naW5SZWRpcmVjdCA9IGFycmF5KCdjb250cm9sbGVyJyA9PiAnbWVzc2FnZXMnLCAnYWN0aW9uJyA9PiAnbXltZXNzYWdlcycpOwoJCQoJCQkKCQkJfQoJCQoJCQoJCSAgZnVuY3Rpb24gYWZ0ZXJQYXlwYWxOb3RpZmljYXRpb24oJHR4bklkKXsgCiAgICAvL0hlcmUgaXMgd2hlcmUgeW91IGNhbiBpbXBsZW1lbnQgY29kZSB0byBhcHBseSB0aGUgdHJhbnNhY3Rpb24gdG8geW91ciBhcHAuIAogICAgLy9mb3IgZXhhbXBsZSwgeW91IGNvdWxkIG5vdyBtYXJrIGFuIG9yZGVyIGFzIHBhaWQsIGEgc3Vic2NyaXB0aW9uLCBvciBnaXZlIHRoZSB1c2VyIHByZW1pdW0gYWNjZXNzLiAKICAgIC8vcmV0cmlldmUgdGhlIHRyYW5zYWN0aW9uIHVzaW5nIHRoZSB0eG5JZCBwYXNzZWQgYW5kIGFwcGx5IHdoYXRldmVyIGxvZ2ljIHlvdXIgc2l0ZSBuZWVkcy4gCiAgICAgCiAgICAkdHJhbnNhY3Rpb24gPSBDbGFzc1JlZ2lzdHJ5Ojppbml0KCdQYXlwYWxJcG4uSW5zdGFudFBheW1lbnROb3RpZmljYXRpb24nKS0+ZmluZEJ5SWQoJHR4bklkKTsgCiAgICAkdGhpcy0+bG9nKCR0cmFuc2FjdGlvblsnSW5zdGFudFBheW1lbnROb3RpZmljYXRpb24nXVsnaWQnXSwgJ3BheXBhbCcpOyAKCiAgICAvL1RpcDogYmUgc3VyZSB0byBjaGVjayB0aGUgcGF5bWVudF9zdGF0dXMgaXMgY29tcGxldGUgYmVjYXVzZSBmYWlsdXJlIHRyYW5zYWN0aW9ucyAgCiAgICAvLyAgICAgYXJlIGFsc28gc2F2ZWQgdG8gb3VyIGRhdGFiYXNlIGZvciByZXZpZXcuIAoKICAgIGlmKCR0cmFuc2FjdGlvblsnSW5zdGFudFBheW1lbnROb3RpZmljYXRpb24nXVsncGF5bWVudF9zdGF0dXMnXSA9PSAnUGVuZGluZycgJiYgJHRyYW5zYWN0aW9uWydJbnN0YW50UGF5bWVudE5vdGlmaWNhdGlvbiddWydwZW5kaW5nX3JlYXNvbiddID09ICdhdXRob3JpemF0aW9uJyl7IAogICAgICAgICRyZXNlcnZhdGlvbklkID0gJHRyYW5zYWN0aW9uWydJbnN0YW50UGF5bWVudE5vdGlmaWNhdGlvbiddWydpdGVtX251bWJlciddOwkKCQkgJHRoaXMtPmxvZygkcmVzZXJ2YXRpb25JZCwgJ3BheXBhbCcpOyAKCQkkdGhpcy0+UmVzZXJ2YXRpb24tPmlkID0gJHJlc2VydmF0aW9uSWQ7CgkJCgkJJHJlc2VydmF0aW9uID0gJHRoaXMtPlJlc2VydmF0aW9uLT5maW5kKCdmaXJzdCcsIGFycmF5KCdSZXNlcnZhdGlvbi5pZCcgPT4gJHJlc2VydmF0aW9uSWQpKTsKCQkKCQlpZigkdHJhbnNhY3Rpb25bJ0luc3RhbnRQYXltZW50Tm90aWZpY2F0aW9uJ11bJ21jX2dyb3NzJ10gPT0gJHJlc2VydmF0aW9uWydSZXNlcnZhdGlvbiddWyd0b3RhbF9hbW91bnQnXSl7CgkJCSR0aGlzLT5SZXNlcnZhdGlvbi0+c2F2ZUZpZWxkKCdzdGF0dXMnLCAxLCBhcnJheSgnY2FsbGJhY2tzJyA9PiAnZmFsc2UnLCAndmFsaWRhdGUnID0+ICdmYWxzZScpKTsKCQl9ZWxzZXsKCQkJJHRoaXMtPlJlc2VydmF0aW9uLT5zYXZlRmllbGQoJ3N0YXR1cycsIDQsIGFycmF5KCdjYWxsYmFja3MnID0+ICdmYWxzZScsICd2YWxpZGF0ZScgPT4gJ2ZhbHNlJykpOwoJCQkkdGhpcy0+c2VuZEVtYWlsKCJzdXBwb3J0QHJlc2VydmF0aW9ucmVzb3VyY2VzLmNvbSIsICJJRCMgIi4kcmVzZXJ2YXRpb25JZC4iIFBheW1lbnQgYW1vdW50cyBkb24ndCBtYXRjaCEiLCAicGF5bWVudCIpOwoJCX0KCQkkdGhpcy0+c2VuZEVtYWlsKCJoYXJyeUByZXNlcnZhdGlvbnJlc291cmNlcy5jb20iLCAiUEFZTUVOVCBOT1RJRklDQVRJT04gIi4kcmVzZXJ2YXRpb25JZCwgInBheW1lbnQiKTsKICAgIH0gCiAgICBlbHNlIHsgCiAgICAgIC8vT2ggbm8sIGJldHRlciBsb29rIGF0IHRoaXMgdHJhbnNhY3Rpb24gdG8gZGV0ZXJtaW5lIHdoYXQgdG8gZG87IGxpa2UgZW1haWwgYSBkZWNsaW5lIGxldHRlci4gCiAgICB9IAogIH0gCiAgCiAgCWZ1bmN0aW9uIF9QUEh0dHBQb3N0KCRtZXRob2ROYW1lXywgJG52cFN0cl8pIHsKCQkkdGhpcy0+YXV0b1JlbmRlciA9IGZhbHNlOwoJCSRlbnZpcm9ubWVudCA9ICdzYW5kYm94JzsJLy8gb3IgJ2JldGEtc2FuZGJveCcgb3IgJ2xpdmUnCgkJLy8gU2V0IHVwIHlvdXIgQVBJIGNyZWRlbnRpYWxzLCBQYXlQYWwgZW5kIHBvaW50LCBhbmQgQVBJIHZlcnNpb24uCgkJJEFQSV9Vc2VyTmFtZSA9IHVybGVuY29kZSgnaW52b2ljZV9hcGkxLnJlc2VydmF0aW9ucmVzb3VyY2VzLmNvbScpOwoJCSRBUElfUGFzc3dvcmQgPSB1cmxlbmNvZGUoJ1JFUTZCRDlCRDNCSEVaQjMnKTsKCQkkQVBJX1NpZ25hdHVyZSA9IHVybGVuY29kZSgnQTlFd3VmLTZ2UTZ3M0tDNk1SRGZrSmptdlRGZ0FlRGlYZkthSXo0bkJ4MUQ1dER2cTFjU3l2Q3MnKTsKCQoJCSRBUElfVXNlck5hbWUgPSB1cmxlbmNvZGUoJ3NoYWhydV8xMzIyODQzNDc0X2Jpel9hcGkxLmdtYWlsLmNvbScpOwoJCSRBUElfUGFzc3dvcmQgPSB1cmxlbmNvZGUoJzEzMjI4NDM1MjAnKTsKCQkkQVBJX1NpZ25hdHVyZSA9IHVybGVuY29kZSgnQWFmZEx6MXI2RVdvb0k2NGVMTlVjY3BvZzdHMEF4ZVZEVXpJLnZqWi4wQkk1Q2gwbUdMR2tmQnAnKTsKCQkKCQkkQVBJX0VuZHBvaW50ID0gImh0dHBzOi8vYS4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4ubC5jb20vbnZwIjsKCQlpZigic2FuZGJveCIgPT09ICRlbnZpcm9ubWVudCB8fCAiYmV0YS1zYW5kYm94IiA9PT0gJGVudmlyb25tZW50KSB7CgkJCSRBUElfRW5kcG9pbnQgPSAiaHR0cHM6Ly9hcGktM3QuJGVudmlyb25tZW50LnBheXBhbC5jb20vbnZwIjsKCQl9CgkJJHZlcnNpb24gPSB1cmxlbmNvZGUoJzUxLjAnKTsKCgkJLy8gU2V0IHRoZSBjdXJsIHBhcmFtZXRlcnMuCgkJJGNoID0gY3VybF9pbml0KCk7CgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1VSTCwgJEFQSV9FbmRwb2ludCk7CgkJY3VybF9zZXRvcHQoJGNoLCBDVVJMT1BUX1ZFUkJPU0UsIDEpOwoKCQkvLyBUdXJuIG9mZiB0aGUgc2VydmVyIGFuZCBwZWVyIHZlcmlmaWNhdGlvbiAoVHJ1c3RNYW5hZ2VyIENvbmNlcHQpLgoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9TU0xfVkVSSUZZUEVFUiwgRkFMU0UpOwoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9TU0xfVkVSSUZZSE9TVCwgRkFMU0UpOwoKCQljdXJsX3NldG9wdCgkY2gsIENVUkxPUFRfUkVUVVJOVFJBTlNGRVIsIDEpOwoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9QT1NULCAxKTsKCgkJLy8gU2V0IHRoZSBBUEkgb3BlcmF0aW9uLCB2ZXJzaW9uLCBhbmQgQVBJIHNpZ25hdHVyZSBpbiB0aGUgcmVxdWVzdC4KCQkkbnZwcmVxID0gIk1FVEhPRD0kbWV0aG9kTmFtZV8mVkVSU0lPTj0kdmVyc2lvbiZQV0Q9JEFQSV9QYXNzd29yZCZVU0VSPSRBUElfVXNlck5hbWUmU0lHTkFUVVJFPSRBUElfU2lnbmF0dXJlJG52cFN0cl8iOwoKCQkvLyBTZXQgdGhlIHJlcXVlc3QgYXMgYSBQT1NUIEZJRUxEIGZvciBjdXJsLgoJCWN1cmxfc2V0b3B0KCRjaCwgQ1VSTE9QVF9QT1NURklFTERTLCAkbnZwcmVxKTsKCgkJLy8gR2V0IHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlci4KCQkkaHR0cFJlc3BvbnNlID0gY3VybF9leGVjKCRjaCk7CgoJCWlmKCEkaHR0cFJlc3BvbnNlKSB7CgkJCWV4aXQoIiRtZXRob2ROYW1lXyBmYWlsZWQ6ICIuY3VybF9lcnJvcigkY2gpLicoJy5jdXJsX2Vycm5vKCRjaCkuJyknKTsKCQl9CgoJCS8vIEV4dHJhY3QgdGhlIHJlc3BvbnNlIGRldGFpbHMuCgkJJGh0dHBSZXNwb25zZUFyID0gZXhwbG9kZSgiJiIsICRodHRwUmVzcG9uc2UpOwoKCQkkaHR0cFBhcnNlZFJlc3BvbnNlQXIgPSBhcnJheSgpOwoJCWZvcmVhY2ggKCRodHRwUmVzcG9uc2VBciBhcyAkaSA9PiAkdmFsdWUpIHsKCQkJJHRtcEFyID0gZXhwbG9kZSgiPSIsICR2YWx1ZSk7CgkJCWlmKHNpemVvZigkdG1wQXIpID4gMSkgewoJCQkJJGh0dHBQYXJzZWRSZXNwb25zZUFyWyR0bXBBclswXV0gPSAkdG1wQXJbMV07CgkJCX0KCQl9CgoJCWlmKCgwID09IHNpemVvZigkaHR0cFBhcnNlZFJlc3BvbnNlQXIpKSB8fCAhYXJyYXlfa2V5X2V4aXN0cygnQUNLJywgJGh0dHBQYXJzZWRSZXNwb25zZUFyKSkgewoJCQlleGl0KCJJbnZhbGlkIEhUVFAgUmVzcG9uc2UgZm9yIFBPU1QgcmVxdWVzdCgkbnZwcmVxKSB0byAkQVBJX0VuZHBvaW50LiIpOwoJCX0KCgkJcmV0dXJuICRodHRwUGFyc2VkUmVzcG9uc2VBcjsKCQkKCQkvKiBTZXQgcmVxdWVzdC1zcGVjaWZpYyBmaWVsZHMuCgkJCSRhdXRob3JpemF0aW9uSUQgPSB1cmxlbmNvZGUoJ2V4YW1wbGVfYXV0aG9yaXphdGlvbl9pZCcpOwoJCQkkYW1vdW50ID0gdXJsZW5jb2RlKCdleGFtcGxlX2Ftb3VudCcpOwoJCQkkY3VycmVuY3kgPSB1cmxlbmNvZGUoJ1VTRCcpOwkJCQkJCQkvLyBvciBvdGhlciBjdXJyZW5jeSAoJ0dCUCcsICdFVVInLCAnSlBZJywgJ0NBRCcsICdBVUQnKQoJCQkkY29tcGxldGVDb2RlVHlwZSA9IHVybGVuY29kZSgnQ29tcGxldGUnKTsJCQkJLy8gb3IgJ05vdENvbXBsZXRlJwoJCQkkaW52b2ljZUlEID0gdXJsZW5jb2RlKCdleGFtcGxlX2ludm9pY2VfaWQnKTsKCQkJJG5vdGUgPSB1cmxlbmNvZGUoJ2V4YW1wbGVfbm90ZScpOwoKCQkJLy8gQWRkIHJlcXVlc3Qtc3BlY2lmaWMgZmllbGRzIHRvIHRoZSByZXF1ZXN0IHN0cmluZy4KCQkJJG52cFN0cj0iJkFVVEhPUklaQVRJT05JRD0kYXV0aG9yaXphdGlvbklEJkFNVD0kYW1vdW50JkNPTVBMRVRFVFlQRT0kY29tcGxldGVDb2RlVHlwZSZDVVJSRU5DWUNPREU9JGN1cnJlbmN5Jk5PVEU9JG5vdGUiOwoKCQkJLy8gRXhlY3V0ZSB0aGUgQVBJIG9wZXJhdGlvbjsgc2VlIHRoZSBQUEh0dHBQb3N0IGZ1bmN0aW9uIGFib3ZlLgoJCQkkaHR0cFBhcnNlZFJlc3BvbnNlQXIgPSBQUEh0dHBQb3N0KCdEb0NhcHR1cmUnLCAkbnZwU3RyKTsKCgkJCWlmKCJTVUNDRVNTIiA9PSBzdHJ0b3VwcGVyKCRodHRwUGFyc2VkUmVzcG9uc2VBclsiQUNLIl0pIHx8ICJTVUNDRVNTV0lUSFdBUk5JTkciID09IHN0cnRvdXBwZXIoJGh0dHBQYXJzZWRSZXNwb25zZUFyWyJBQ0siXSkpIHsKCQkJCWV4aXQoJ0NhcHR1cmUgQ29tcGxldGVkIFN1Y2Nlc3NmdWxseTogJy5wcmludF9yKCRodHRwUGFyc2VkUmVzcG9uc2VBciwgdHJ1ZSkpOwoJCQl9IGVsc2UgIHsKCQkJCWV4aXQoJ0RvQ2FwdHVyZSBmYWlsZWQ6ICcgLiBwcmludF9yKCRodHRwUGFyc2VkUmVzcG9uc2VBciwgdHJ1ZSkpOwoJCQl9CgkJKi8KCX0KICAKICAJCQoJCWZ1bmN0aW9uIGRlbGV0ZWltYWdlKCRuYW1lID0gbnVsbCwgJHByb3BlcnR5ICA9IG51bGwpey8vcGljayB1cCBoZXJlIGltYWdlIGhhbmRsaW5nIDExLzI5LzExCgkJCSR0aGlzLT5hdXRvUmVuZGVyID0gZmFsc2U7CgkJCQoJCQlpZigkdGhpcy0+VXBsb2FkZXItPmRlbGV0ZSgndXNlcl9waG90b3MvJy4kdGhpcy0+QXV0aC0+dXNlcignaWQnKS4nLycuJHByb3BlcnR5LicvJy4kbmFtZSkmJiR0aGlzLT5VcGxvYWRlci0+ZGVsZXRlKCd1c2VyX3Bob3Rvcy8nLiR0aGlzLT5BdXRoLT51c2VyKCdpZCcpLicvJy4kcHJvcGVydHkuJy9yZXNpemVkLycuJG5hbWUpKXsKCQkJCXJldHVybiAgdHJ1ZTsKCQkJCgkJCX0KCQkJZWxzZXsKCQkJCXJldHVybiBmYWxzZTsKCQkJfQoJCQkKCQkKCQl9Ci8qCnRoZSBmb2xsb3dpbmcgMiBmdW5jdGlvbnMgYWRkcyBpbWFnZXMgdG8gYSBwcm9wZXJ0eS4KdGhlIHJlYXNvbiB3aHkgaSBoYWQgdG8gY3JlYXRlIDIgZnVuY3Rpb25zIGlzIGJlY3Vhc2UgdGhleSBhcnJheSBjb21lIGluIGRpZmZyZW50bHkKYmFzZWQgdXBvbiBpZiB0aGVyZSBhZGRpbmcgaW1hZ2VzIGZvciB0aGUgZmlyc3QgdGltZSBvciBqdXN0IGFkZGluZyBuZXcgaW1hZ2VzIHRvIGFuIGFscmVhZHkKZXhpc3RpbmcgcHJvcGVydHkKKi8KCWZ1bmN0aW9uIHVwbG9hZHByb3BlcnR5cGljcygkaWQgPSBudWxsKXsKCQkJCQoJCQkJJHRoaXMtPmF1dG9SZW5kZXIgID0gZmFsc2U7CgkJCQkkZm9sZGVyID0gbmV3IEZvbGRlcigndXNlcl9waG90b3MvJy5EUy4kdGhpcy0+QXV0aC0+dXNlcignaWQnKS5EUy4kaWQsdHJ1ZSk7CgkJCQkkcmVzaXplZCAgPSBuZXcgRm9sZGVyKCd1c2VyX3Bob3Rvcy8nLkRTLiR0aGlzLT5BdXRoLT51c2VyKCdpZCcpLkRTLiRpZC5EUy4ncmVzaXplZCcsdHJ1ZSk7CgkJCQkkdGhpcy0+VXBsb2FkZXItPnVwbG9hZERpciA9ICcvdXNlcl9waG90b3MnLkRTLiR0aGlzLT5BdXRoLT51c2VyKCdpZCcpLkRTLiRpZC4nLyc7CgkJCQkJCgkJCQlmb3IoJGkgPSAxOyAkaSA8IGNvdW50KCR0aGlzLT5kYXRhWydJbWFnZXMnXSk7JGkrKyl7CgkJCQkvL2RlYnVnKGNvdW50KCR0aGlzLT5kYXRhWydJbWFnZXMnXSkpOwoJCQkJIC8vZGVidWcoJHRoaXMtPlVwbG9hZGVyLT50ZW1wRGlyKTsKCQkJCQkJaWYgKCRkYXRhID0gJHRoaXMtPlVwbG9hZGVyLT51cGxvYWQoJ0ltYWdlcy5maWxlJy4kaSkpewoJCQkJCQkJCgkJCQkJCQkkc2NhbGUgPSAkdGhpcy0+VXBsb2FkZXItPnJlc2l6ZShhcnJheSgnd2lkdGgnID0+IDg5MCwgJ2FwcGVuZCcgPT4gJ3NjYWxlZCcsJ3F1YWxpdHknPT4xMDApKTsKCQkJCQkJCSR0aGlzLT5VcGxvYWRlci0+bW92ZSgkc2NhbGUsICd1c2VyX3Bob3Rvcy8nLiR0aGlzLT5BdXRoLT51c2VyKCdpZCcpLicvJy4kaWQuJy9yZXNpemVkLycuJGRhdGFbJ25hbWUnXSxmYWxzZSk7CgkJCQkJCQl9CgkJCQkJCgkJCQkJfQoJCQkJCgkJCQl9CgkJCQkKCQkkdGhpcy0+cmVkaXJlY3QoYXJyYXkoJ2NvbnRyb2xsZXInID0+ICdwcm9wZXJ0aWVzJywgJ2FjdGlvbicgPT4gJ3ZpZXdwcm9wZXJ0eScsJGlkKSk7CQoJCgkJZnVuY3Rpb24gYWRkcGhvdG9zKCRpZCA9IG51bGwsJHBhdGggPSBudWxsKXsKCQkKCQkJCSR0aGlzLT5hdXRvUmVuZGVyICA9IGZhbHNlOwoJCQkJJGZvbGRlciA9IG5ldyBGb2xkZXIoJ3VzZXJfcGhvdG9zLycuRFMuJHRoaXMtPkF1dGgtPnVzZXIoJ2lkJykuRFMuJGlkLHRydWUpOwoJCQkJJHJlc2l6ZWQgID0gbmV3IEZvbGRlcigndXNlcl9waG90b3MvJy5EUy4kdGhpcy0+QXV0aC0+dXNlcignaWQnKS5EUy4kaWQuRFMuJ3Jlc2l6ZWQnLHRydWUpOwoJCQkJJHRoaXMtPlVwbG9hZGVyLT51cGxvYWREaXIgPSAkcGF0aDsKCQkJCQoJCQkKCQkJCQoJCQkJZm9yKCRpID0gMTsgJGkgPCBjb3VudCgkdGhpcy0+ZGF0YVsnSW1hZ2VzJ10pOyRpKyspewoJCQkJCQkKCQkJCQkJCgkJCQkJCWlmICgkZGF0YSA9ICR0aGlzLT5VcGxvYWRlci0+dXBsb2FkKCdmaWxlJy4kaSkpIHsKCQkJCQkJJHNjYWxlID0gJHRoaXMtPlVwbG9hZGVyLT5zY2FsZShhcnJheSgnd2lkdGgnID0+IDg5MCwgJ2FwcGVuZCcgPT4gJ3NjYWxlZCcpKTsKCQkJCQkKCQkJCQkJJHRoaXMtPlVwbG9hZGVyLT5tb3ZlKCRzY2FsZSwgJ3VzZXJfcGhvdG9zLycuRFMuJHRoaXMtPkF1dGgtPnVzZXIoJ2lkJykuRFMuJGlkLicvcmVzaXplZC8nLiRkYXRhWyduYW1lJ10sZmFsc2UpOwoJCQkJCgkJCQkJCX0KCQkJCQkJCgkJCQl9CgkJCQoJfQoJCglmdW5jdGlvbiBjbGVhblN0cmluZygkbXNnID0gTlVMTCkKCXsKCQlwcmVnX21hdGNoKCIvW19hLXowLTktXSsoXC5bX2EtejAtOS1dKykqQFthLXowLTktXSsoXC5bYS16MC05LV0rKSooXC5bYS16XXsyLDN9KS9pIiwgJG1zZywgJG1hdGNoZXMpOwoJCWlmKCFlbXB0eSgkbWF0Y2hlcykpCgkJCXJldHVybiBmYWxzZTsKCQkkbXNnID0gIHByZWdfcmVwbGFjZSggIi9bXmEtekEtWjAtOV0vaSIsICIiLCAkbXNnKTsKCQkkbXNnID0gc3RyaXBfdGFncygkbXNnKTsKCQkkdW5jbGVhbiA9ICIiOwoKCQkkayA9IDA7CgkJZm9yKCRpID0gMDsgJGkgPCBzdHJsZW4oJG1zZyk7ICRpKyspCgkJewoJCQlpZigkazw3KQoJCQl7CgkJCQkkayA9IDA7CgkJCQlpZihpc19udW1lcmljKHN1YnN0cigkbXNnLCAkaSwgMSkpKQoJCQkJewoJCQkJCWZvcigkaiA9ICRpOyAkaiA8IHN0cmxlbigkbXNnKTsgJGorKykKCQkJCQl7CgkJCQkJCWlmKGlzX251bWVyaWMoc3Vic3RyKCRtc2csICRqLCAxKSkpCgkJCQkJCXsKCQkJCQkJCSRrKys7CgkJCQkJCX0KCQkJCQkJZWxzZQoJCQkJCQkJJGsgPSAwOwoJCQkJCQkKCQkJCQkJJGkgPSAkajsKCQkJCQkJLy9QdXNoZXMgdGhlIGxhcmdlciBmb3IgbG9vcCB0byBjb250aW51ZSB3aGVyZSB0aGlzIG9uZSBsZWZ0IG9mZiBhZnRlciBjaGVja2luZyBudW1iZXJzIGluIGEgcm93CgkJCQkJfQoJCQkJCQoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJCSRpID0gc3RybGVuKCRtc2cpOwoJCQkKCQl9CgkJCgkJaWYoJGs8NykKCQkJcmV0dXJuIHRydWU7CgkJZWxzZQoJCQlyZXR1cm4gZmFsc2U7IC8vVU5DTEVBTiBTVFJJTkcKCX0KCiAKCWZ1bmN0aW9uIHNlbmRFbWFpbCgkZW1haWwsICRzdWJqZWN0LCAkbGF5b3V0KSB7CgkvKiR0aGlzLT5FbWFpbC0+cmVzZXQoKTsKICAgICR0aGlzLT5FbWFpbC0+dG8gPSAkZW1haWw7CiAgICAkdGhpcy0+RW1haWwtPnN1YmplY3QgPSAkc3ViamVjdDsKICAgICR0aGlzLT5FbWFpbC0+cmVwbHlUbyA9ICdzdXBwb3J0QHJlc2VydmF0aW9ucmVzb3VyY2VzLmNvbSc7CiAgICAkdGhpcy0+RW1haWwtPmZyb20gPSAnUmVzZXJ2YXRpb24gUmVzb3VyY2VzIDxub3JlcGx5QHJlc2VydmF0aW9ucmVzb3VyY2VzLmNvbT4nOwoJLy9kZWJ1ZygkdGhpcy0+RW1haWwpOwogICAgJHRoaXMtPkVtYWlsLT50ZW1wbGF0ZSA9ICRsYXlvdXQ7IC8vIG5vdGUgbm8gJy5jdHAnCiAgICAvL1NlbmQgYXMgJ2h0bWwnLCAndGV4dCcgb3IgJ2JvdGgnIChkZWZhdWx0IGlzICd0ZXh0JykKICAgICR0aGlzLT5FbWFpbC0+c2VuZEFzID0gJ2h0bWwnOyAvLyBiZWNhdXNlIHdlIGxpa2UgdG8gc2VuZCBwcmV0dHkgbWFpbAogICAgLy9EbyBub3QgcGFzcyBhbnkgYXJncyB0byBzZW5kKCkKICAgICR0aGlzLT5FbWFpbC0+c2VuZCgpOyAKCQoJT05MWSBXT1JLUyBGT1IgT05FIEVNQUlMIEZPUiBTT01FIFJFQVNPTgoJKi8KCQkvL0Z1bmN0aW9uIGlzIGNvcHkgKyBwYXN0ZWQgaW4gUHJvZmlsZXMgLyB2ZXJpZnkgJiYgVXNlcnMgLyBmb3Jnb3RwYXNzd29yZCAmJiBIYXJyaWVzL3NlbmRFbWFpbAoJCSR0aGlzLT5Td2lmdE1haWxlci0+c210cFR5cGUgPSAndGxzJzsgCiAgICAgICAgJHRoaXMtPlN3aWZ0TWFpbGVyLT5zbXRwSG9zdCA9ICdzbXRwLmdtYWlsLmNvbSc7IAogICAgICAgICR0aGlzLT5Td2lmdE1haWxlci0+c210cFBvcnQgPSA1ODc7IAogICAgICAgICR0aGlzLT5Td2lmdE1haWxlci0+c210cFVzZXJuYW1lID0gJ3N1cHBvcnRAcmVzZXJ2YXRpb25yZXNvdXJjZXMuY29tJzsgCiAgICAgICAgJHRoaXMtPlN3aWZ0TWFpbGVyLT5zbXRwUGFzc3dvcmQgPSAnaEFSUlkxMjM0JV4nOyAKCiAgICAgICAgJHRoaXMtPlN3aWZ0TWFpbGVyLT5zZW5kQXMgPSAnaHRtbCc7IAogICAgICAgICR0aGlzLT5Td2lmdE1haWxlci0+ZnJvbSA9ICdzdXBwb3J0QHJlc2VydmF0aW9ucmVzb3VyY2VzLmNvbSc7IAogICAgICAgICR0aGlzLT5Td2lmdE1haWxlci0+ZnJvbU5hbWUgPSAnU3VwcG9ydCBUZWFtJzsgCiAgICAgICAgJHRoaXMtPlN3aWZ0TWFpbGVyLT50byA9ICRlbWFpbDsgCiAgICAgICAgLy9zZXQgdmFyaWFibGVzIHRvIHRlbXBsYXRlIGFzIHVzdWFsIAogICAgICAgIHRyeSB7IAogICAgICAgICAgICBpZighJHRoaXMtPlN3aWZ0TWFpbGVyLT5zZW5kKCRsYXlvdXQsICRzdWJqZWN0KSkgeyAKICAgICAgICAgICAgICAgICR0aGlzLT5sb2coIkVycm9yIHNlbmRpbmcgZW1haWwiKTsgCiAgICAgICAgICAgIH0gCiAgICAgICAgfSAKICAgICAgICBjYXRjaChFeGNlcHRpb24gJGUpIHsgCiAgICAgICAgICAgICAgJHRoaXMtPmxvZygiRmFpbGVkIHRvIHNlbmQgZW1haWw6ICIuJGUtPmdldE1lc3NhZ2UoKSk7IAogICAgICAgIH0gCgoJIH0JCgkKfQo/Pg==