first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
define("paygw_paypal/gateways_modal",["exports","./repository","core/templates","core/truncate","core/modal","core/modal_events","core/str"],(function(_exports,Repository,_templates,_truncate,_modal,_modal_events,_str){function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj}}function _getRequireWildcardCache(nodeInterop){if("function"!=typeof WeakMap)return null;var cacheBabelInterop=new WeakMap,cacheNodeInterop=new WeakMap;return(_getRequireWildcardCache=function(nodeInterop){return nodeInterop?cacheNodeInterop:cacheBabelInterop})(nodeInterop)}Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.process=void 0,Repository=function(obj,nodeInterop){if(!nodeInterop&&obj&&obj.__esModule)return obj;if(null===obj||"object"!=typeof obj&&"function"!=typeof obj)return{default:obj};var cache=_getRequireWildcardCache(nodeInterop);if(cache&&cache.has(obj))return cache.get(obj);var newObj={},hasPropertyDescriptor=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var key in obj)if("default"!==key&&Object.prototype.hasOwnProperty.call(obj,key)){var desc=hasPropertyDescriptor?Object.getOwnPropertyDescriptor(obj,key):null;desc&&(desc.get||desc.set)?Object.defineProperty(newObj,key,desc):newObj[key]=obj[key]}newObj.default=obj,cache&&cache.set(obj,newObj);return newObj}
/**
* This module is responsible for PayPal content in the gateways modal.
*
* @module paygw_paypal/gateways_modal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/(Repository),_templates=_interopRequireDefault(_templates),_truncate=_interopRequireDefault(_truncate),_modal=_interopRequireDefault(_modal),_modal_events=_interopRequireDefault(_modal_events);const showModalWithPlaceholder=async()=>await _modal.default.create({body:await _templates.default.render("paygw_paypal/paypal_button_placeholder",{}),show:!0,removeOnClose:!0});_exports.process=(component,paymentArea,itemId,description)=>Promise.all([showModalWithPlaceholder(),Repository.getConfigForJs(component,paymentArea,itemId)]).then((_ref=>{let[modal,paypalConfig]=_ref;return Promise.all([modal,paypalConfig,switchSdk(paypalConfig.clientid,paypalConfig.currency)])})).then((_ref2=>{let[modal,paypalConfig]=_ref2;return modal.setBody(""),new Promise((resolve=>{window.paypal.Buttons({createOrder:function(data,actions){return actions.order.create({purchase_units:[{amount:{currency_code:paypalConfig.currency_code,value:paypalConfig.cost},description:_truncate.default.truncate(description,{length:127,stripTags:!0})}],application_context:{shipping_preference:"NO_SHIPPING",brand_name:_truncate.default.truncate(paypalConfig.brandname,{length:127,stripTags:!0})}})},onApprove:function(data){modal.getRoot().on(_modal_events.default.outsideClick,(e=>{e.preventDefault()})),modal.setBody((0,_str.getString)("authorising","paygw_paypal")),Repository.markTransactionComplete(component,paymentArea,itemId,data.orderID).then((res=>(modal.hide(),res))).then(resolve)}}).render(modal.getBody()[0])}))})).then((res=>res.success?Promise.resolve(res.message):Promise.reject(res.message)));const switchSdk=(clientId,currency)=>{const sdkUrl="https://www.paypal.com/sdk/js?client-id=".concat(clientId,"&currency=").concat(currency);if(switchSdk.currentlyloaded===sdkUrl)return Promise.resolve();if(switchSdk.currentlyloaded){const suspectedScript=document.querySelector('script[src="'.concat(switchSdk.currentlyloaded,'"]'));suspectedScript&&suspectedScript.parentNode.removeChild(suspectedScript)}const script=document.createElement("script");return new Promise((resolve=>{script.readyState?script.onreadystatechange=function(){"complete"!=this.readyState&&"loaded"!=this.readyState||(this.onreadystatechange=null,resolve())}:script.onload=function(){resolve()},script.setAttribute("src",sdkUrl),document.head.appendChild(script),switchSdk.currentlyloaded=sdkUrl}))};switchSdk.currentlyloaded=""}));
//# sourceMappingURL=gateways_modal.min.js.map
File diff suppressed because one or more lines are too long
+10
View File
@@ -0,0 +1,10 @@
define("paygw_paypal/repository",["exports","core/ajax"],(function(_exports,_ajax){var obj;
/**
* PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.
*
* @module paygw_paypal/repository
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.markTransactionComplete=_exports.getConfigForJs=void 0,_ajax=(obj=_ajax)&&obj.__esModule?obj:{default:obj};_exports.getConfigForJs=(component,paymentArea,itemId)=>{const request={methodname:"paygw_paypal_get_config_for_js",args:{component:component,paymentarea:paymentArea,itemid:itemId}};return _ajax.default.call([request])[0]};_exports.markTransactionComplete=(component,paymentArea,itemId,orderId)=>{const request={methodname:"paygw_paypal_create_transaction_complete",args:{component:component,paymentarea:paymentArea,itemid:itemId,orderid:orderId}};return _ajax.default.call([request])[0]}}));
//# sourceMappingURL=repository.min.js.map
@@ -0,0 +1 @@
{"version":3,"file":"repository.min.js","sources":["../src/repository.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.\n *\n * @module paygw_paypal/repository\n * @copyright 2020 Shamim Rezaie <shamim@moodle.com>\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport Ajax from 'core/ajax';\n\n/**\n * Return the PayPal JavaScript SDK URL.\n *\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea The area of the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @returns {Promise<{clientid: string, brandname: string, cost: number, currency: string}>}\n */\nexport const getConfigForJs = (component, paymentArea, itemId) => {\n const request = {\n methodname: 'paygw_paypal_get_config_for_js',\n args: {\n component,\n paymentarea: paymentArea,\n itemid: itemId,\n },\n };\n\n return Ajax.call([request])[0];\n};\n\n/**\n * Call server to validate and capture payment for order.\n *\n * @param {string} component Name of the component that the itemId belongs to\n * @param {string} paymentArea The area of the component that the itemId belongs to\n * @param {number} itemId An internal identifier that is used by the component\n * @param {string} orderId The order id coming back from PayPal\n * @returns {*}\n */\nexport const markTransactionComplete = (component, paymentArea, itemId, orderId) => {\n const request = {\n methodname: 'paygw_paypal_create_transaction_complete',\n args: {\n component,\n paymentarea: paymentArea,\n itemid: itemId,\n orderid: orderId,\n },\n };\n\n return Ajax.call([request])[0];\n};\n"],"names":["component","paymentArea","itemId","request","methodname","args","paymentarea","itemid","Ajax","call","orderId","orderid"],"mappings":";;;;;;;yMAiC8B,CAACA,UAAWC,YAAaC,gBAC7CC,QAAU,CACZC,WAAY,iCACZC,KAAM,CACFL,UAAAA,UACAM,YAAaL,YACbM,OAAQL,gBAITM,cAAKC,KAAK,CAACN,UAAU,qCAYO,CAACH,UAAWC,YAAaC,OAAQQ,iBAC9DP,QAAU,CACZC,WAAY,2CACZC,KAAM,CACFL,UAAAA,UACAM,YAAaL,YACbM,OAAQL,OACRS,QAASD,iBAIVF,cAAKC,KAAK,CAACN,UAAU"}
@@ -0,0 +1,167 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This module is responsible for PayPal content in the gateways modal.
*
* @module paygw_paypal/gateways_modal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import * as Repository from './repository';
import Templates from 'core/templates';
import Truncate from 'core/truncate';
import Modal from 'core/modal';
import ModalEvents from 'core/modal_events';
import {getString} from 'core/str';
/**
* Creates and shows a modal that contains a placeholder.
*
* @returns {Promise<Modal>}
*/
const showModalWithPlaceholder = async() => await Modal.create({
body: await Templates.render('paygw_paypal/paypal_button_placeholder', {}),
show: true,
removeOnClose: true,
});
/**
* Process the payment.
*
* @param {string} component Name of the component that the itemId belongs to
* @param {string} paymentArea The area of the component that the itemId belongs to
* @param {number} itemId An internal identifier that is used by the component
* @param {string} description Description of the payment
* @returns {Promise<string>}
*/
export const process = (component, paymentArea, itemId, description) => {
return Promise.all([
showModalWithPlaceholder(),
Repository.getConfigForJs(component, paymentArea, itemId),
])
.then(([modal, paypalConfig]) => {
return Promise.all([
modal,
paypalConfig,
switchSdk(paypalConfig.clientid, paypalConfig.currency),
]);
})
.then(([modal, paypalConfig]) => {
// We have to clear the body. The render method in paypal.Buttons will render everything.
modal.setBody('');
return new Promise(resolve => {
window.paypal.Buttons({
// Set up the transaction.
createOrder: function(data, actions) {
return actions.order.create({
purchase_units: [{ // eslint-disable-line
amount: {
currency_code: paypalConfig.currency_code, // eslint-disable-line
value: paypalConfig.cost,
},
description: Truncate.truncate(description, {length: 127, stripTags: true}),
}],
application_context: { // eslint-disable-line
shipping_preference: 'NO_SHIPPING', // eslint-disable-line
brand_name: Truncate.truncate(paypalConfig.brandname, {length: 127, stripTags: true}), // eslint-disable-line
},
});
},
// Finalise the transaction.
onApprove: function(data) {
modal.getRoot().on(ModalEvents.outsideClick, (e) => {
// Prevent closing the modal when clicking outside of it.
e.preventDefault();
});
modal.setBody(getString('authorising', 'paygw_paypal'));
Repository.markTransactionComplete(component, paymentArea, itemId, data.orderID)
.then(res => {
modal.hide();
return res;
})
.then(resolve);
}
}).render(modal.getBody()[0]);
});
})
.then(res => {
if (res.success) {
return Promise.resolve(res.message);
}
return Promise.reject(res.message);
});
};
/**
* Unloads the previously loaded PayPal JavaScript SDK, and loads a new one.
*
* @param {string} clientId PayPal client ID
* @param {string} currency The currency
* @returns {Promise}
*/
const switchSdk = (clientId, currency) => {
const sdkUrl = `https://www.paypal.com/sdk/js?client-id=${clientId}&currency=${currency}`;
// Check to see if this file has already been loaded. If so just go straight to the func.
if (switchSdk.currentlyloaded === sdkUrl) {
return Promise.resolve();
}
// PayPal can only work with one currency at the same time. We have to unload the previously loaded script
// if it was loaded for a different currency. Weird way indeed, but the only way.
// See: https://github.com/paypal/paypal-checkout-components/issues/1180
if (switchSdk.currentlyloaded) {
const suspectedScript = document.querySelector(`script[src="${switchSdk.currentlyloaded}"]`);
if (suspectedScript) {
suspectedScript.parentNode.removeChild(suspectedScript);
}
}
const script = document.createElement('script');
return new Promise(resolve => {
if (script.readyState) {
script.onreadystatechange = function() {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
this.onreadystatechange = null;
resolve();
}
};
} else {
script.onload = function() {
resolve();
};
}
script.setAttribute('src', sdkUrl);
document.head.appendChild(script);
switchSdk.currentlyloaded = sdkUrl;
});
};
/**
* Holds the full url of loaded PayPal JavaScript SDK.
*
* @static
* @type {string}
*/
switchSdk.currentlyloaded = '';
@@ -0,0 +1,68 @@
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* PayPal repository module to encapsulate all of the AJAX requests that can be sent for PayPal.
*
* @module paygw_paypal/repository
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import Ajax from 'core/ajax';
/**
* Return the PayPal JavaScript SDK URL.
*
* @param {string} component Name of the component that the itemId belongs to
* @param {string} paymentArea The area of the component that the itemId belongs to
* @param {number} itemId An internal identifier that is used by the component
* @returns {Promise<{clientid: string, brandname: string, cost: number, currency: string}>}
*/
export const getConfigForJs = (component, paymentArea, itemId) => {
const request = {
methodname: 'paygw_paypal_get_config_for_js',
args: {
component,
paymentarea: paymentArea,
itemid: itemId,
},
};
return Ajax.call([request])[0];
};
/**
* Call server to validate and capture payment for order.
*
* @param {string} component Name of the component that the itemId belongs to
* @param {string} paymentArea The area of the component that the itemId belongs to
* @param {number} itemId An internal identifier that is used by the component
* @param {string} orderId The order id coming back from PayPal
* @returns {*}
*/
export const markTransactionComplete = (component, paymentArea, itemId, orderId) => {
const request = {
methodname: 'paygw_paypal_create_transaction_complete',
args: {
component,
paymentarea: paymentArea,
itemid: itemId,
orderid: orderId,
},
};
return Ajax.call([request])[0];
};
@@ -0,0 +1,90 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This class contains a list of webservice functions related to the PayPal payment gateway.
*
* @package paygw_paypal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
namespace paygw_paypal\external;
use core_payment\helper;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_value;
use core_external\external_single_structure;
class get_config_for_js extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters(): external_function_parameters {
return new external_function_parameters([
'component' => new external_value(PARAM_COMPONENT, 'Component'),
'paymentarea' => new external_value(PARAM_AREA, 'Payment area in the component'),
'itemid' => new external_value(PARAM_INT, 'An identifier for payment area in the component'),
]);
}
/**
* Returns the config values required by the PayPal JavaScript SDK.
*
* @param string $component
* @param string $paymentarea
* @param int $itemid
* @return string[]
*/
public static function execute(string $component, string $paymentarea, int $itemid): array {
self::validate_parameters(self::execute_parameters(), [
'component' => $component,
'paymentarea' => $paymentarea,
'itemid' => $itemid,
]);
$config = helper::get_gateway_configuration($component, $paymentarea, $itemid, 'paypal');
$payable = helper::get_payable($component, $paymentarea, $itemid);
$surcharge = helper::get_gateway_surcharge('paypal');
return [
'clientid' => $config['clientid'],
'brandname' => $config['brandname'],
'cost' => helper::get_rounded_cost($payable->get_amount(), $payable->get_currency(), $surcharge),
'currency' => $payable->get_currency(),
];
}
/**
* Returns description of method result value.
*
* @return external_single_structure
*/
public static function execute_returns(): external_single_structure {
return new external_single_structure([
'clientid' => new external_value(PARAM_TEXT, 'PayPal client ID'),
'brandname' => new external_value(PARAM_TEXT, 'Brand name'),
'cost' => new external_value(PARAM_FLOAT, 'Cost with gateway surcharge'),
'currency' => new external_value(PARAM_TEXT, 'Currency'),
]);
}
}
@@ -0,0 +1,149 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This class contains a list of webservice functions related to the PayPal payment gateway.
*
* @package paygw_paypal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
declare(strict_types=1);
namespace paygw_paypal\external;
use core_external\external_api;
use core_external\external_value;
use core_external\external_function_parameters;
use core_payment\helper;
use core_payment\helper as payment_helper;
use paygw_paypal\paypal_helper;
class transaction_complete extends external_api {
/**
* Returns description of method parameters.
*
* @return external_function_parameters
*/
public static function execute_parameters() {
return new external_function_parameters([
'component' => new external_value(PARAM_COMPONENT, 'The component name'),
'paymentarea' => new external_value(PARAM_AREA, 'Payment area in the component'),
'itemid' => new external_value(PARAM_INT, 'The item id in the context of the component area'),
'orderid' => new external_value(PARAM_TEXT, 'The order id coming back from PayPal'),
]);
}
/**
* Perform what needs to be done when a transaction is reported to be complete.
* This function does not take cost as a parameter as we cannot rely on any provided value.
*
* @param string $component Name of the component that the itemid belongs to
* @param string $paymentarea
* @param int $itemid An internal identifier that is used by the component
* @param string $orderid PayPal order ID
* @return array
*/
public static function execute(string $component, string $paymentarea, int $itemid, string $orderid): array {
global $USER, $DB;
self::validate_parameters(self::execute_parameters(), [
'component' => $component,
'paymentarea' => $paymentarea,
'itemid' => $itemid,
'orderid' => $orderid,
]);
$config = (object)helper::get_gateway_configuration($component, $paymentarea, $itemid, 'paypal');
$sandbox = $config->environment == 'sandbox';
$payable = payment_helper::get_payable($component, $paymentarea, $itemid);
$currency = $payable->get_currency();
// Add surcharge if there is any.
$surcharge = helper::get_gateway_surcharge('paypal');
$amount = helper::get_rounded_cost($payable->get_amount(), $currency, $surcharge);
$paypalhelper = new paypal_helper($config->clientid, $config->secret, $sandbox);
$orderdetails = $paypalhelper->get_order_details($orderid);
$success = false;
$message = '';
if ($orderdetails) {
if ($orderdetails['status'] == paypal_helper::ORDER_STATUS_APPROVED &&
$orderdetails['intent'] == paypal_helper::ORDER_INTENT_CAPTURE) {
$item = $orderdetails['purchase_units'][0];
if ($item['amount']['value'] == $amount && $item['amount']['currency_code'] == $currency) {
$capture = $paypalhelper->capture_order($orderid);
if ($capture && $capture['status'] == paypal_helper::CAPTURE_STATUS_COMPLETED) {
$success = true;
// Everything is correct. Let's give them what they paid for.
try {
$paymentid = payment_helper::save_payment($payable->get_account_id(), $component, $paymentarea,
$itemid, (int) $USER->id, $amount, $currency, 'paypal');
// Store PayPal extra information.
$record = new \stdClass();
$record->paymentid = $paymentid;
$record->pp_orderid = $orderid;
$DB->insert_record('paygw_paypal', $record);
payment_helper::deliver_order($component, $paymentarea, $itemid, $paymentid, (int) $USER->id);
} catch (\Exception $e) {
debugging('Exception while trying to process payment: ' . $e->getMessage(), DEBUG_DEVELOPER);
$success = false;
$message = get_string('internalerror', 'paygw_paypal');
}
} else {
$success = false;
$message = get_string('paymentnotcleared', 'paygw_paypal');
}
} else {
$success = false;
$message = get_string('amountmismatch', 'paygw_paypal');
}
} else {
$success = false;
$message = get_string('paymentnotcleared', 'paygw_paypal');
}
} else {
// Could not capture authorization!
$success = false;
$message = get_string('cannotfetchorderdatails', 'paygw_paypal');
}
return [
'success' => $success,
'message' => $message,
];
}
/**
* Returns description of method result value.
*
* @return external_function_parameters
*/
public static function execute_returns() {
return new external_function_parameters([
'success' => new external_value(PARAM_BOOL, 'Whether everything was successful or not.'),
'message' => new external_value(PARAM_RAW, 'Message (usually the error message).'),
]);
}
}
@@ -0,0 +1,89 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains class for PayPal payment gateway.
*
* @package paygw_paypal
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace paygw_paypal;
/**
* The gateway class for PayPal payment gateway.
*
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class gateway extends \core_payment\gateway {
public static function get_supported_currencies(): array {
// See https://developer.paypal.com/docs/api/reference/currency-codes/,
// 3-character ISO-4217: https://en.wikipedia.org/wiki/ISO_4217#Active_codes.
return [
'AUD', 'BRL', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'ILS', 'INR', 'JPY',
'MXN', 'MYR', 'NOK', 'NZD', 'PHP', 'PLN', 'RUB', 'SEK', 'SGD', 'THB', 'TRY', 'TWD', 'USD'
];
}
/**
* Configuration form for the gateway instance
*
* Use $form->get_mform() to access the \MoodleQuickForm instance
*
* @param \core_payment\form\account_gateway $form
*/
public static function add_configuration_to_gateway_form(\core_payment\form\account_gateway $form): void {
$mform = $form->get_mform();
$mform->addElement('text', 'brandname', get_string('brandname', 'paygw_paypal'));
$mform->setType('brandname', PARAM_TEXT);
$mform->addHelpButton('brandname', 'brandname', 'paygw_paypal');
$mform->addElement('text', 'clientid', get_string('clientid', 'paygw_paypal'));
$mform->setType('clientid', PARAM_TEXT);
$mform->addHelpButton('clientid', 'clientid', 'paygw_paypal');
$mform->addElement('text', 'secret', get_string('secret', 'paygw_paypal'));
$mform->setType('secret', PARAM_TEXT);
$mform->addHelpButton('secret', 'secret', 'paygw_paypal');
$options = [
'live' => get_string('live', 'paygw_paypal'),
'sandbox' => get_string('sandbox', 'paygw_paypal'),
];
$mform->addElement('select', 'environment', get_string('environment', 'paygw_paypal'), $options);
$mform->addHelpButton('environment', 'environment', 'paygw_paypal');
}
/**
* Validates the gateway configuration form.
*
* @param \core_payment\form\account_gateway $form
* @param \stdClass $data
* @param array $files
* @param array $errors form errors (passed by reference)
*/
public static function validate_gateway_form(\core_payment\form\account_gateway $form,
\stdClass $data, array $files, array &$errors): void {
if ($data->enabled &&
(empty($data->brandname) || empty($data->clientid) || empty($data->secret))) {
$errors['enabled'] = get_string('gatewaycannotbeenabled', 'payment');
}
}
}
@@ -0,0 +1,196 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Contains helper class to work with PayPal REST API.
*
* @package core_payment
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace paygw_paypal;
use curl;
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/filelib.php');
class paypal_helper {
/**
* @var string The payment was authorized or the authorized payment was captured for the order.
*/
public const CAPTURE_STATUS_COMPLETED = 'COMPLETED';
/**
* @var string The merchant intends to capture payment immediately after the customer makes a payment.
*/
public const ORDER_INTENT_CAPTURE = 'CAPTURE';
/**
* @var string The customer approved the payment.
*/
public const ORDER_STATUS_APPROVED = 'APPROVED';
/**
* @var string The base API URL
*/
private $baseurl;
/**
* @var string Client ID
*/
private $clientid;
/**
* @var string PayPal App secret
*/
private $secret;
/**
* @var string The oath bearer token
*/
private $token;
/**
* helper constructor.
*
* @param string $clientid The client id.
* @param string $secret PayPal secret.
* @param bool $sandbox Whether we are working with the sandbox environment or not.
*/
public function __construct(string $clientid, string $secret, bool $sandbox) {
$this->clientid = $clientid;
$this->secret = $secret;
$this->baseurl = $sandbox ? 'https://api.sandbox.paypal.com' : 'https://api.paypal.com';
$this->token = $this->get_token();
}
/**
* Captures an authorized payment, by ID.
*
* @param string $authorizationid The PayPal-generated ID for the authorized payment to capture.
* @param float $amount The amount to capture.
* @param string $currency The currency code for the amount.
* @param bool $final Indicates whether this is the final captures against the authorized payment.
* @return array|null Formatted API response.
*/
public function capture_authorization(string $authorizationid, float $amount, string $currency, bool $final = true): ?array {
$location = "{$this->baseurl}/v2/payments/authorizations/{$authorizationid}/capture";
$options = [
'CURLOPT_RETURNTRANSFER' => true,
'CURLOPT_TIMEOUT' => 30,
'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
'CURLOPT_HTTPHEADER' => [
'Content-Type: application/json',
"Authorization: Bearer {$this->token}",
],
];
$command = [
'amount' => [
'value' => (string) $amount,
'currency_code' => $currency,
],
'final_capture' => $final,
];
$command = json_encode($command);
$curl = new curl();
$result = $curl->post($location, $command, $options);
return json_decode($result, true);
}
/**
* Captures order details from PayPal.
*
* @param string $orderid The order we want to capture.
* @return array|null Formatted API response.
*/
public function capture_order(string $orderid): ?array {
$location = "{$this->baseurl}/v2/checkout/orders/{$orderid}/capture";
$options = [
'CURLOPT_RETURNTRANSFER' => true,
'CURLOPT_TIMEOUT' => 30,
'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
'CURLOPT_HTTPHEADER' => [
'Content-Type: application/json',
"Authorization: Bearer {$this->token}",
],
];
$command = '{}';
$curl = new curl();
$result = $curl->post($location, $command, $options);
return json_decode($result, true);
}
public function get_order_details(string $orderid): ?array {
$location = "{$this->baseurl}/v2/checkout/orders/{$orderid}";
$options = [
'CURLOPT_RETURNTRANSFER' => true,
'CURLOPT_TIMEOUT' => 30,
'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
'CURLOPT_HTTPHEADER' => [
'Content-Type: application/json',
"Authorization: Bearer {$this->token}",
],
];
$curl = new curl();
$result = $curl->get($location, [], $options);
return json_decode($result, true);
}
/**
* Request for PayPal REST oath bearer token.
*
* @return string
*/
private function get_token(): string {
$location = "{$this->baseurl}/v1/oauth2/token";
$options = [
'CURLOPT_RETURNTRANSFER' => true,
'CURLOPT_TIMEOUT' => 30,
'CURLOPT_HTTP_VERSION' => CURL_HTTP_VERSION_1_1,
'CURLOPT_SSLVERSION' => CURL_SSLVERSION_TLSv1_2,
'CURLOPT_USERPWD' => "{$this->clientid}:{$this->secret}",
];
$command = 'grant_type=client_credentials';
$curl = new curl();
$result = $curl->post($location, $command, $options);
$result = json_decode($result, true);
return $result['access_token'];
}
}
@@ -0,0 +1,82 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Privacy Subsystem implementation for paygw_paypal.
*
* @package paygw_paypal
* @category privacy
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace paygw_paypal\privacy;
use core_payment\privacy\paygw_provider;
use core_privacy\local\request\writer;
/**
* Privacy Subsystem implementation for paygw_paypal.
*
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider, paygw_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
/**
* Export all user data for the specified payment record, and the given context.
*
* @param \context $context Context
* @param array $subcontext The location within the current context that the payment data belongs
* @param \stdClass $payment The payment record
*/
public static function export_payment_data(\context $context, array $subcontext, \stdClass $payment) {
global $DB;
$subcontext[] = get_string('gatewayname', 'paygw_paypal');
$record = $DB->get_record('paygw_paypal', ['paymentid' => $payment->id]);
$data = (object) [
'orderid' => $record->pp_orderid,
];
writer::with_context($context)->export_data(
$subcontext,
$data
);
}
/**
* Delete all user data related to the given payments.
*
* @param string $paymentsql SQL query that selects payment.id field for the payments
* @param array $paymentparams Array of parameters for $paymentsql
*/
public static function delete_data_for_payment_sql(string $paymentsql, array $paymentparams) {
global $DB;
$DB->delete_records_select('paygw_paypal', "paymentid IN ({$paymentsql})", $paymentparams);
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* paygw_paypal installer script.
*
* @package paygw_paypal
* @copyright 2020 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_paygw_paypal_install() {
global $CFG;
// Enable the Paypal payment gateway on installation. It still needs to be configured and enabled for accounts.
$order = (!empty($CFG->paygw_plugins_sortorder)) ? explode(',', $CFG->paygw_plugins_sortorder) : [];
set_config('paygw_plugins_sortorder', join(',', array_merge($order, ['paypal'])));
}
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="payment/gateway/paypal/db" VERSION="20201216" COMMENT="XMLDB file for PayPal payment gateway plugin"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="paygw_paypal" COMMENT="Stores PayPal related information">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="paymentid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="pp_orderid" TYPE="char" LENGTH="255" NOTNULL="true" DEFAULT="The ID of the order in PayPal" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="paymentid" TYPE="foreign-unique" FIELDS="paymentid" REFTABLE="payments" REFFIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
+43
View File
@@ -0,0 +1,43 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* External functions and service definitions for the PayPal payment gateway plugin.
*
* @package paygw_paypal
* @copyright 2020 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$functions = [
'paygw_paypal_get_config_for_js' => [
'classname' => 'paygw_paypal\external\get_config_for_js',
'classpath' => '',
'description' => 'Returns the configuration settings to be used in js',
'type' => 'read',
'ajax' => true,
],
'paygw_paypal_create_transaction_complete' => [
'classname' => 'paygw_paypal\external\transaction_complete',
'classpath' => '',
'description' => 'Takes care of what needs to be done when a PayPal transaction comes back as complete.',
'type' => 'write',
'ajax' => true,
'loginrequired' => false,
],
];
+58
View File
@@ -0,0 +1,58 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Upgrade script for paygw_paypal.
*
* @package paygw_paypal
* @copyright 2021 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Upgrade the plugin.
*
* @param int $oldversion the version we are upgrading from
* @return bool always true
*/
function xmldb_paygw_paypal_upgrade(int $oldversion): bool {
global $DB;
$dbman = $DB->get_manager();
if ($oldversion < 2021052501) {
// Define key paymentid (foreign-unique) to be added to paygw_paypal.
$table = new xmldb_table('paygw_paypal');
$key = new xmldb_key('paymentid', XMLDB_KEY_FOREIGN_UNIQUE, ['paymentid'], 'payments', ['id']);
// Launch add key paymentid.
$dbman->add_key($table, $key);
// Paypal savepoint reached.
upgrade_plugin_savepoint(true, 2021052501, 'paygw', 'paypal');
}
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
@@ -0,0 +1,45 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Strings for component 'paygw_paypal', language 'en'
*
* @package paygw_paypal
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['amountmismatch'] = 'The amount you attempted to pay does not match the required fee. Your account has not been debited.';
$string['authorising'] = 'Authorising the payment. Please wait...';
$string['brandname'] = 'Brand name';
$string['brandname_help'] = 'An optional label that overrides the business name for the PayPal account on the PayPal site.';
$string['cannotfetchorderdatails'] = 'Could not fetch payment details from PayPal. Your account has not been debited.';
$string['clientid'] = 'Client ID';
$string['clientid_help'] = 'The client ID that PayPal generated for your application.';
$string['environment'] = 'Environment';
$string['environment_help'] = 'You can set this to Sandbox if you are using sandbox accounts (for testing purpose only).';
$string['gatewaydescription'] = 'PayPal is an authorised payment gateway provider for processing credit card transactions.';
$string['gatewayname'] = 'PayPal';
$string['internalerror'] = 'An internal error has occurred. Please contact us.';
$string['live'] = 'Live';
$string['paymentnotcleared'] = 'payment not cleared by PayPal.';
$string['pluginname'] = 'PayPal';
$string['pluginname_desc'] = 'The PayPal plugin allows you to receive payments via PayPal.';
$string['privacy:metadata'] = 'The PayPal plugin does not store any personal data.';
$string['repeatedorder'] = 'This order has already been processed earlier.';
$string['sandbox'] = 'Sandbox';
$string['secret'] = 'Secret';
$string['secret_help'] = 'The secret that PayPal generated for your application.';
+330
View File
@@ -0,0 +1,330 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 320 125" style="enable-background:new 0 0 320 125;" xml:space="preserve" preserveAspectRatio="xMinYMid meet">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
.st1{fill:#222562;}
.st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FF8000;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#FF0000;}
.st4{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;stroke:#FFFFFF;stroke-width:0.1212;stroke-linecap:square;stroke-miterlimit:10;}
.st5{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st6{fill:none;stroke:#FFFFFF;stroke-width:0.1212;stroke-linecap:square;stroke-miterlimit:10;}
.st7{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;stroke:#999999;}
.st8{fill-rule:evenodd;clip-rule:evenodd;fill:#E6E7E8;stroke:#000000;}
.st9{fill:#263F6B;stroke:#263F6B;stroke-width:0.25;}
.st10{fill-rule:evenodd;clip-rule:evenodd;fill:#009DE2;}
.st11{fill-rule:evenodd;clip-rule:evenodd;fill:#113984;}
.st12{fill-rule:evenodd;clip-rule:evenodd;fill:#172C70;}
.st13{fill:#00589F;}
.st14{fill:#F9A51A;}
.st15{fill:#F79739;stroke:#F79739;stroke-width:6;}
.st16{fill:none;stroke:#F79739;stroke-width:2;}
</style>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="159.3737" y1="31.3265" x2="159.3737" y2="121.832">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="0.2032" style="stop-color:#FFFEFC"/>
<stop offset="0.35" style="stop-color:#FFFAF3"/>
<stop offset="0.479" style="stop-color:#FEF4E3"/>
<stop offset="0.5978" style="stop-color:#FEEBCD"/>
<stop offset="0.7097" style="stop-color:#FDDFB0"/>
<stop offset="0.8164" style="stop-color:#FDD18C"/>
<stop offset="0.917" style="stop-color:#FCC063"/>
<stop offset="1" style="stop-color:#FBB03B"/>
</linearGradient>
<rect x="4.6" y="31.3" class="st0" width="309.5" height="90.5"/>
<g>
<rect x="120.8" y="62" class="st1" width="78.6" height="47.7"/>
<g>
<polygon class="st2" points="174.1,64.3 175.2,64.3 176.3,64.4 178.4,64.8 180.5,65.3 182.5,66 184.4,66.9 186.2,68 187.8,69.3
189.4,70.6 190.8,72.2 192,73.8 193.1,75.6 194,77.5 194.7,79.4 195.3,81.5 195.6,83.7 195.7,85.8 195.7,86.9 195.6,88
195.3,90.1 194.7,92.2 194,94.2 193.1,96.1 192,97.8 190.8,99.5 189.4,101 187.8,102.4 186.2,103.7 184.4,104.7 182.5,105.7
180.5,106.4 178.4,106.9 176.3,107.2 174.1,107.3 173,107.3 171.9,107.2 169.8,106.9 167.8,106.4 165.8,105.7 163.9,104.8
162.2,103.7 160.5,102.4 159,101 157.6,99.5 156.4,97.9 155.4,96.1 154.5,94.2 153.8,92.3 153.2,90.2 152.9,88.1 152.8,85.9
152.8,84.8 152.9,83.7 153.2,81.6 153.8,79.5 154.5,77.5 155.4,75.7 156.4,73.9 157.6,72.2 159,70.7 160.5,69.3 162.2,68
163.9,66.9 165.8,66 167.8,65.3 169.8,64.8 171.9,64.4 174.1,64.3 "/>
<polygon class="st3" points="160.8,100.8 160.7,100.9 160.6,101 160.5,101.1 160.4,101.2 160.3,101.3 160.2,101.3 160.1,101.4
160,101.5 159.9,101.6 159.9,101.7 159.8,101.8 159.7,101.8 159.6,101.9 159.5,102 159.4,102.1 159.3,102.2 158.9,102.5
158.5,102.7 157.8,103.3 157,103.8 156.3,104.2 155.4,104.7 154.6,105.1 153.8,105.5 152.9,105.8 152.1,106.1 151.2,106.3
150.3,106.5 149.4,106.7 148.5,106.9 147.6,107 146.7,107 145.8,107.1 144.7,107 143.6,106.9 141.5,106.6 139.5,106.1
137.5,105.4 135.7,104.5 133.9,103.4 132.3,102.2 130.8,100.8 129.4,99.3 128.2,97.7 127.1,95.9 126.2,94.1 125.5,92.1 125,90.1
124.6,88 124.5,85.9 124.5,84.8 124.6,83.7 125,81.6 125.5,79.6 126.3,77.7 127.2,75.8 128.3,74.1 129.5,72.4 130.9,70.9
132.4,69.6 134.1,68.4 135.7,67.3 137.5,66.4 139.4,65.7 141.3,65.2 143.2,64.9 145.1,64.8 145.7,64.8 146.2,64.8 147.3,64.9
148.3,65 149.3,65.2 150.3,65.4 151.2,65.6 152.1,65.8 153,66.1 153.9,66.5 154.7,66.8 155.5,67.2 156.2,67.6 157,68.1
157.7,68.5 158.4,69 159,69.5 159.7,70.2 160.5,70.9 161.3,71.8 158,71.8 157.1,72.9 162.5,72.9 162.7,73.2 163.3,74 163.5,74.3
156.2,74.3 155.5,75.4 164.2,75.4 164.4,75.8 165,76.8 154.8,76.8 154.3,78 165.4,78 165.7,78.6 166,79.4 153.8,79.4 153.5,80.5
166.3,80.5 166.6,81.6 166.7,81.9 153.2,81.9 153,83 166.8,83 166.9,83.7 167,84.8 167,85.9 167,87 163.5,87 163.5,88.1
166.9,88.1 166.8,89.1 166.7,89.5 163.2,89.5 163.1,90.7 166.5,90.7 166.4,91.1 166.1,92.1 153.7,92.1 154.1,93.2 165.7,93.2
165.4,94.1 165.1,94.6 154.7,94.6 155.2,95.7 164.5,95.7 164.4,95.9 163.9,96.8 163.7,97.1 156,97.1 156.7,98.3 163,98.3
162.8,98.5 162.1,99.3 161.8,99.7 157.7,99.7 158.8,100.8 160.8,100.8 "/>
<polygon class="st2" points="154.7,87 152,87 152.1,88 154.7,88 154.7,87 "/>
<polygon class="st4" points="173.1,83.9 173.1,83.9 172.9,83.8 172.8,83.8 172.6,83.7 172.5,83.7 172.4,83.6 172.2,83.6
172.1,83.6 171.9,83.5 171.8,83.5 171.7,83.5 171.5,83.5 171.3,83.5 171,83.5 170.9,83.5 170.7,83.5 170.6,83.5 170.3,83.6
170.1,83.7 169.8,83.8 169.6,83.9 169.4,84.1 169.2,84.3 169,84.5 168.9,84.7 168.7,85 168.6,85.2 168.5,85.5 168.4,85.8
168.3,86.1 168.2,86.4 168.2,86.6 168.1,86.8 168.1,86.9 168.1,87.2 168.2,87.5 168.2,87.8 168.3,88 168.4,88.2 168.6,88.5
168.7,88.7 168.9,88.8 169.1,89 169.3,89.1 169.5,89.3 169.7,89.3 170,89.4 170.2,89.4 170.5,89.4 170.6,89.4 170.7,89.4
170.9,89.4 171,89.4 171.2,89.4 171.3,89.3 171.5,89.3 171.6,89.3 171.7,89.3 171.9,89.2 172,89.2 172.1,89.1 172.1,89.1
172.2,89.1 172.3,89 172.4,89 172.5,89.1 172.4,89.2 172.4,89.3 172.4,89.4 172.3,89.4 172.3,89.5 172.3,89.6 172.2,89.7
172.2,89.8 172.2,89.9 172.1,90 172.1,90.1 172.1,90.2 172.1,90.3 172.1,90.4 172.1,90.5 172.1,90.7 172.1,90.8 172.1,90.9
172.1,90.9 172,91 171.9,91 171.8,91 171.7,91.1 171.6,91.1 171.4,91.1 171.3,91.1 171.2,91.2 171.1,91.2 171,91.2 170.9,91.2
170.8,91.2 170.6,91.2 170.1,91.2 169.8,91.2 169.3,91.1 168.9,91 168.4,90.9 168,90.7 167.7,90.5 167.4,90.3 167.1,90
166.8,89.7 166.6,89.4 166.5,89 166.3,88.6 166.2,88.2 166.2,87.7 166.2,87.3 166.2,86.8 166.2,86.4 166.2,86.1 166.3,85.5
166.5,85 166.7,84.5 166.9,84 167.2,83.6 167.4,83.2 167.8,82.9 168.1,82.6 168.5,82.3 168.9,82.1 169.3,81.9 169.7,81.8
170.2,81.7 170.6,81.6 171.1,81.6 171.2,81.7 171.3,81.7 171.5,81.7 171.7,81.7 171.8,81.7 172,81.7 172.2,81.8 172.3,81.8
172.5,81.8 172.6,81.8 172.8,81.9 172.9,81.9 173,81.9 173.2,82 173.3,82 173.4,82.1 173.5,82.1 173.5,82.2 173.5,82.3
173.5,82.4 173.5,82.5 173.5,82.6 173.5,82.6 173.4,82.7 173.4,82.8 173.4,82.8 173.4,82.9 173.4,83 173.4,83 173.4,83.2
173.3,83.3 173.3,83.3 173.3,83.4 173.3,83.5 173.3,83.6 173.3,83.7 173.3,83.7 173.3,83.8 173.3,83.9 173.2,83.9 173.1,83.9
"/>
<polygon class="st4" points="162.3,83.5 164.2,83.5 164.1,84.4 164.1,84.5 164.1,84.6 164.2,84.6 164.3,84.6 164.3,84.5
164.4,84.4 164.5,84.3 164.6,84.2 164.7,84 164.8,83.9 165,83.8 165.1,83.8 165.2,83.7 165.4,83.6 165.5,83.6 165.7,83.6
165.8,83.5 166,83.5 166.1,83.5 166.3,83.5 166.5,83.5 165.9,84.7 165.7,85.6 165.6,85.5 165.5,85.5 165.4,85.5 165.2,85.5
165.1,85.5 164.9,85.6 164.8,85.6 164.6,85.7 164.5,85.8 164.4,85.9 164.3,86 164.2,86.1 164.1,86.3 164,86.5 163.9,86.7
163.8,86.9 163.8,87.1 163.2,90.1 163.1,91.1 160.9,91.1 161.2,90 162.2,84.2 162.3,83.5 "/>
<polygon class="st4" points="144.2,91 144.3,90.1 144.4,89.4 144.4,89.4 144.5,89.4 144.6,89.5 144.8,89.5 145,89.5 145.1,89.6
145.4,89.6 145.5,89.6 145.8,89.6 145.9,89.6 146.1,89.6 146.3,89.6 146.5,89.6 147.1,89.6 147.1,89.6 147.3,89.6 147.4,89.6
147.5,89.5 147.6,89.4 147.7,89.3 147.8,89.2 147.8,89.1 147.9,89 147.9,88.8 147.8,88.7 147.8,88.6 147.7,88.5 147.6,88.4
147.4,88.2 147.2,88.1 147.1,88.1 147,88 146.8,88 146.6,87.9 146.4,87.8 146.2,87.7 146,87.6 145.8,87.5 145.6,87.3 145.5,87.2
145.3,87 145.2,86.9 145.1,86.7 145,86.5 145,86.2 145,86 145,85.7 145,85.6 145,85.5 145,85.3 145.1,85 145.2,84.9 145.3,84.7
145.4,84.5 145.5,84.3 145.6,84.1 145.8,84 146,83.8 146.2,83.7 146.5,83.6 146.7,83.5 147,83.5 147.3,83.4 147.7,83.4 148,83.4
148.2,83.4 148.4,83.4 148.6,83.4 148.7,83.4 148.9,83.4 149,83.5 149.2,83.5 149.4,83.5 149.5,83.5 149.7,83.5 149.8,83.5
150,83.5 150.2,83.5 150.3,83.5 150,84.6 149.9,85.1 149.8,85.1 149.8,85.1 149.6,85 149.5,85 149.3,85 149.2,85 149,85 148.8,85
148.7,85 148.5,84.9 147.9,84.9 147.8,85 147.7,85 147.6,85 147.6,85 147.4,85.1 147.4,85.1 147.3,85.2 147.2,85.3 147.2,85.4
147.1,85.4 147.1,85.5 147.1,85.6 147.1,85.7 147.2,85.8 147.2,85.9 147.3,86 147.4,86.1 147.5,86.2 147.7,86.3 147.8,86.4
147.9,86.4 148.1,86.5 148.3,86.6 148.5,86.7 148.7,86.8 148.9,86.9 149.1,87 149.3,87.2 149.4,87.3 149.5,87.5 149.7,87.7
149.8,87.9 149.8,88.1 149.9,88.4 149.9,88.7 149.8,89 149.8,89.2 149.8,89.3 149.7,89.6 149.6,89.9 149.5,90.1 149.4,90.3
149.3,90.4 149.1,90.6 148.9,90.7 148.7,90.8 148.5,90.9 148.3,91 148,91 147.8,91.1 147.5,91.1 147.2,91.1 146.9,91.2
146.8,91.2 146.6,91.2 146.5,91.2 146.3,91.2 146,91.2 145.8,91.2 145.6,91.2 145.5,91.2 145.3,91.2 145.1,91.1 144.9,91.1
144.7,91.1 144.6,91.1 144.4,91 144.2,91 "/>
<polygon class="st4" points="128.4,81.7 131.7,81.7 131.8,87.8 132,87.8 134.5,81.7 137.9,81.7 137.6,82.9 136.3,90.1 136.3,91.1
134.2,91.1 134.5,90 135.6,83.5 135.4,83.5 132.2,91.1 130.5,91.1 129.9,83.5 129.8,83.5 128.6,90 128.5,91.1 126.6,91.1
126.9,90.1 128.3,82.5 128.4,81.7 "/>
<polygon class="st5" points="191,81.7 190.6,84.3 190.5,84.4 190.4,84.5 190.3,84.4 190.3,84.3 190.2,84.2 190.1,84.1 190,84
189.9,83.9 189.8,83.9 189.7,83.8 189.7,83.8 189.6,83.8 189.5,83.7 189.4,83.7 189.3,83.6 189.2,83.6 189.2,83.6 189.1,83.5
189,83.5 188.9,83.5 188.9,83.5 188.8,83.5 188.6,83.4 188.5,83.4 188.2,83.4 187.8,83.5 187.5,83.5 187.2,83.6 186.9,83.8
186.6,83.9 186.3,84.1 186.1,84.3 185.8,84.6 185.6,84.9 185.4,85.1 185.2,85.5 185,85.8 184.9,86.2 184.8,86.6 184.8,86.9
184.7,87.1 184.7,87.6 184.6,88 184.7,88.4 184.7,88.8 184.8,89.1 184.9,89.5 185,89.8 185.2,90 185.4,90.3 185.6,90.5
185.8,90.7 186.1,90.8 186.4,91 186.7,91.1 187,91.1 187.1,91.2 187.3,91.2 187.5,91.2 187.7,91.1 187.9,91.1 188.1,91 188.2,91
188.4,90.9 188.6,90.8 188.7,90.8 188.9,90.7 189,90.6 189.1,90.5 189.2,90.4 189.3,90.3 189.4,90.2 189.4,90.2 189.5,90.3
189.4,91.1 191.5,91.1 191.6,90.3 192.5,85.1 188.5,85.1 188.8,85.1 188.9,85.2 189,85.2 189.3,85.3 189.5,85.4 189.6,85.5
189.7,85.6 189.8,85.8 189.9,85.9 190,86.1 190,86.3 190,86.5 190,86.7 190,86.9 190,87.1 189.9,87.3 189.9,87.5 189.9,87.7
189.8,87.8 189.8,87.9 189.7,88.1 189.6,88.3 189.5,88.5 189.5,88.7 189.3,88.8 189.2,88.9 189.1,89.1 189,89.2 188.9,89.3
188.7,89.3 188.6,89.4 188.4,89.4 188.2,89.4 188.1,89.5 187.8,89.5 187.7,89.4 187.6,89.4 187.4,89.3 187.3,89.3 187.2,89.2
187.1,89.1 187,88.9 186.9,88.8 186.8,88.6 186.8,88.5 186.7,88.3 186.7,88.1 186.7,87.9 186.7,87.7 186.7,87.4 186.7,87.2
186.8,87.1 186.8,87 186.8,86.8 186.9,86.6 187,86.4 187.1,86.2 187.2,86.1 187.3,85.9 187.4,85.7 187.5,85.6 187.7,85.5
187.8,85.4 188,85.3 188.2,85.2 188.4,85.2 188.5,85.1 192.5,85.1 192.9,82.9 193.2,81.7 191,81.7 "/>
<polygon class="st5" points="181.2,83.5 183.2,83.5 183,84.4 183,84.5 183,84.6 183.1,84.6 183.2,84.6 183.2,84.5 183.3,84.4
183.4,84.3 183.5,84.2 183.7,84.1 183.8,84 183.9,83.9 184,83.8 184.2,83.8 184.3,83.7 184.5,83.6 184.6,83.6 184.8,83.5
184.9,83.5 185.1,83.5 185.3,83.5 185.4,83.5 184.9,84.7 184.7,85.6 184.6,85.5 184.6,85.5 184.4,85.5 184.2,85.5 184.1,85.5
183.9,85.6 183.8,85.6 183.6,85.7 183.5,85.8 183.4,85.9 183.2,86 183.1,86.1 183,86.3 182.9,86.5 182.8,86.7 182.8,86.9
182.7,87.1 182.2,90.1 182,91.1 179.9,91.1 180.1,90 181.2,84.2 181.2,83.5 "/>
<polyline class="st6" points="191,81.7 190.6,84.3 190.5,84.4 190.4,84.5 190.3,84.4 190.3,84.3 190.2,84.2 190.1,84.1 190,84
189.9,83.9 189.8,83.9 189.7,83.8 189.7,83.8 189.6,83.8 189.5,83.7 189.4,83.7 189.3,83.6 189.2,83.6 189.2,83.6 189.1,83.5
189,83.5 188.9,83.5 188.9,83.5 188.8,83.5 188.6,83.4 188.5,83.4 188.2,83.4 187.8,83.5 187.5,83.5 187.2,83.6 186.9,83.8
186.6,83.9 186.3,84.1 186.1,84.3 185.8,84.6 185.6,84.9 185.4,85.1 185.2,85.5 185,85.8 184.9,86.2 184.8,86.6 184.8,86.9
184.7,87.1 184.7,87.6 184.6,88 184.7,88.4 184.7,88.8 184.8,89.1 184.9,89.5 185,89.8 185.2,90 185.4,90.3 185.6,90.5
185.8,90.7 186.1,90.8 186.4,91 186.7,91.1 187,91.1 187.1,91.2 187.3,91.2 "/>
<polyline class="st6" points="187.3,91.2 187.5,91.2 187.7,91.1 187.9,91.1 188.1,91 188.2,91 188.4,90.9 188.6,90.8 188.7,90.8
188.9,90.7 189,90.6 189.1,90.5 189.2,90.4 189.3,90.3 189.4,90.2 189.4,90.2 189.5,90.3 189.4,91.1 191.5,91.1 191.6,90.3
192.9,82.9 193.2,81.7 191,81.7 "/>
<polyline class="st6" points="181.2,83.5 183.2,83.5 183,84.4 183,84.5 183,84.6 183.1,84.6 183.2,84.6 183.2,84.5 183.3,84.4
183.4,84.3 183.5,84.2 183.7,84.1 183.8,84 183.9,83.9 184,83.8 184.2,83.8 184.3,83.7 184.5,83.6 184.6,83.6 184.8,83.5
184.9,83.5 185.1,83.5 185.3,83.5 185.4,83.5 184.9,84.7 184.7,85.6 184.6,85.5 184.6,85.5 184.4,85.5 184.2,85.5 184.1,85.5
183.9,85.6 183.8,85.6 183.6,85.7 183.5,85.8 183.4,85.9 183.2,86 183.1,86.1 183,86.3 182.9,86.5 182.8,86.7 182.8,86.9
182.7,87.1 182.2,90.1 182,91.1 179.9,91.1 180.1,90 181.2,84.2 181.2,83.5 "/>
<polyline class="st6" points="189.9,87.7 189.8,87.8 189.8,87.9 189.7,88.1 189.6,88.3 189.5,88.5 189.5,88.7 189.3,88.8
189.2,88.9 189.1,89.1 189,89.2 188.9,89.3 188.7,89.3 188.6,89.4 188.4,89.4 188.2,89.4 188.1,89.5 187.8,89.5 187.7,89.4
187.6,89.4 187.4,89.3 187.3,89.3 187.2,89.2 187.1,89.1 187,88.9 186.9,88.8 186.8,88.6 186.8,88.5 186.7,88.3 186.7,88.1
186.7,87.9 186.7,87.7 186.7,87.4 186.7,87.2 186.8,87.1 186.8,87 186.8,86.8 186.9,86.6 187,86.4 187.1,86.2 187.2,86.1
187.3,85.9 187.4,85.7 187.5,85.6 187.7,85.5 187.8,85.4 188,85.3 188.2,85.2 188.4,85.2 188.5,85.1 188.8,85.1 188.9,85.2
189,85.2 189.3,85.3 189.5,85.4 189.6,85.5 189.7,85.6 189.8,85.8 189.9,85.9 190,86.1 "/>
<polyline class="st6" points="190,86.1 190,86.3 190,86.5 190,86.7 190,86.9 190,87.1 189.9,87.3 189.9,87.5 189.9,87.7 "/>
<polygon class="st5" points="141.5,90.3 141.5,90.3 141.3,90.5 141.2,90.6 141.1,90.6 141,90.7 140.9,90.8 140.8,90.9 140.7,90.9
140.5,91 140.4,91 140.2,91.1 140.1,91.1 139.9,91.2 139.7,91.2 139.6,91.2 139.4,91.2 139.2,91.2 139.1,91.2 138.8,91.2
138.5,91.1 138.3,91 138.1,90.8 137.9,90.7 137.7,90.5 137.6,90.4 137.5,90.2 137.4,90 137.3,89.8 137.3,89.5 137.2,89.3
137.2,89.1 137.2,88.9 137.3,88.7 137.3,88.5 137.3,88.3 137.5,88 137.6,87.7 137.8,87.5 138,87.2 138.2,87 138.4,86.8
138.8,86.7 139.1,86.5 139.4,86.4 139.8,86.3 140.3,86.3 140.7,86.2 141.2,86.2 141.8,86.2 142.4,86.2 142.4,86.1 142.4,86
142.4,85.9 142.4,85.7 142.3,85.6 142.3,85.5 142.2,85.4 142.2,85.3 142.1,85.2 142,85.2 141.9,85.1 141.7,85 141.6,85
141.5,84.9 141.4,84.9 141.2,84.9 141.1,84.9 140.7,84.9 140.6,84.9 140.4,84.9 140.2,84.9 140,84.9 139.9,84.9 139.7,85
139.5,85 139.3,85 139.1,85.1 138.9,85.1 138.8,85.1 138.6,85.2 138.4,85.3 138.5,84.8 138.8,83.8 138.8,83.7 138.9,83.7
139.1,83.6 139.2,83.6 139.3,83.6 139.5,83.5 139.6,83.5 139.8,83.5 140,83.5 140.2,83.4 140.4,83.4 140.7,83.4 140.9,83.4
141.2,83.4 141.4,83.4 141.9,83.4 142,83.4 142.3,83.4 142.5,83.5 142.7,83.5 143,83.6 143.2,83.7 143.4,83.8 143.6,84
143.8,84.1 143.9,84.3 144.1,84.5 144.2,84.7 144.2,84.9 144.3,85.1 144.3,85.4 144.3,85.6 143.9,87.5 141.3,87.5 141.2,87.5
141,87.5 140.7,87.6 140.5,87.6 140.4,87.7 140.1,87.7 140,87.8 139.8,87.9 139.6,88 139.5,88.1 139.4,88.2 139.4,88.3
139.3,88.4 139.3,88.5 139.2,88.7 139.2,88.8 139.2,89 139.3,89.1 139.3,89.2 139.4,89.3 139.5,89.4 139.6,89.5 139.7,89.6
139.9,89.6 140.1,89.6 140.3,89.6 140.5,89.6 140.7,89.6 140.8,89.6 140.9,89.5 141.1,89.5 141.2,89.3 141.4,89.2 141.5,89.1
141.6,88.9 141.7,88.8 141.8,88.6 141.9,88.5 141.9,88.3 141.9,88.1 142,88 142,87.9 142,87.7 142,87.6 141.9,87.6 141.8,87.6
141.7,87.5 141.5,87.5 141.3,87.5 143.9,87.5 143.6,89.3 143.6,89.4 143.6,89.5 143.6,89.5 143.6,89.6 143.6,89.7 143.6,89.8
143.5,90 143.5,90 143.5,90.2 143.5,90.3 143.5,90.4 143.5,90.5 143.5,90.8 143.5,90.9 143.5,91.1 141.6,91.1 141.7,90.3
141.6,90.2 141.5,90.2 141.5,90.3 "/>
<polyline class="st6" points="141.5,90.3 141.5,90.3 141.3,90.5 141.2,90.6 141.1,90.6 141,90.7 140.9,90.8 140.8,90.9
140.7,90.9 140.5,91 140.4,91 140.2,91.1 140.1,91.1 139.9,91.2 139.7,91.2 139.6,91.2 139.4,91.2 139.2,91.2 139.1,91.2
138.8,91.2 138.5,91.1 138.3,91 138.1,90.8 137.9,90.7 137.7,90.5 137.6,90.4 137.5,90.2 137.4,90 137.3,89.8 137.3,89.5
137.2,89.3 137.2,89.1 137.2,88.9 137.3,88.7 137.3,88.5 137.3,88.3 137.5,88 137.6,87.7 137.8,87.5 138,87.2 138.2,87
138.4,86.8 138.8,86.7 139.1,86.5 139.4,86.4 139.8,86.3 140.3,86.3 140.7,86.2 141.2,86.2 141.8,86.2 142.4,86.2 142.4,86.1
142.4,86 142.4,85.9 142.4,85.7 142.3,85.6 142.3,85.5 142.2,85.4 142.2,85.3 142.1,85.2 "/>
<polyline class="st6" points="142.1,85.2 142,85.2 141.9,85.1 141.7,85 141.6,85 141.5,84.9 141.4,84.9 141.2,84.9 141.1,84.9
140.7,84.9 140.6,84.9 140.4,84.9 140.2,84.9 140,84.9 139.9,84.9 139.7,85 139.5,85 139.3,85 139.1,85.1 138.9,85.1 138.8,85.1
138.6,85.2 138.4,85.3 138.5,84.8 138.8,83.8 138.8,83.7 138.9,83.7 139.1,83.6 139.2,83.6 139.3,83.6 139.5,83.5 139.6,83.5
139.8,83.5 140,83.5 140.2,83.4 140.4,83.4 140.7,83.4 140.9,83.4 141.2,83.4 141.4,83.4 141.9,83.4 142,83.4 142.3,83.4
142.5,83.5 142.7,83.5 143,83.6 143.2,83.7 143.4,83.8 143.6,84 143.8,84.1 143.9,84.3 144.1,84.5 144.2,84.7 144.2,84.9
144.3,85.1 144.3,85.4 144.3,85.6 143.6,89.3 143.6,89.4 143.6,89.5 "/>
<polyline class="st6" points="143.6,89.5 143.6,89.5 143.6,89.6 143.6,89.7 143.6,89.8 143.5,90 143.5,90 143.5,90.2 143.5,90.3
143.5,90.4 143.5,90.5 143.5,90.8 143.5,90.9 143.5,91.1 141.6,91.1 141.7,90.3 141.6,90.2 141.5,90.2 141.5,90.3 "/>
<polyline class="st6" points="142,87.6 141.9,87.6 141.8,87.6 141.7,87.5 141.5,87.5 141.3,87.5 141.2,87.5 141,87.5 140.7,87.6
140.5,87.6 140.4,87.7 140.1,87.7 140,87.8 139.8,87.9 139.6,88 139.5,88.1 139.4,88.2 139.4,88.3 139.3,88.4 139.3,88.5
139.2,88.7 139.2,88.8 139.2,89 139.3,89.1 139.3,89.2 139.4,89.3 139.5,89.4 139.6,89.5 139.7,89.6 139.9,89.6 140.1,89.6
140.3,89.6 140.5,89.6 140.7,89.6 140.8,89.6 140.9,89.5 141.1,89.5 141.2,89.3 141.4,89.2 141.5,89.1 141.6,88.9 141.7,88.8
141.8,88.6 141.9,88.5 141.9,88.3 141.9,88.1 142,88 142,87.9 142,87.7 142,87.6 "/>
<polygon class="st5" points="177.2,90.4 177.1,90.4 177,90.6 176.8,90.7 176.8,90.8 176.6,90.8 176.5,90.9 176.4,91 176.3,91
176.1,91.1 176,91.1 175.8,91.2 175.7,91.2 175.5,91.2 175.3,91.2 175.2,91.2 175,91.2 174.8,91.2 174.7,91.2 174.4,91.2
174.1,91.1 173.9,91 173.7,90.9 173.5,90.7 173.3,90.6 173.2,90.4 173.1,90.2 173,90 172.9,89.8 172.9,89.6 172.9,89.3
172.8,89.1 172.9,88.9 172.9,88.7 172.9,88.5 173,88.3 173.1,88 173.3,87.7 173.5,87.5 173.7,87.3 173.9,87.1 174.2,86.9
174.5,86.8 174.8,86.7 175.2,86.6 175.6,86.5 176,86.5 176.4,86.4 176.8,86.4 177.3,86.4 177.8,86.4 177.9,86.3 177.9,86.2
177.9,86.1 177.9,86 177.9,85.9 177.9,85.8 177.8,85.7 177.8,85.5 177.7,85.4 177.6,85.3 177.4,85.2 177.2,85.1 177,85.1
176.8,85 176.7,85 176.3,85 176.2,85 176,85 175.8,85 175.6,85.1 175.4,85.1 175.2,85.1 175,85.1 174.8,85.2 174.6,85.2
174.5,85.2 174.3,85.3 174.2,85.3 174,85.4 174.1,84.9 174.4,83.8 174.5,83.8 174.6,83.7 174.7,83.7 174.9,83.7 175,83.6
175.2,83.6 175.3,83.6 175.5,83.5 175.7,83.5 175.9,83.5 176.1,83.5 176.3,83.4 176.5,83.4 176.8,83.4 177.1,83.4 177.5,83.4
177.6,83.4 177.9,83.5 178.1,83.5 178.4,83.6 178.6,83.7 178.8,83.8 179,83.9 179.2,84.1 179.4,84.3 179.5,84.5 179.7,84.6
179.8,84.9 179.9,85.1 179.9,85.3 179.9,85.5 179.9,85.8 179.6,87.7 177.1,87.7 177,87.7 176.9,87.7 176.8,87.7 176.7,87.7
176.6,87.7 176.5,87.7 176.4,87.7 176.3,87.8 176.2,87.8 176.1,87.8 176,87.8 175.9,87.8 175.8,87.8 175.7,87.9 175.6,87.9
175.5,87.9 175.4,88 175.3,88 175.3,88.1 175.2,88.1 175.1,88.2 175,88.3 175,88.4 174.9,88.5 174.9,88.5 174.9,88.7 174.8,88.8
174.8,89 174.8,89.1 174.9,89.3 174.9,89.3 175,89.5 175.1,89.5 175.2,89.6 175.3,89.7 175.5,89.7 175.6,89.8 175.8,89.8
176,89.8 176.3,89.7 176.4,89.7 176.4,89.7 176.6,89.6 176.8,89.5 176.9,89.3 177.1,89.2 177.2,89.1 177.3,88.9 177.3,88.7
177.4,88.6 177.5,88.4 177.5,88.3 177.5,88.1 177.6,88 177.6,87.9 177.6,87.8 177.5,87.8 177.5,87.7 177.4,87.7 177.3,87.7
177.2,87.7 179.6,87.7 179.3,89.3 179.3,89.4 179.2,89.5 179.2,89.6 179.2,89.7 179.2,89.8 179.2,89.9 179.2,90 179.1,90.2
179.1,90.3 179.1,90.4 179.1,90.5 179.1,90.7 179.1,90.8 179.1,90.9 179.1,91.1 177.3,91.1 177.3,90.4 177.2,90.4 177.2,90.4
177.2,90.4 "/>
<polyline class="st6" points="177.2,90.4 177.1,90.4 177,90.6 176.8,90.7 176.8,90.8 176.6,90.8 176.5,90.9 176.4,91 176.3,91
176.1,91.1 176,91.1 175.8,91.2 175.7,91.2 175.5,91.2 175.3,91.2 175.2,91.2 175,91.2 174.8,91.2 174.7,91.2 174.4,91.2
174.1,91.1 173.9,91 173.7,90.9 173.5,90.7 173.3,90.6 173.2,90.4 173.1,90.2 173,90 172.9,89.8 172.9,89.6 172.9,89.3
172.8,89.1 172.9,88.9 172.9,88.7 172.9,88.5 173,88.3 173.1,88 173.3,87.7 173.5,87.5 173.7,87.3 173.9,87.1 174.2,86.9
174.5,86.8 174.8,86.7 175.2,86.6 175.6,86.5 176,86.5 176.4,86.4 176.8,86.4 177.3,86.4 177.8,86.4 177.9,86.3 177.9,86.2
177.9,86.1 177.9,86 177.9,85.9 177.9,85.8 177.8,85.7 177.8,85.5 177.7,85.4 "/>
<polyline class="st6" points="177.7,85.4 177.6,85.3 177.4,85.2 177.2,85.1 177,85.1 176.8,85 176.7,85 176.3,85 176.2,85 176,85
175.8,85 175.6,85.1 175.4,85.1 175.2,85.1 175,85.1 174.8,85.2 174.6,85.2 174.5,85.2 174.3,85.3 174.2,85.3 174,85.4
174.1,84.9 174.4,83.8 174.5,83.8 174.6,83.7 174.7,83.7 174.9,83.7 175,83.6 175.2,83.6 175.3,83.6 175.5,83.5 175.7,83.5
175.9,83.5 176.1,83.5 176.3,83.4 176.5,83.4 176.8,83.4 177.1,83.4 177.5,83.4 177.6,83.4 177.9,83.5 178.1,83.5 178.4,83.6
178.6,83.7 178.8,83.8 179,83.9 179.2,84.1 179.4,84.3 179.5,84.5 179.7,84.6 179.8,84.9 179.9,85.1 179.9,85.3 179.9,85.5
179.9,85.8 179.3,89.3 179.3,89.4 179.2,89.5 179.2,89.6 179.2,89.7 "/>
<polyline class="st6" points="179.2,89.7 179.2,89.8 179.2,89.9 179.2,90 179.1,90.2 179.1,90.3 179.1,90.4 179.1,90.5
179.1,90.7 179.1,90.8 179.1,90.9 179.1,91.1 177.3,91.1 177.3,90.4 177.2,90.4 177.2,90.4 177.2,90.4 "/>
<polyline class="st6" points="177.5,87.8 177.5,87.7 177.4,87.7 177.3,87.7 177.2,87.7 177.1,87.7 177,87.7 176.9,87.7
176.8,87.7 176.7,87.7 176.6,87.7 176.5,87.7 176.4,87.7 176.3,87.8 176.2,87.8 176.1,87.8 176,87.8 175.9,87.8 175.8,87.8
175.7,87.9 175.6,87.9 175.5,87.9 175.4,88 175.3,88 175.3,88.1 175.2,88.1 175.1,88.2 175,88.3 175,88.4 174.9,88.5 174.9,88.5
174.9,88.7 174.8,88.8 174.8,89 174.8,89.1 174.9,89.3 174.9,89.3 175,89.5 175.1,89.5 175.2,89.6 175.3,89.7 175.5,89.7
175.6,89.8 175.8,89.8 176,89.8 176.3,89.7 176.4,89.7 176.4,89.7 176.6,89.6 176.8,89.5 176.9,89.3 177.1,89.2 177.2,89.1
177.3,88.9 177.3,88.7 177.4,88.6 177.5,88.4 177.5,88.3 177.5,88.1 177.6,88 "/>
<polyline class="st6" points="177.6,88 177.6,87.9 177.6,87.8 177.5,87.8 "/>
<polygon class="st4" points="151.7,81.8 153.7,81.8 153.3,83.5 154.5,83.5 154.2,85.2 153,85.2 152.5,88.5 152.4,88.5 152.4,88.6
152.4,88.8 152.4,88.9 152.4,89.1 152.5,89.2 152.5,89.3 152.6,89.3 152.7,89.4 152.8,89.4 152.9,89.4 153,89.4 153.3,89.4
153.5,89.4 153.7,89.4 153.9,89.4 153.5,91.1 153.2,91.1 152.9,91.2 152.4,91.2 152,91.2 151.6,91.2 151.3,91.1 151,91
150.8,90.9 150.6,90.8 150.5,90.6 150.4,90.4 150.3,90.2 150.3,90 150.3,89.8 150.3,89.5 150.3,89.2 150.4,88.9 151.5,82.8
151.7,81.8 "/>
<polygon class="st5" points="160.6,89.1 160.3,90.8 160.2,90.8 160.1,90.9 160,90.9 159.9,91 159.8,91 159.7,91 159.6,91.1
159.4,91.1 159.3,91.1 159.1,91.1 158.9,91.2 158.7,91.2 158.5,91.2 158.3,91.2 158,91.2 157.5,91.2 157.3,91.2 157,91.1
156.6,91.1 156.3,91 155.9,90.8 155.6,90.7 155.3,90.5 155.1,90.3 154.9,90 154.7,89.7 154.5,89.4 154.4,89.1 154.3,88.7
154.2,88.3 154.2,87.8 154.2,87.3 154.2,87.1 154.3,86.9 154.4,86.5 154.5,86.1 154.6,85.7 154.8,85.3 155,85 155.2,84.7
155.5,84.4 155.7,84.2 156,84 156.3,83.8 156.6,83.7 156.9,83.5 157.2,83.4 157.6,83.4 157.9,83.4 158.1,83.4 158.4,83.4
158.8,83.4 159.2,83.5 159.5,83.7 159.9,83.8 160.1,84 160.4,84.2 160.6,84.5 160.8,84.8 160.8,84.9 157.7,84.9 157.5,84.9
157.3,85 157.1,85.1 157,85.2 156.8,85.4 156.7,85.5 156.6,85.6 156.5,85.8 156.4,85.9 156.4,86.1 156.4,86.2 156.4,86.3
156.4,86.4 156.5,86.4 159,86.4 159.1,86.3 159.1,86.2 159.1,86.1 159.1,86 159,85.8 159,85.7 158.9,85.6 158.9,85.5 158.8,85.4
158.7,85.2 158.5,85.1 158.3,85 158.1,84.9 157.9,84.9 157.8,84.9 160.8,84.9 160.9,85.1 161,85.5 161.1,85.9 161.1,86.3
161,86.8 160.9,87.3 160.8,87.9 156.2,87.9 156.1,87.9 156.1,88 156.1,88.1 156.1,88.3 156.1,88.4 156.1,88.5 156.2,88.7
156.3,88.8 156.4,89 156.5,89.1 156.7,89.3 156.9,89.4 157.1,89.5 157.3,89.5 157.6,89.6 157.6,89.6 157.8,89.6 157.9,89.6
158.1,89.6 158.3,89.6 158.4,89.6 158.6,89.6 158.8,89.6 159,89.6 159.2,89.5 159.4,89.5 159.6,89.4 159.7,89.4 159.9,89.3
160.1,89.3 160.4,89.2 160.6,89.1 "/>
<polyline class="st6" points="160.6,89.1 160.3,90.8 160.2,90.8 160.1,90.9 160,90.9 159.9,91 159.8,91 159.7,91 159.6,91.1
159.4,91.1 159.3,91.1 159.1,91.1 158.9,91.2 158.7,91.2 158.5,91.2 158.3,91.2 158,91.2 157.5,91.2 157.3,91.2 157,91.1
156.6,91.1 156.3,91 155.9,90.8 155.6,90.7 155.3,90.5 155.1,90.3 154.9,90 154.7,89.7 154.5,89.4 154.4,89.1 154.3,88.7
154.2,88.3 154.2,87.8 154.2,87.3 154.2,87.1 154.3,86.9 154.4,86.5 154.5,86.1 154.6,85.7 154.8,85.3 155,85 155.2,84.7
155.5,84.4 155.7,84.2 156,84 156.3,83.8 156.6,83.7 156.9,83.5 157.2,83.4 157.6,83.4 157.9,83.4 158.1,83.4 158.4,83.4
158.8,83.4 159.2,83.5 159.5,83.7 159.9,83.8 160.1,84 160.4,84.2 160.6,84.5 "/>
<polyline class="st6" points="160.6,84.5 160.8,84.8 160.9,85.1 161,85.5 161.1,85.9 161.1,86.3 161,86.8 160.9,87.3 160.8,87.9
156.2,87.9 156.1,87.9 156.1,88 156.1,88.1 156.1,88.3 156.1,88.4 156.1,88.5 156.2,88.7 156.3,88.8 156.4,89 156.5,89.1
156.7,89.3 156.9,89.4 157.1,89.5 157.3,89.5 157.6,89.6 157.6,89.6 157.8,89.6 157.9,89.6 158.1,89.6 158.3,89.6 158.4,89.6
158.6,89.6 158.8,89.6 159,89.6 159.2,89.5 159.4,89.5 159.6,89.4 159.7,89.4 159.9,89.3 160.1,89.3 160.4,89.2 160.6,89.1 "/>
<polyline class="st6" points="159,86.4 159.1,86.3 159.1,86.2 159.1,86.1 159.1,86 159,85.8 159,85.7 158.9,85.6 158.9,85.5
158.8,85.4 158.7,85.2 158.5,85.1 158.3,85 158.1,84.9 157.9,84.9 157.7,84.9 157.5,84.9 157.3,85 157.1,85.1 157,85.2
156.8,85.4 156.7,85.5 156.6,85.6 156.5,85.8 156.4,85.9 156.4,86.1 156.4,86.2 156.4,86.3 156.4,86.4 156.5,86.4 159,86.4 "/>
<polygon class="st5" points="193.1,91 193.1,89.8 193.6,89.8 193.7,89.8 193.8,89.9 193.8,89.9 193.9,89.9 193.9,89.9 194,90
194,90 194,90 194,90.1 194,90.2 194,90.2 194,90.3 194,90.4 193.8,90.4 193.8,90.3 193.8,90.3 193.9,90.3 193.9,90.2 193.9,90.2
193.9,90.1 193.9,90.1 193.8,90 193.8,90 193.7,90 193.7,90 193.6,90 193.3,90 193.3,90.4 193.7,90.4 193.8,90.4 194,90.4
193.9,90.4 193.9,90.4 193.8,90.5 193.8,90.5 194.1,91 193.9,91 193.6,90.5 193.3,90.5 193.3,91 193.1,91 "/>
<polygon class="st5" points="193.5,91.3 193.6,91.3 193.7,91.3 193.8,91.3 193.8,91.3 193.9,91.2 194,91.2 194,91.2 194.1,91.1
194.2,91.1 194.2,91 194.3,90.9 194.3,90.9 194.3,90.8 194.4,90.7 194.4,90.7 194.4,90.6 194.4,90.5 194.4,90.4 194.4,90.4
194.4,90.3 194.4,90.2 194.4,90.1 194.3,90 194.3,90 194.3,89.9 194.2,89.9 194.2,89.8 194.1,89.7 194,89.7 194,89.6 193.9,89.6
193.8,89.6 193.8,89.6 193.7,89.6 193.6,89.5 193.5,89.5 193.5,89.5 193.4,89.6 193.3,89.6 193.2,89.6 193.2,89.6 193.1,89.6
193,89.7 193,89.7 192.9,89.8 192.9,89.9 192.8,89.9 192.8,90 192.7,90 192.7,90.1 192.7,90.2 192.7,90.3 192.7,90.4 192.7,90.5
192.7,90.6 192.7,90.7 192.7,90.7 192.7,90.8 192.8,90.9 192.8,90.9 192.9,91 192.9,91.1 193,91.1 193,91.2 193.1,91.2
193.2,91.2 193.2,91.3 193.3,91.3 193.4,91.3 193.5,91.3 193.5,91.3 193.5,91.2 193.5,91.2 193.4,91.2 193.3,91.2 193.2,91.2
193.2,91.1 193.1,91.1 193,91 193,91 192.9,90.9 192.9,90.9 192.8,90.8 192.8,90.7 192.8,90.7 192.8,90.6 192.7,90.5 192.7,90.4
192.8,90.3 192.8,90.2 192.8,90.1 192.8,90 192.9,90 192.9,89.9 193,89.9 193,89.8 193.1,89.8 193.2,89.7 193.2,89.7 193.3,89.6
193.4,89.6 193.5,89.6 193.6,89.6 193.7,89.6 193.8,89.6 193.8,89.7 193.9,89.7 194,89.8 194,89.8 194.1,89.9 194.1,89.9
194.2,90 194.2,90 194.3,90.1 194.3,90.2 194.3,90.3 194.3,90.4 194.3,90.4 194.3,90.5 194.3,90.6 194.3,90.7 194.3,90.7
194.2,90.8 194.2,90.9 194.1,90.9 194.1,91 194,91 194,91.1 193.9,91.1 193.8,91.2 193.8,91.2 193.7,91.2 193.6,91.2 193.5,91.2
193.5,91.3 "/>
</g>
</g>
<polygon class="st7" points="24.1,63.5 106.3,63.5 106.3,112.2 24.1,112.2 24.1,63.5 "/>
<g>
<polygon class="st8" points="216.5,62.2 291.7,62.2 291.7,109.4 216.5,109.4 216.5,62.2 "/>
<g>
<g>
<path class="st9" d="M226.6,78.2c0.9-0.2,2.4-0.3,3.8-0.3c2.1,0,3.4,0.4,4.4,1.1c0.8,0.6,1.3,1.5,1.3,2.8c0,1.5-1,2.8-2.7,3.4v0
c1.5,0.4,3.3,1.6,3.3,3.9c0,1.4-0.6,2.4-1.4,3.1c-1.1,1-3,1.5-5.6,1.5c-1.4,0-2.5-0.1-3.2-0.2V78.2z M228.7,84.6h1.9
c2.2,0,3.5-1.1,3.5-2.6c0-1.8-1.4-2.6-3.6-2.6c-1,0-1.5,0.1-1.9,0.1V84.6z M228.7,92.1c0.4,0.1,1,0.1,1.8,0.1
c2.2,0,4.2-0.8,4.2-3.1c0-2.1-1.9-3-4.2-3h-1.7V92.1z"/>
<path class="st9" d="M242.2,88.7l-1.7,4.9h-2.2l5.5-15.7h2.5l5.5,15.7h-2.2l-1.7-4.9H242.2z M247.6,87.1l-1.6-4.5
c-0.4-1-0.6-2-0.8-2.9h-0.1c-0.2,0.9-0.5,1.9-0.8,2.8l-1.6,4.5H247.6z"/>
<path class="st9" d="M254.3,93.7V78h2.3l5.2,8c1.2,1.8,2.1,3.5,2.9,5.1l0,0c-0.2-2.1-0.2-4-0.2-6.5V78h2v15.7h-2.1l-5.1-8
c-1.1-1.7-2.2-3.5-3-5.2l-0.1,0c0.1,2,0.2,3.9,0.2,6.5v6.7H254.3z"/>
<path class="st9" d="M270.2,78h2.1v7.6h0.1c0.4-0.6,0.9-1.2,1.3-1.7l5-5.9h2.6l-5.9,6.7l6.3,9h-2.5l-5.3-7.7l-1.5,1.7v6h-2.1V78z
"/>
</g>
</g>
</g>
<g>
<path class="st10" d="M100.1,15.7h9.9c5.3,0,7.3,2.7,7,6.7c-0.5,6.5-4.5,10.2-9.7,10.2h-2.6c-0.7,0-1.2,0.5-1.4,1.8l-1.1,7.5
c-0.1,0.5-0.3,0.8-0.7,0.8h-6.2c-0.6,0-0.8-0.4-0.6-1.4l3.8-24C98.5,16.1,99,15.7,100.1,15.7z"/>
<path class="st11" d="M143.2,15.2c3.3,0,6.4,1.8,6,6.3c-0.5,5.4-3.4,8.4-7.9,8.4h-4c-0.6,0-0.8,0.5-1,1.4l-0.8,4.9
c-0.1,0.7-0.5,1.1-1.1,1.1h-3.7c-0.6,0-0.8-0.4-0.7-1.2l3.1-19.6c0.1-1,0.5-1.3,1.2-1.3H143.2L143.2,15.2z M137.1,25.7h3
c1.9-0.1,3.1-1.4,3.3-3.7c0.1-1.5-0.9-2.5-2.5-2.5l-2.8,0L137.1,25.7L137.1,25.7z M159.2,35.8c0.3-0.3,0.7-0.5,0.6-0.1l-0.1,0.9
c-0.1,0.5,0.1,0.7,0.6,0.7h3.3c0.6,0,0.8-0.2,1-1.1l2-12.7c0.1-0.6-0.1-0.9-0.5-0.9h-3.6c-0.3,0-0.5,0.2-0.6,0.7l-0.1,0.8
c-0.1,0.4-0.3,0.5-0.4,0.1c-0.6-1.5-2.2-2.1-4.4-2.1c-5.1,0.1-8.5,3.9-8.8,8.9c-0.3,3.8,2.4,6.8,6,6.8
C156.7,37.8,157.9,37,159.2,35.8L159.2,35.8z M156.5,33.9c-2.2,0-3.7-1.7-3.4-3.9c0.3-2.1,2.4-3.9,4.5-3.9c2.2,0,3.7,1.7,3.4,3.9
C160.7,32.1,158.6,33.9,156.5,33.9L156.5,33.9z M173,22.6h-3.3c-0.7,0-1,0.5-0.7,1.1l4.1,12.1l-4.1,5.8c-0.3,0.5-0.1,0.9,0.4,0.9
h3.7c0.6,0,0.8-0.1,1.1-0.5l12.7-18.2c0.4-0.6,0.2-1.1-0.4-1.2l-3.5,0c-0.6,0-0.9,0.2-1.2,0.7l-5.3,7.7l-2.4-7.7
C174,22.9,173.6,22.6,173,22.6z"/>
<path class="st10" d="M200.2,15.2c3.3,0,6.4,1.8,6,6.3c-0.5,5.4-3.4,8.4-7.9,8.4h-4c-0.6,0-0.8,0.5-1,1.4l-0.8,4.9
c-0.1,0.7-0.5,1.1-1.1,1.1h-3.7c-0.6,0-0.8-0.4-0.7-1.2l3.1-19.6c0.1-1,0.5-1.3,1.2-1.3H200.2L200.2,15.2z M194.1,25.7h3
c1.9-0.1,3.1-1.4,3.3-3.7c0.1-1.5-0.9-2.5-2.5-2.5l-2.8,0L194.1,25.7L194.1,25.7z M216.2,35.8c0.3-0.3,0.7-0.5,0.6-0.1l-0.1,0.9
c-0.1,0.5,0.1,0.7,0.6,0.7h3.3c0.6,0,0.8-0.2,1-1.1l2-12.7c0.1-0.6-0.1-0.9-0.5-0.9h-3.6c-0.3,0-0.5,0.2-0.6,0.7l-0.1,0.8
c-0.1,0.4-0.3,0.5-0.4,0.1c-0.6-1.5-2.2-2.1-4.4-2.1c-5.1,0.1-8.5,3.9-8.8,8.9c-0.3,3.8,2.4,6.8,6,6.8
C213.7,37.8,214.9,37,216.2,35.8L216.2,35.8z M213.5,33.9c-2.2,0-3.7-1.7-3.4-3.9c0.3-2.1,2.4-3.9,4.5-3.9c2.2,0,3.7,1.7,3.4,3.9
C217.7,32.1,215.6,33.9,213.5,33.9L213.5,33.9z M228.6,37.4h-3.8c-0.3,0-0.5-0.2-0.5-0.5l3.3-21.1c0-0.3,0.3-0.5,0.6-0.5h3.8
c0.3,0,0.5,0.2,0.5,0.5l-3.3,21.1C229.2,37.2,228.9,37.4,228.6,37.4z"/>
<path class="st11" d="M93.9,7.4h9.9c2.8,0,6.1,0.1,8.3,2c1.5,1.3,2.3,3.4,2.1,5.6c-0.6,7.6-5.1,11.8-11.2,11.8h-4.9
c-0.8,0-1.4,0.6-1.6,2l-1.4,8.7c-0.1,0.6-0.3,0.9-0.8,0.9h-6.1c-0.7,0-0.9-0.5-0.7-1.6L91.9,9C92.1,7.9,92.7,7.4,93.9,7.4z"/>
<path class="st12" d="M96.6,28.1l1.7-11c0.2-1,0.7-1.4,1.7-1.4h9.9c1.6,0,3,0.3,4,0.7c-1,6.7-5.4,10.5-11.1,10.5h-4.9
C97.4,26.9,96.9,27.2,96.6,28.1z"/>
</g>
<g>
<polygon class="st13" points="54.8,98.3 58.4,77.4 64.1,77.4 60.5,98.3 "/>
<path class="st13" d="M81.2,77.9C80,77.5,78.3,77,76.1,77c-5.6,0-9.6,2.8-9.6,6.9c0,3,2.8,4.7,5,5.7c2.2,1,3,1.7,3,2.6
c0,1.4-1.8,2-3.4,2c-2.3,0-3.5-0.3-5.4-1.1l-0.7-0.3l-0.8,4.7c1.3,0.6,3.8,1.1,6.3,1.1c6,0,9.9-2.8,9.9-7.2c0-2.4-1.5-4.2-4.8-5.7
c-2-1-3.2-1.6-3.2-2.6c0-0.9,1-1.8,3.3-1.8c1.9,0,3.2,0.4,4.3,0.8l0.5,0.2L81.2,77.9z"/>
<path class="st13" d="M95.8,77.4h-4.4c-1.4,0-2.4,0.4-3,1.7l-8.5,19.2h6c0,0,1-2.6,1.2-3.1c0.7,0,6.5,0,7.3,0
c0.2,0.7,0.7,3.1,0.7,3.1h5.3L95.8,77.4z M88.7,90.9c0.5-1.2,2.3-5.9,2.3-5.9c0,0.1,0.5-1.2,0.8-2l0.4,1.8c0,0,1.1,5,1.3,6.1H88.7z
"/>
<path class="st13" d="M50,77.4l-5.6,14.3l-0.6-2.9c-1-3.3-4.3-7-7.9-8.8L41,98.3l6,0l9-20.9H50z"/>
<path class="st14" d="M39.3,77.4h-9.2L30,77.8c7.1,1.7,11.9,5.9,13.8,11l-2-9.6C41.5,77.8,40.5,77.4,39.3,77.4"/>
</g>
<g>
<line class="st15" x1="315.6" y1="29.5" x2="243.4" y2="29.5"/>
<line class="st16" x1="4.6" y1="27" x2="4.6" y2="121.8"/>
<line class="st16" x1="315.6" y1="27" x2="315.6" y2="121.8"/>
<line class="st16" x1="3.6" y1="121.8" x2="315.6" y2="121.8"/>
<line class="st15" x1="75.8" y1="29.5" x2="3.6" y2="29.5"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 33 KiB

+32
View File
@@ -0,0 +1,32 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Settings for the PayPal payment gateway
*
* @package paygw_paypal
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
if ($ADMIN->fulltree) {
$settings->add(new admin_setting_heading('paygw_paypal_settings', '', get_string('pluginname_desc', 'paygw_paypal')));
\core_payment\helper::add_common_gateway_settings($settings, 'paygw_paypal');
}
+4
View File
@@ -0,0 +1,4 @@
.core_payment_gateways_modal .paypal .icon {
height: 40px;
width: auto;
}
@@ -0,0 +1,35 @@
{{!
This file is part of Moodle - http://moodle.org/
Moodle is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Moodle is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Moodle. If not, see <http://www.gnu.org/licenses/>.
}}
{{!
@template paygw_paypal/paypal_button_placeholder
Classes required for JS:
* none
Data attributes required for JS:
* none
Context variables required for this template:
* none
Example context (json):
{}
}}
<div class="bg-pulse-grey rounded" style="width: 100%; height: 45px; margin-bottom: 14px;"></div>
<div class="bg-pulse-grey rounded" style="width: 100%; height: 45px; margin-bottom: 14px;"></div>
<div class="bg-pulse-grey" style="width: 110px; height: 16px; margin: 10px auto; position: relative; bottom: 3px;"></div>
+29
View File
@@ -0,0 +1,29 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version information
*
* @package paygw_paypal
* @copyright 2019 Shamim Rezaie <shamim@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'paygw_paypal'; // Full name of the plugin (used for diagnostics).