Version Description
- Added Magic Checkout feature.
Download this release
Release Info
Developer | razorpay |
Plugin | Razorpay for WooCommerce |
Version | 3.0.0 |
Comparing to | |
See all releases |
Code changes from version 2.8.6 to 3.0.0
- btn-1cc-checkout.js +235 -0
- debug.md +58 -0
- includes/api/api.php +229 -0
- includes/api/auth.php +12 -0
- includes/api/cart.php +35 -0
- includes/api/coupon-apply.php +219 -0
- includes/api/coupon-get.php +301 -0
- includes/api/order.php +227 -0
- includes/api/save-abandonment-data.php +162 -0
- includes/api/shipping-info.php +422 -0
- includes/debug.php +141 -0
- includes/razorpay-route.php +4 -4
- includes/razorpay-webhook.php +87 -98
- includes/state-map.php +110 -0
- includes/utils.php +110 -0
- public/css/1cc-product-checkout.css +79 -0
- public/css/bootstrap.min.css +7 -0
- public/css/woo_route.css +193 -0
- public/images/payment.png +0 -0
- public/images/rzp-spinner.svg +5 -0
- public/js/admin-rzp-settings.js +21 -0
- public/js/bootstrap.min.js +7 -0
- public/js/woo_route.js +87 -0
- readme.txt +4 -1
- templates/rzp-cart-checkout-btn.php +23 -0
- templates/rzp-mini-checkout-btn.php +17 -0
- templates/rzp-pdp-checkout-btn.php +71 -0
- woo-razorpay.php +650 -26
btn-1cc-checkout.js
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
window.addEventListener('DOMContentLoaded', function() {
|
2 |
+
|
3 |
+
var btn = document.getElementById('btn-1cc');
|
4 |
+
var btnMini = document.getElementById('btn-1cc-mini-cart');
|
5 |
+
var btnPdp = document.getElementById('btn-1cc-pdp');
|
6 |
+
var rzpSpinnerBackdrop = document.getElementById('rzp-spinner-backdrop');
|
7 |
+
var rzpSpinner = document.getElementById('rzp-spinner');
|
8 |
+
var pageURL = jQuery(location).attr('href');
|
9 |
+
var url = new URL(pageURL);
|
10 |
+
var accessToken = new URLSearchParams(url.search).get('wcf_ac_token');
|
11 |
+
|
12 |
+
// event triggered by wc on any cart change
|
13 |
+
// as input function is the same, duplicate event listeners are NOT called
|
14 |
+
jQuery(document.body).on('updated_cart_totals', function(event) {
|
15 |
+
var btn = document.getElementById('btn-1cc');
|
16 |
+
if (btn !== null) {
|
17 |
+
btn.addEventListener('click', openRzpCheckout);
|
18 |
+
}
|
19 |
+
|
20 |
+
var btnMini = document.getElementById('btn-1cc-mini-cart');
|
21 |
+
if (btnMini !== null) {
|
22 |
+
btnMini.addEventListener('click', openRzpCheckout);
|
23 |
+
}
|
24 |
+
});
|
25 |
+
|
26 |
+
function addEventListenerToMinicart(wcEvent) {
|
27 |
+
jQuery(document.body).on(wcEvent, function(event) {
|
28 |
+
var btnMini = document.getElementById('btn-1cc-mini-cart');
|
29 |
+
if (btnMini !== null) {
|
30 |
+
btnMini.addEventListener('click', openRzpCheckout);
|
31 |
+
}
|
32 |
+
});
|
33 |
+
}
|
34 |
+
|
35 |
+
addEventListenerToMinicart('wc_fragments_refreshed');
|
36 |
+
addEventListenerToMinicart('wc_fragments_loaded');
|
37 |
+
addEventListenerToMinicart('added_to_cart');
|
38 |
+
|
39 |
+
if (btnPdp != null) {
|
40 |
+
btnPdp.onclick = function() {
|
41 |
+
|
42 |
+
var pdpCheckout = btnPdp.getAttribute('pdp_checkout');
|
43 |
+
var productId = btnPdp.getAttribute('product_id');
|
44 |
+
var quantity = btnPdp.getAttribute('quantity');
|
45 |
+
|
46 |
+
rzp1ccCheckoutData.pdpCheckout = pdpCheckout;
|
47 |
+
rzp1ccCheckoutData.productId = productId;
|
48 |
+
rzp1ccCheckoutData.quantity = quantity;
|
49 |
+
|
50 |
+
if (btnPdp.getAttribute('variation_id') != null) {
|
51 |
+
var variationId = btnPdp.getAttribute('variation_id');
|
52 |
+
var variations = btnPdp.getAttribute('variations');
|
53 |
+
|
54 |
+
rzp1ccCheckoutData.variationId = variationId;
|
55 |
+
rzp1ccCheckoutData.variations = variations;
|
56 |
+
}
|
57 |
+
|
58 |
+
//To support custom product fields plugin.
|
59 |
+
const customFieldForm = document.getElementsByClassName('wcpa_form_outer');
|
60 |
+
|
61 |
+
if (customFieldForm && customFieldForm.length > 0) {
|
62 |
+
|
63 |
+
var customProductFieldForm = customFieldForm[0];
|
64 |
+
|
65 |
+
var fieldValues = customProductFieldForm.getElementsByTagName('input');
|
66 |
+
var fieldKey = customProductFieldForm.getElementsByTagName('label');
|
67 |
+
var fieldArray = [];
|
68 |
+
var fieldObj = {};
|
69 |
+
|
70 |
+
for (i = 0; i < fieldKey.length; i++) {
|
71 |
+
fieldObj[fieldKey[i].innerText] = fieldValues[i].value;
|
72 |
+
}
|
73 |
+
|
74 |
+
rzp1ccCheckoutData.fieldObj = fieldObj;
|
75 |
+
}
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
// fetch opts from server and open 1cc modal
|
80 |
+
var rzp1cc = {
|
81 |
+
orderApi: rzp1ccCheckoutData.siteurl + '/wp-json/1cc/v1/order/create',
|
82 |
+
saveAbandonedCartApi: rzp1ccCheckoutData.siteurl + '/wp-json/1cc/v1/abandoned-cart',
|
83 |
+
makeRequest: function(url, body) {
|
84 |
+
return new Promise(function(resolve, reject) {
|
85 |
+
var xhr = new XMLHttpRequest();
|
86 |
+
xhr.open('POST', url, true);
|
87 |
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
88 |
+
xhr.setRequestHeader('X-WP-Nonce', rzp1ccCheckoutData.nonce);
|
89 |
+
xhr.onload = function() {
|
90 |
+
if (this.status === 200) {
|
91 |
+
resolve(rzp1cc.parseIfJson(this.response));
|
92 |
+
} else {
|
93 |
+
reject({ status: this.status, response: rzp1cc.parseIfJson(this.response) });
|
94 |
+
}
|
95 |
+
}
|
96 |
+
xhr.onerror = function () {
|
97 |
+
reject({ status: this.status, statusText: this.statusText});
|
98 |
+
};
|
99 |
+
xhr.send(JSON.stringify(body));
|
100 |
+
});
|
101 |
+
},
|
102 |
+
parseIfJson: function (str) {
|
103 |
+
try {
|
104 |
+
return JSON.parse(str);
|
105 |
+
} catch (e) {
|
106 |
+
return str;
|
107 |
+
}
|
108 |
+
},
|
109 |
+
setDisabled: function(id, state) {
|
110 |
+
if (typeof state === 'undefined') {
|
111 |
+
state = true;
|
112 |
+
}
|
113 |
+
var elem = document.getElementById(id);
|
114 |
+
|
115 |
+
if(elem != null)
|
116 |
+
{
|
117 |
+
if (state === false) {
|
118 |
+
elem.removeAttribute('disabled');
|
119 |
+
} else {
|
120 |
+
elem.setAttribute('disabled', state);
|
121 |
+
}
|
122 |
+
}
|
123 |
+
},
|
124 |
+
showSpinner: function(state) {
|
125 |
+
if (rzpSpinnerBackdrop == null) {
|
126 |
+
rzpSpinnerBackdrop = document.getElementById('rzp-spinner-backdrop');
|
127 |
+
}
|
128 |
+
if (rzpSpinner == null) {
|
129 |
+
rzpSpinner = document.getElementById('rzp-spinner');
|
130 |
+
}
|
131 |
+
if (state === true) {
|
132 |
+
rzpSpinnerBackdrop.classList.add('show');
|
133 |
+
rzpSpinner.classList.add('show');
|
134 |
+
} else {
|
135 |
+
rzpSpinnerBackdrop.classList.remove('show');
|
136 |
+
rzpSpinner.classList.remove('show');
|
137 |
+
}
|
138 |
+
},
|
139 |
+
handleAbandonmentCart: function(rzpOrderId) {
|
140 |
+
if(rzpOrderId != null) {
|
141 |
+
var xhr = new XMLHttpRequest();
|
142 |
+
try {
|
143 |
+
var body = {
|
144 |
+
order_id: rzpOrderId
|
145 |
+
};
|
146 |
+
xhr.open('POST', rzp1cc.saveAbandonedCartApi, true);
|
147 |
+
xhr.setRequestHeader('Content-Type', 'application/json');
|
148 |
+
xhr.send(JSON.stringify(body));
|
149 |
+
} catch (e) {
|
150 |
+
|
151 |
+
}
|
152 |
+
}
|
153 |
+
},
|
154 |
+
enableCheckoutButtons: function() {
|
155 |
+
rzp1cc.setDisabled('btn-1cc', false);
|
156 |
+
rzp1cc.setDisabled('btn-1cc-mini-cart', false);
|
157 |
+
rzp1cc.setDisabled('btn-1cc-pdp', false);
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
if (btn !== null) {
|
162 |
+
btn.addEventListener('click', openRzpCheckout);
|
163 |
+
}
|
164 |
+
|
165 |
+
if (btnMini !== null) {
|
166 |
+
btnMini.addEventListener('click', openRzpCheckout);
|
167 |
+
}
|
168 |
+
|
169 |
+
if (btnPdp !== null) {
|
170 |
+
btnPdp.addEventListener('click', openRzpCheckout);
|
171 |
+
}
|
172 |
+
|
173 |
+
async function openRzpCheckout(e) {
|
174 |
+
e.preventDefault();
|
175 |
+
rzp1cc.showSpinner(true);
|
176 |
+
|
177 |
+
if (accessToken !== null)
|
178 |
+
{
|
179 |
+
rzp1ccCheckoutData.token = accessToken;
|
180 |
+
}
|
181 |
+
|
182 |
+
var body = rzp1ccCheckoutData;
|
183 |
+
|
184 |
+
rzp1cc.setDisabled('btn-1cc');
|
185 |
+
rzp1cc.setDisabled('btn-1cc-mini-cart');
|
186 |
+
rzp1cc.setDisabled('btn-1cc-pdp');
|
187 |
+
|
188 |
+
rzp1cc.makeRequest(rzp1cc.orderApi, body)
|
189 |
+
.then(data => {
|
190 |
+
rzp1cc.showSpinner(false);
|
191 |
+
try {
|
192 |
+
var razorpayCheckout = new Razorpay({
|
193 |
+
...data,
|
194 |
+
modal: {
|
195 |
+
ondismiss: function() {
|
196 |
+
rzp1cc.handleAbandonmentCart(data.order_id);
|
197 |
+
rzp1cc.enableCheckoutButtons();
|
198 |
+
}
|
199 |
+
},
|
200 |
+
});
|
201 |
+
razorpayCheckout.open();
|
202 |
+
|
203 |
+
} catch (e) {
|
204 |
+
document.getElementById('error-message').innerHTML =
|
205 |
+
"<div class='entry-content'><div class='woocommerce'><div class='woocommerce-notices-wrapper'><p class='cart-empty woocommerce-info' style='margin-left: -50px; margin-right: 75px'>Something went wrong, please try again after sometime.</p></div></div></div>";
|
206 |
+
|
207 |
+
rzp1cc.enableCheckoutButtons();
|
208 |
+
rzp1cc.showSpinner(false);
|
209 |
+
|
210 |
+
}
|
211 |
+
})
|
212 |
+
.catch(e => {
|
213 |
+
// Response sent to the User when cart is empty or order creation fails
|
214 |
+
if (e.status == 400){
|
215 |
+
if (e.response.code == 'BAD_REQUEST_EMPTY_CART'){
|
216 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Order could not be placed as your cart is empty.</p>";
|
217 |
+
} else if (e.response.code == 'ORDER_CREATION_FAILED'){
|
218 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Razorpay Error: Order could not be placed, please try again after sometime.</p>";
|
219 |
+
} else if (e.response.code == 'MIN_CART_AMOUNT_CHECK_FAILED'){
|
220 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>"+e.response.message+"</p>";
|
221 |
+
} else if (e.response.code == 'WOOCOMMERCE_ORDER_CREATION_FAILED'){
|
222 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Order could not be placed, please connect with the "+rzp1ccCheckoutData.blogname+"</p>";
|
223 |
+
} else {
|
224 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Something went wrong, please try again after sometime.</p>";
|
225 |
+
}
|
226 |
+
|
227 |
+
} else {
|
228 |
+
document.getElementById('error-message').innerHTML = "<p style='margin-top: revert;text-color: #e2401c !important;color: #e80707;'>Something went wrong, please try again after sometime.</p>";
|
229 |
+
}
|
230 |
+
|
231 |
+
rzp1cc.enableCheckoutButtons();
|
232 |
+
rzp1cc.showSpinner(false);
|
233 |
+
});
|
234 |
+
}
|
235 |
+
});
|
debug.md
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
localhost - incognito - key + order_id sent
|
2 |
+
|
3 |
+
|
4 |
+
kinsta - incognito - key + order_id sent
|
5 |
+
|
6 |
+
|
7 |
+
|
8 |
+
localhost - incognito - only order_id
|
9 |
+
|
10 |
+
|
11 |
+
kinsta - incognito - only order_id
|
12 |
+
|
13 |
+
|
14 |
+
TODO
|
15 |
+
- Confirm if we send both `key` and `order_id`
|
16 |
+
-
|
17 |
+
|
18 |
+
|
19 |
+
Bug on Chrome NOT on Firefox
|
20 |
+
Incog -> prefill number + email -> open checkout for non-logged in user -> goes to address before otp check
|
21 |
+
|
22 |
+
Firefox Curl
|
23 |
+
```
|
24 |
+
curl 'https://omega-api.stage.razorpay.in/v1/customers/status/+918888888888?x_entity_id=order_IDu8TYW7wKolMv&_[platform]=browser' --globoff -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:93.0) Gecko/20100101 Firefox/93.0' -H 'Accept: */*' -H 'Accept-Language: en-US,en;q=0.5' --compressed -H 'DNT: 1' -H 'Connection: keep-alive' -H 'Referer: https://omega-api.stage.razorpay.in/test/checkout.html?branch=feat/1cc' -H 'Cookie: razorpay_api_session=eyJpdiI6IjJUYkU1Kzc2cXNLa2ZzeW5wNzhPTWc9PSIsInZhbHVlIjoiRDFSdFJhTllcL2NrbnI3UFlYQnh4SHRCazNYS0JlNlVla05HWm9rQ0piaVwvbzduemtPQ3did1RiZDQwUnRvWnVQOTVmVkx3aWhMbGVOeFZZVXpyRThlcU9UNUE5Z2xyXC9YNE5FM2VxcnBhb292RTJuSGRzaE1WeGtGZGF2OERGQW4iLCJtYWMiOiJmZjBjOWM0OTNlM2JiMTk0OGQ3MzdkYzRlMDQxYTg4ZjgyYzM2MjIzYjRiNzYzYWI2MGYzNTgyNmVhZjE4Nzg3In0%3D' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin'
|
25 |
+
```
|
26 |
+
|
27 |
+
|
28 |
+
Chrome Curl
|
29 |
+
```
|
30 |
+
curl 'https://omega-api.stage.razorpay.in/v1/customers/status/+918888888888?x_entity_id=order_IDu8TYW7wKolMv&_\[platform\]=browser' \
|
31 |
+
-H 'Connection: keep-alive' \
|
32 |
+
-H 'sec-ch-ua: "Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"' \
|
33 |
+
-H 'sec-ch-ua-mobile: ?0' \
|
34 |
+
-H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36' \
|
35 |
+
-H 'sec-ch-ua-platform: "macOS"' \
|
36 |
+
-H 'Accept: */*' \
|
37 |
+
-H 'Sec-Fetch-Site: same-origin' \
|
38 |
+
-H 'Sec-Fetch-Mode: cors' \
|
39 |
+
-H 'Sec-Fetch-Dest: empty' \
|
40 |
+
-H 'Referer: https://omega-api.stage.razorpay.in/test/checkout.html?branch=feat/1cc' \
|
41 |
+
-H 'Accept-Language: en-GB,en;q=0.9' \
|
42 |
+
--compressed
|
43 |
+
```
|
44 |
+
|
45 |
+
|
46 |
+
|
47 |
+
curl --location --request POST 'https://api.razorpay.com/v1/orders' \
|
48 |
+
--header 'Authorization: Basic cnpwX3Rlc3RfMURQNW1tT2xGNUc1YWc6dGhpc2lzc3VwZXJzZWNyZXQ=' \
|
49 |
+
--header 'Content-Type: application/json' \
|
50 |
+
--data-raw '{
|
51 |
+
"amount": 100000,
|
52 |
+
"currency": "INR",
|
53 |
+
"receipt": "ORDER_COUPON",
|
54 |
+
"payment_capture": 1,
|
55 |
+
"notes": {
|
56 |
+
"notes_key_1": "Book 1"
|
57 |
+
}
|
58 |
+
}'
|
includes/api/api.php
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* custom APIs for Razorpay 1cc
|
5 |
+
*/
|
6 |
+
|
7 |
+
require_once __DIR__ . '/../debug.php';
|
8 |
+
require_once __DIR__ . '/../../woo-razorpay.php';
|
9 |
+
require_once __DIR__ . '/shipping-info.php';
|
10 |
+
require_once __DIR__ . '/coupon-apply.php';
|
11 |
+
require_once __DIR__ . '/coupon-get.php';
|
12 |
+
require_once __DIR__ . '/order.php';
|
13 |
+
require_once __DIR__ . '/cart.php';
|
14 |
+
require_once __DIR__ . '/auth.php';
|
15 |
+
require_once __DIR__ . '/../state-map.php';
|
16 |
+
require_once __DIR__ . '/save-abandonment-data.php';
|
17 |
+
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
18 |
+
|
19 |
+
define('RZP_1CC_ROUTES_BASE', '1cc/v1');
|
20 |
+
define('RZP_1CC_CART_HASH', 'wc_razorpay_cart_hash_');
|
21 |
+
|
22 |
+
function rzp1ccInitRestApi()
|
23 |
+
{
|
24 |
+
|
25 |
+
/**
|
26 |
+
* coupon APIs required
|
27 |
+
*/
|
28 |
+
|
29 |
+
// returns applicable coupons for an order
|
30 |
+
register_rest_route(
|
31 |
+
RZP_1CC_ROUTES_BASE . '/coupon',
|
32 |
+
'list',
|
33 |
+
array(
|
34 |
+
'methods' => 'POST',
|
35 |
+
'callback' => 'getCouponList',
|
36 |
+
'permission_callback' => 'checkAuthCredentials',
|
37 |
+
)
|
38 |
+
);
|
39 |
+
|
40 |
+
// checks if a coupon can be applied and returns discount amount
|
41 |
+
register_rest_route(
|
42 |
+
RZP_1CC_ROUTES_BASE . '/coupon',
|
43 |
+
'apply',
|
44 |
+
array(
|
45 |
+
'methods' => 'POST',
|
46 |
+
'callback' => 'applyCouponOnCart',
|
47 |
+
'permission_callback' => 'checkAuthCredentials',
|
48 |
+
)
|
49 |
+
);
|
50 |
+
|
51 |
+
/**
|
52 |
+
* order APIs
|
53 |
+
*/
|
54 |
+
|
55 |
+
// create new wc order
|
56 |
+
register_rest_route(
|
57 |
+
RZP_1CC_ROUTES_BASE . '/order',
|
58 |
+
'create',
|
59 |
+
array(
|
60 |
+
'methods' => 'POST',
|
61 |
+
'callback' => 'createWcOrder',
|
62 |
+
'permission_callback' => 'checkAuthCredentials',
|
63 |
+
)
|
64 |
+
);
|
65 |
+
|
66 |
+
/**
|
67 |
+
* shipping APIs
|
68 |
+
*/
|
69 |
+
|
70 |
+
// list of shipping methods for an order
|
71 |
+
register_rest_route(
|
72 |
+
RZP_1CC_ROUTES_BASE . '/shipping',
|
73 |
+
'shipping-info',
|
74 |
+
array(
|
75 |
+
'methods' => 'POST',
|
76 |
+
'callback' => 'calculateShipping1cc',
|
77 |
+
'permission_callback' => 'checkAuthCredentials',
|
78 |
+
)
|
79 |
+
);
|
80 |
+
|
81 |
+
// save abandoned cart data
|
82 |
+
register_rest_route(
|
83 |
+
RZP_1CC_ROUTES_BASE . '/',
|
84 |
+
'abandoned-cart',
|
85 |
+
array(
|
86 |
+
'methods' => 'POST',
|
87 |
+
'callback' => 'saveCartAbandonmentData',
|
88 |
+
'permission_callback' => 'checkAuthCredentials',
|
89 |
+
)
|
90 |
+
);
|
91 |
+
}
|
92 |
+
|
93 |
+
add_action('rest_api_init', 'rzp1ccInitRestApi');
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Check any prerequisites for our REST request
|
97 |
+
*/
|
98 |
+
function initCustomerSessionAndCart()
|
99 |
+
{
|
100 |
+
if (defined('WC_ABSPATH')) {
|
101 |
+
// WC 3.6+ - Cart and other frontend functions are not included for REST requests.
|
102 |
+
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
|
103 |
+
include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
|
104 |
+
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
|
105 |
+
}
|
106 |
+
|
107 |
+
if (null === WC()->session) {
|
108 |
+
$session_class = apply_filters('woocommerce_session_handler', 'WC_Session_Handler');
|
109 |
+
WC()->session = new $session_class();
|
110 |
+
WC()->session->init();
|
111 |
+
}
|
112 |
+
|
113 |
+
if (null === WC()->customer) {
|
114 |
+
WC()->customer = new WC_Customer(get_current_user_id(), true);
|
115 |
+
}
|
116 |
+
|
117 |
+
if (null === WC()->cart) {
|
118 |
+
WC()->cart = new WC_Cart();
|
119 |
+
WC()->cart->get_cart();
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
add_action('setup_extra_setting_fields', 'addMagicCheckoutSettingFields');
|
124 |
+
|
125 |
+
function addMagicCheckoutSettingFields(&$defaultFormFields)
|
126 |
+
{
|
127 |
+
$magicCheckoutConfigFields = array(
|
128 |
+
|
129 |
+
'enable_1cc' => array(
|
130 |
+
'title' => __('Activate Magic Checkout'),
|
131 |
+
'type' => 'checkbox',
|
132 |
+
'description' => "",
|
133 |
+
'label' => __('Activate Magic Checkout'),
|
134 |
+
'default' => 'no',
|
135 |
+
),
|
136 |
+
'enable_1cc_test_mode' => array(
|
137 |
+
'title' => __('Activate test mode'),
|
138 |
+
'type' => 'checkbox',
|
139 |
+
'description' => 'When test mode is active, only logged-in admin users will see the Razorpay Magic Checkout button',
|
140 |
+
'label' => __('Activate test mode for Magic Checkout'),
|
141 |
+
'default' => 'no',
|
142 |
+
),
|
143 |
+
'enable_1cc_pdp_checkout' => array(
|
144 |
+
'title' => __('Activate Buy Now Button'),
|
145 |
+
'type' => 'checkbox',
|
146 |
+
'description' => 'By enabling the Buy Now button, user will be able to see the Razorpay Magic Checkout button on Product display page. ',
|
147 |
+
'label' => __('Activate Buy Now for Magic Checkout'),
|
148 |
+
'default' => 'yes',
|
149 |
+
),
|
150 |
+
'enable_1cc_mini_cart_checkout' => array(
|
151 |
+
'title' => __('Activate Mini Cart Checkout'),
|
152 |
+
'type' => 'checkbox',
|
153 |
+
'description' => 'By enabling the Mini Cart checkout button, user will be able to see the Razorpay Magic Checkout on click of checkout button. ',
|
154 |
+
'label' => __('Activate Mini Cart for Magic Checkout'),
|
155 |
+
'default' => 'yes',
|
156 |
+
),
|
157 |
+
'1cc_min_cart_amount' => array(
|
158 |
+
'title' => __('Set minimum cart amount (INR)'),
|
159 |
+
'type' => 'number',
|
160 |
+
'description' => 'Enter a minimum cart amount required to place an order via Magic Checkout.',
|
161 |
+
'default' => 0,
|
162 |
+
'css' => 'width: 120px;',
|
163 |
+
'custom_attributes' => array(
|
164 |
+
'min' => 0,
|
165 |
+
'step' => 1,
|
166 |
+
),
|
167 |
+
),
|
168 |
+
'enable_1cc_mandatory_login' => array(
|
169 |
+
'title' => __('Activate Mandatory Login'),
|
170 |
+
'type' => 'checkbox',
|
171 |
+
'description' => "",
|
172 |
+
'label' => __('Activate Mandatory Login for Magic Checkout'),
|
173 |
+
'default' => 'no',
|
174 |
+
),
|
175 |
+
'enable_1cc_cod_intelligence' => array(
|
176 |
+
'title' => __('Activate COD Intelligence'),
|
177 |
+
'type' => 'checkbox',
|
178 |
+
'description' => "By enabling this you allow Magic Checkout to decide which customer sees the COD option based on past shopping history",
|
179 |
+
'label' => __('Activate Magic Checkout COD Intelligence'),
|
180 |
+
'default' => 'no',
|
181 |
+
),
|
182 |
+
'1cc_min_COD_slab_amount' => array(
|
183 |
+
'title' => __('Set minimum amount (INR) for COD'),
|
184 |
+
'type' => 'number',
|
185 |
+
'description' => 'Enter a minimum amount required to place an order via COD (if enabled)',
|
186 |
+
'default' => 0,
|
187 |
+
'css' => 'width: 120px;',
|
188 |
+
'custom_attributes' => array(
|
189 |
+
'min' => 0,
|
190 |
+
'step' => 1,
|
191 |
+
),
|
192 |
+
),
|
193 |
+
'1cc_max_COD_slab_amount' => array(
|
194 |
+
'title' => __('Set maximum amount (INR) for COD'),
|
195 |
+
'type' => 'number',
|
196 |
+
'description' => 'Enter a maximum amount allowed to place an order via COD (if enabled)',
|
197 |
+
'default' => 0,
|
198 |
+
'css' => 'width: 120px;',
|
199 |
+
'custom_attributes' => array(
|
200 |
+
'min' => 0,
|
201 |
+
'step' => 1,
|
202 |
+
),
|
203 |
+
),
|
204 |
+
'enable_1cc_ga_analytics' => array(
|
205 |
+
'title' => __('Activate Google Analytics'),
|
206 |
+
'type' => 'checkbox',
|
207 |
+
'description' => "To track orders using Google Analytics",
|
208 |
+
'label' => __('Activate Magic Checkout Google Analytics'),
|
209 |
+
'default' => 'no',
|
210 |
+
),
|
211 |
+
'enable_1cc_fb_analytics' => array(
|
212 |
+
'title' => __('Activate Facebook Analytics'),
|
213 |
+
'type' => 'checkbox',
|
214 |
+
'description' => "To track orders using Facebook Pixel",
|
215 |
+
'label' => __('Activate Magic Checkout Facebook Analytics'),
|
216 |
+
'default' => 'no',
|
217 |
+
),
|
218 |
+
'enable_1cc_debug_mode' => array(
|
219 |
+
'title' => __('Activate debug mode'),
|
220 |
+
'type' => 'checkbox',
|
221 |
+
'description' => 'When debug mode is active, API logs and errors are collected and stored in your Woocommerce dashboard. It is recommended to keep this activated.',
|
222 |
+
'label' => __('Enable debug mode for Magic Checkout'),
|
223 |
+
'default' => 'yes',
|
224 |
+
),
|
225 |
+
);
|
226 |
+
|
227 |
+
$defaultFormFields = array_merge($defaultFormFields, $magicCheckoutConfigFields);
|
228 |
+
|
229 |
+
}
|
includes/api/auth.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* custom auth to secure 1cc APIs
|
5 |
+
*/
|
6 |
+
|
7 |
+
function checkAuthCredentials()
|
8 |
+
{
|
9 |
+
return true;
|
10 |
+
}
|
11 |
+
|
12 |
+
?>
|
includes/api/cart.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* For cart related functionality
|
4 |
+
*/
|
5 |
+
|
6 |
+
/**
|
7 |
+
* Create the cart object for the line items exist in order
|
8 |
+
*/
|
9 |
+
function create1ccCart($orderId)
|
10 |
+
{
|
11 |
+
global $woocommerce;
|
12 |
+
|
13 |
+
$order = wc_get_order($orderId);
|
14 |
+
|
15 |
+
if ($order && $order->get_item_count() > 0) {
|
16 |
+
foreach ($order->get_items() as $item_id => $item) {
|
17 |
+
$productId = $item->get_product_id();
|
18 |
+
$variationId = $item->get_variation_id();
|
19 |
+
$quantity = $item->get_quantity();
|
20 |
+
$customData["item_id"] = $item_id;
|
21 |
+
|
22 |
+
WC()->cart->add_to_cart(
|
23 |
+
$productId,
|
24 |
+
$quantity,
|
25 |
+
$variationId,
|
26 |
+
[],
|
27 |
+
$customData
|
28 |
+
);
|
29 |
+
}
|
30 |
+
|
31 |
+
return true;
|
32 |
+
} else {
|
33 |
+
return false;
|
34 |
+
}
|
35 |
+
}
|
includes/api/coupon-apply.php
ADDED
@@ -0,0 +1,219 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* for coupon related API
|
5 |
+
*/
|
6 |
+
|
7 |
+
function applyCouponOnCart(WP_REST_Request $request)
|
8 |
+
{
|
9 |
+
global $woocommerce;
|
10 |
+
|
11 |
+
$status = 400;
|
12 |
+
$failure_reason = "";
|
13 |
+
|
14 |
+
$params = $request->get_params();
|
15 |
+
|
16 |
+
$logObj = [];
|
17 |
+
$logObj["api"] = "applyCouponOnCart";
|
18 |
+
$logObj["params"] = $params;
|
19 |
+
|
20 |
+
$validateInput = validateApplyCouponApi($params);
|
21 |
+
|
22 |
+
if ($validateInput != null) {
|
23 |
+
$response["failure_reason"] = $validateInput;
|
24 |
+
$response["failure_code"] = "VALIDATION_ERROR";
|
25 |
+
$logObj["response"] = $response;
|
26 |
+
|
27 |
+
rzpLogError(json_encode($logObj));
|
28 |
+
|
29 |
+
return new WP_REST_Response($response, 400);
|
30 |
+
}
|
31 |
+
|
32 |
+
$couponCode = sanitize_text_field($params["code"]);
|
33 |
+
$email = sanitize_text_field($params["email"]) ?? "";
|
34 |
+
$orderId = sanitize_text_field($params["order_id"]);
|
35 |
+
|
36 |
+
// initializes the session
|
37 |
+
initCustomerSessionAndCart();
|
38 |
+
|
39 |
+
// Set current user for smart coupon plugin
|
40 |
+
if (is_plugin_active('wt-smart-coupons-for-woocommerce/wt-smart-coupon.php')) {
|
41 |
+
if (empty($email) === false) {
|
42 |
+
$user = get_user_by('email', $email);
|
43 |
+
wp_set_current_user($user->id);
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
// check for individual specific coupons
|
48 |
+
// cart->apply does not enforce this
|
49 |
+
$coupon = new WC_Coupon($couponCode);
|
50 |
+
|
51 |
+
// check the enable coupon option
|
52 |
+
if (get_option("woocommerce_enable_coupons") === "no") {
|
53 |
+
$response["failure_reason"] = "Coupon feature disabled";
|
54 |
+
$response["failure_code"] = "INVALID_COUPON";
|
55 |
+
$logObj["response"] = $response;
|
56 |
+
|
57 |
+
rzpLogError(json_encode($logObj));
|
58 |
+
|
59 |
+
return new WP_REST_Response($response, 400);
|
60 |
+
}
|
61 |
+
|
62 |
+
//check woo-discount-rule plugin disabling the coupons
|
63 |
+
$discountOptions = get_option('woo-discount-config-v2', []);
|
64 |
+
if (!empty($discountOptions)) {
|
65 |
+
$isCouponEnabled = $discountOptions['disable_coupon_when_rule_applied'];
|
66 |
+
if ($isCouponEnabled == 'disable_coupon') {
|
67 |
+
$response["failure_reason"] = "Coupon feature disabled";
|
68 |
+
$response["failure_code"] = "INVALID_COUPON";
|
69 |
+
$logObj["response"] = $response;
|
70 |
+
|
71 |
+
rzpLogError(json_encode($logObj));
|
72 |
+
|
73 |
+
return new WP_REST_Response($response, 400);
|
74 |
+
}
|
75 |
+
}
|
76 |
+
|
77 |
+
if (empty($coupon->get_email_restrictions()) === false) {
|
78 |
+
if ($email == "") {
|
79 |
+
$response["failure_reason"] = "User email is required";
|
80 |
+
$response["failure_code"] = "LOGIN_REQUIRED";
|
81 |
+
$logObj["response"] = $response;
|
82 |
+
|
83 |
+
rzpLogError(json_encode($logObj));
|
84 |
+
|
85 |
+
return new WP_REST_Response($response, 400);
|
86 |
+
} elseif (in_array($email, $coupon->get_email_restrictions()) === false) {
|
87 |
+
$response["failure_reason"] = "Coupon does not exist";
|
88 |
+
$response["failure_code"] = "INVALID_COUPON";
|
89 |
+
$logObj["response"] = $response;
|
90 |
+
|
91 |
+
rzpLogError(json_encode($logObj));
|
92 |
+
|
93 |
+
return new WP_REST_Response($response, 400);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
// Get coupon usage limit per user
|
98 |
+
$userLimit = $coupon->get_usage_limit_per_user();
|
99 |
+
if (!empty($userLimit)) {
|
100 |
+
$dataStore = $coupon->get_data_store();
|
101 |
+
$order = wc_get_order($orderId);
|
102 |
+
$usageCount = $order->get_customer_id() ? $dataStore->get_usage_by_user_id($coupon, $order->get_customer_id()) : $dataStore->get_usage_by_email($coupon, $email);
|
103 |
+
|
104 |
+
if (!empty($usageCount) && !empty($userLimit)) {
|
105 |
+
// Calculate remaining
|
106 |
+
$remainingCount = $userLimit - $usageCount;
|
107 |
+
|
108 |
+
if ($remainingCount <= 0) {
|
109 |
+
$response["failure_reason"] = "Coupon usage limit has been reached";
|
110 |
+
$response["failure_code"] = "REQUIREMENT_NOT_MET";
|
111 |
+
$logObj["response"] = $response;
|
112 |
+
|
113 |
+
rzpLogError(json_encode($logObj));
|
114 |
+
|
115 |
+
return new WP_REST_Response($response, 400);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
}
|
119 |
+
|
120 |
+
// to clear any residual notices
|
121 |
+
$temp = wc_print_notices(true);
|
122 |
+
|
123 |
+
WC()->cart->remove_coupon($couponCode);
|
124 |
+
WC()->cart->empty_cart();
|
125 |
+
|
126 |
+
$cart1cc = create1ccCart($orderId);
|
127 |
+
|
128 |
+
if ($cart1cc) {
|
129 |
+
$applyCoupon = WC()->cart->add_discount($couponCode);
|
130 |
+
|
131 |
+
if ($applyCoupon === true) {
|
132 |
+
$status = true;
|
133 |
+
} else {
|
134 |
+
$markup = wc_print_notices(true);
|
135 |
+
$errorArray = explode("<li>", $markup);
|
136 |
+
$errorMessage = preg_replace(
|
137 |
+
"/\t|\n/",
|
138 |
+
"",
|
139 |
+
strip_tags(end($errorArray))
|
140 |
+
);
|
141 |
+
$failureReason = html_entity_decode($errorMessage);
|
142 |
+
}
|
143 |
+
} else {
|
144 |
+
$invalidCartResponse = [];
|
145 |
+
$invalidCartResponse["failure_reason"] = "Invalid merchant order id";
|
146 |
+
$invalidCartResponse["failure_code"] = "VALIDATION_ERROR";
|
147 |
+
|
148 |
+
$logObj["response"] = $invalidCartResponse;
|
149 |
+
|
150 |
+
rzpLogError(json_encode($logObj));
|
151 |
+
return new WP_REST_Response($invalidCartResponse, 400);
|
152 |
+
}
|
153 |
+
|
154 |
+
$newAmount = (WC()->cart->cart_contents_total + WC()->cart->tax_total) * 100;
|
155 |
+
$discountAmount = (WC()->cart->get_cart_discount_tax_total() + WC()->cart->get_cart_discount_total()) * 100;
|
156 |
+
|
157 |
+
$couponError = getApplyCouponErrorCodes($failureReason);
|
158 |
+
|
159 |
+
$promotion = [];
|
160 |
+
$promotion["code"] = $couponCode;
|
161 |
+
$promotion["reference_id"] = $couponCode;
|
162 |
+
$promotion["value"] = round($discountAmount ?? 0);
|
163 |
+
$response["promotion"] = $promotion;
|
164 |
+
|
165 |
+
if ($couponError["failure_reason"] === "") {
|
166 |
+
$logObj["response"] = $response;
|
167 |
+
rzpLogInfo(json_encode($logObj));
|
168 |
+
return new WP_REST_Response($response, 200);
|
169 |
+
} else {
|
170 |
+
$logObj["response"] = array_merge($response, $couponError);
|
171 |
+
rzpLogError(json_encode($logObj));
|
172 |
+
return new WP_REST_Response($couponError, 400);
|
173 |
+
}
|
174 |
+
}
|
175 |
+
|
176 |
+
function getApplyCouponErrorCodes($failureMessage)
|
177 |
+
{
|
178 |
+
$result = [];
|
179 |
+
$result["failure_code"] = "REQUIREMENT_NOT_MET";
|
180 |
+
|
181 |
+
if ($failureMessage === "" || is_null($failureMessage)) {
|
182 |
+
$result["failure_reason"] = "";
|
183 |
+
$result["failure_code"] = "";
|
184 |
+
} elseif (stripos($failureMessage, "does not exist") !== false) {
|
185 |
+
$result["failure_reason"] = "Coupon does not exist";
|
186 |
+
$result["failure_code"] = "INVALID_COUPON";
|
187 |
+
} elseif (stripos($failureMessage, "coupon has expired") !== false) {
|
188 |
+
$result["failure_reason"] = "This coupon has expired";
|
189 |
+
} elseif (stripos($failureMessage, "minimum spend") !== false) {
|
190 |
+
$result["failure_reason"] = "Cart is below the minimum amount";
|
191 |
+
} elseif (stripos($failureMessage, "maximum spend") !== false) {
|
192 |
+
$result["failure_reason"] = "Cart is above maximum allowed amount";
|
193 |
+
} elseif (
|
194 |
+
stripos($failureMessage, "not applicable to selected products") !==
|
195 |
+
false
|
196 |
+
) {
|
197 |
+
$result["failure_reason"] = "Required product is missing";
|
198 |
+
} elseif (
|
199 |
+
stripos($failureMessage, "Coupon usage limit has been reached") !==
|
200 |
+
false
|
201 |
+
) {
|
202 |
+
$result["failure_reason"] = "Coupon usage limit has been reached";
|
203 |
+
} else {
|
204 |
+
$result["failure_reason"] = "Coupon could not be applied";
|
205 |
+
$result["failure_code"] = "INVALID_COUPON";
|
206 |
+
}
|
207 |
+
|
208 |
+
return $result;
|
209 |
+
}
|
210 |
+
|
211 |
+
function validateApplyCouponApi($param)
|
212 |
+
{
|
213 |
+
if (empty(sanitize_text_field($param["code"])) === true) {
|
214 |
+
$failureReason = "Field code is required.";
|
215 |
+
} elseif (empty(sanitize_text_field($param["order_id"])) === true) {
|
216 |
+
$failureReason = "Field order id is required.";
|
217 |
+
}
|
218 |
+
return $failureReason;
|
219 |
+
}
|
includes/api/coupon-get.php
ADDED
@@ -0,0 +1,301 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* for coupon related API
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* create cart from "order_id" using $cart_1cc = create1ccCart($merchant_order_id);
|
9 |
+
* get total amount of items from the cart (replace $amount with that)
|
10 |
+
* run the query for coupons
|
11 |
+
* apply checks for expired coupons (see GMT time)
|
12 |
+
* check for min cart amount condition
|
13 |
+
* check if the email exists in `$coupon->get_email_restrictions())`
|
14 |
+
* convert all amounts to int in paise
|
15 |
+
* return whatever clears
|
16 |
+
*/
|
17 |
+
function getCouponList($request)
|
18 |
+
{
|
19 |
+
global $woocommerce;
|
20 |
+
$couponData = [];
|
21 |
+
|
22 |
+
$params = $request->get_params();
|
23 |
+
$logObj = array();
|
24 |
+
$logObj['api'] = 'getCouponList';
|
25 |
+
$logObj['params'] = $params;
|
26 |
+
|
27 |
+
$orderId = sanitize_text_field($request->get_params()['order_id']);
|
28 |
+
$order = wc_get_order($orderId);
|
29 |
+
|
30 |
+
if (!$order) {
|
31 |
+
$response['failure_reason'] = 'Invalid merchant order id';
|
32 |
+
$response['failure_code'] = 'VALIDATION_ERROR';
|
33 |
+
$statusCode = 400;
|
34 |
+
$logObj['response'] = $response;
|
35 |
+
$logObj['status_code'] = $statusCode;
|
36 |
+
rzpLogError(json_encode($logObj));
|
37 |
+
return new WP_REST_Response($response, $statusCode);
|
38 |
+
}
|
39 |
+
|
40 |
+
$amount = floatval($order->get_total());
|
41 |
+
$email = sanitize_text_field($request->get_params()['email']);
|
42 |
+
$contact = sanitize_text_field($request->get_params()['contact']);
|
43 |
+
|
44 |
+
//Updating the email address to wc order.
|
45 |
+
if (empty($email) == false) {
|
46 |
+
update_post_meta($orderId, '_billing_email', $email);
|
47 |
+
update_post_meta($orderId, '_shipping_email', $email);
|
48 |
+
}
|
49 |
+
|
50 |
+
if (empty($contact) == false) {
|
51 |
+
update_post_meta($orderId, '_billing_phone', $contact);
|
52 |
+
update_post_meta($orderId, '_shipping_phone', $contact);
|
53 |
+
}
|
54 |
+
|
55 |
+
$args = array(
|
56 |
+
'post_type' => 'shop_coupon',
|
57 |
+
'orderby' => 'title',
|
58 |
+
'order' => 'ASC',
|
59 |
+
'meta_query' => array(
|
60 |
+
array(
|
61 |
+
'key' => 'discount_type',
|
62 |
+
'value' => array('fixed_cart', 'percent', 'fixed_product'),
|
63 |
+
'compare' => 'IN',
|
64 |
+
),
|
65 |
+
),
|
66 |
+
'fields' => 'ids',
|
67 |
+
'posts_per_page' => -1, // By default WP_Query will return only 10 posts, to avoid that we need to pass -1
|
68 |
+
);
|
69 |
+
|
70 |
+
//check woo-discount-rule plugin disabling the coupons
|
71 |
+
$discountOptions = get_option('woo-discount-config-v2', []);
|
72 |
+
if (!empty($discountOptions)) {
|
73 |
+
$isCouponEnabled = $discountOptions['disable_coupon_when_rule_applied'];
|
74 |
+
if ($isCouponEnabled == 'disable_coupon') {
|
75 |
+
$args = array();
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
$coupons = new WP_Query($args);
|
80 |
+
|
81 |
+
$couponData['promotions'] = array();
|
82 |
+
|
83 |
+
if ($coupons->have_posts() && 'yes' === get_option('woocommerce_enable_coupons')) {
|
84 |
+
while ($coupons->have_posts()) {
|
85 |
+
$coupons->the_post();
|
86 |
+
$coupon = new WC_Coupon(get_the_ID());
|
87 |
+
$items = $order->get_items();
|
88 |
+
$couponMinAmount = floatval($coupon->get_minimum_amount());
|
89 |
+
$couponMaxAmount = floatval($coupon->get_maximum_amount());
|
90 |
+
$couponExpiryDate = $coupon->get_date_expires() ? $coupon->get_date_expires()->getTimestamp() : null;
|
91 |
+
|
92 |
+
//check coupon description
|
93 |
+
if (empty($coupon->get_description()) === true) {
|
94 |
+
continue;
|
95 |
+
}
|
96 |
+
|
97 |
+
// validation for email coupon
|
98 |
+
if (empty($coupon->get_email_restrictions()) === false) {
|
99 |
+
if (empty($email) === true || in_array($email, $coupon->get_email_restrictions()) === false) {
|
100 |
+
continue;
|
101 |
+
}
|
102 |
+
}
|
103 |
+
|
104 |
+
if (
|
105 |
+
($amount < $couponMinAmount)
|
106 |
+
|| (($amount > $couponMaxAmount) && ($couponMaxAmount != 0))
|
107 |
+
|| ($couponExpiryDate !== null && $couponExpiryDate < time())
|
108 |
+
) {
|
109 |
+
continue;
|
110 |
+
}
|
111 |
+
|
112 |
+
// Get usage count
|
113 |
+
$count = $coupon->get_usage_count();
|
114 |
+
// Get coupon limit
|
115 |
+
$limit = $coupon->get_usage_limit();
|
116 |
+
|
117 |
+
if (!empty($count) && !empty($limit)) {
|
118 |
+
// Calculate remaining
|
119 |
+
$remaining = $limit - $count;
|
120 |
+
if ($remaining <= 0) {
|
121 |
+
continue;
|
122 |
+
}
|
123 |
+
}
|
124 |
+
|
125 |
+
// Get coupon usage limit per user
|
126 |
+
$userLimit = $coupon->get_usage_limit_per_user();
|
127 |
+
|
128 |
+
if (!empty($userLimit)) {
|
129 |
+
$dataStore = $coupon->get_data_store();
|
130 |
+
$usageCount = $order->get_customer_id() ? $dataStore->get_usage_by_user_id($coupon, $order->get_customer_id()) : $dataStore->get_usage_by_email($coupon, $email);
|
131 |
+
|
132 |
+
if (!empty($usageCount) && !empty($userLimit)) {
|
133 |
+
// Calculate remaining
|
134 |
+
$remainingCount = $userLimit - $usageCount;
|
135 |
+
if ($remainingCount <= 0) {
|
136 |
+
continue;
|
137 |
+
}
|
138 |
+
}
|
139 |
+
}
|
140 |
+
|
141 |
+
// Add item based coupons
|
142 |
+
if (count($coupon->get_product_ids()) > 0) {
|
143 |
+
$valid = false;
|
144 |
+
// TODO: fix this logic
|
145 |
+
foreach ($items as $item) {
|
146 |
+
if (in_array($item->get_product_id(), $coupon->get_product_ids()) || in_array($item->get_variation_id(), $coupon->get_product_ids())) {
|
147 |
+
$valid = true;
|
148 |
+
break;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
if (!$valid) {
|
152 |
+
continue;
|
153 |
+
}
|
154 |
+
}
|
155 |
+
|
156 |
+
// Exclude item based coupons
|
157 |
+
if (count($coupon->get_excluded_product_ids()) > 0) {
|
158 |
+
$valid = false;
|
159 |
+
foreach ($items as $item) {
|
160 |
+
if (in_array($item->get_product_id(), $coupon->get_excluded_product_ids()) || in_array($item->get_variation_id(), $coupon->get_excluded_product_ids())) {
|
161 |
+
$valid = true;
|
162 |
+
break;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
if ($valid) {
|
166 |
+
continue;
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
// include and exclude product category items
|
171 |
+
if (count($coupon->get_excluded_product_categories()) > 0) {
|
172 |
+
$categories = array();
|
173 |
+
foreach ($items as $item) {
|
174 |
+
$product_cats = wc_get_product_cat_ids($item->get_product_id());
|
175 |
+
$cat_id_list = array_intersect($product_cats, $coupon->get_excluded_product_categories());
|
176 |
+
if (count($cat_id_list) > 0) {
|
177 |
+
foreach ($cat_id_list as $cat_id) {
|
178 |
+
$cat = get_term($cat_id, 'product_cat');
|
179 |
+
$categories[] = $cat->name;
|
180 |
+
}
|
181 |
+
}
|
182 |
+
}
|
183 |
+
|
184 |
+
if (!empty($categories)) {
|
185 |
+
continue;
|
186 |
+
}
|
187 |
+
}
|
188 |
+
|
189 |
+
if (count($coupon->get_product_categories()) > 0) {
|
190 |
+
$valid = false;
|
191 |
+
foreach ($items as $item) {
|
192 |
+
$product_cats = wc_get_product_cat_ids($item->get_product_id());
|
193 |
+
if (count(array_intersect($product_cats, $coupon->get_product_categories())) > 0) {
|
194 |
+
$valid = true;
|
195 |
+
break;
|
196 |
+
}
|
197 |
+
}
|
198 |
+
|
199 |
+
if (!$valid) {
|
200 |
+
continue;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
// exclude sale item from coupons
|
205 |
+
if ($coupon->get_exclude_sale_items()) {
|
206 |
+
$valid = false;
|
207 |
+
foreach ($items as $item) {
|
208 |
+
$product = new WC_Product($item->get_product_id());
|
209 |
+
if ($product->is_on_sale()) {
|
210 |
+
$valid = true;
|
211 |
+
break;
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
if ($valid) {
|
216 |
+
continue;
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
// Check for smart coupon plugin
|
221 |
+
if (is_plugin_active('wt-smart-coupons-for-woocommerce/wt-smart-coupon.php')) {
|
222 |
+
initCustomerSessionAndCart();
|
223 |
+
// Cleanup cart.
|
224 |
+
WC()->cart->empty_cart();
|
225 |
+
create1ccCart($orderId);
|
226 |
+
$smartCoupon = new Wt_Smart_Coupon_Public(" ", " ");
|
227 |
+
|
228 |
+
// Quantity of matching Products
|
229 |
+
$minMatchingProductQty = get_post_meta($coupon->get_id(), '_wt_min_matching_product_qty', true);
|
230 |
+
$maxMatchingProductQty = get_post_meta($coupon->get_id(), '_wt_max_matching_product_qty', true);
|
231 |
+
|
232 |
+
if ($minMatchingProductQty > 0 || $maxMatchingProductQty > 0) {
|
233 |
+
$quantityMatchingProduct = $smartCoupon->get_quantity_of_matching_product($coupon);
|
234 |
+
if ($minMatchingProductQty > 0 && $quantityMatchingProduct < $minMatchingProductQty) {
|
235 |
+
continue;
|
236 |
+
}
|
237 |
+
if ($maxMatchingProductQty > 0 && $quantityMatchingProduct > $maxMatchingProductQty) {
|
238 |
+
continue;
|
239 |
+
}
|
240 |
+
}
|
241 |
+
|
242 |
+
// Subtotal of matching products
|
243 |
+
$minMatchingProductSubtotal = get_post_meta($coupon->get_id(), '_wt_min_matching_product_subtotal', true);
|
244 |
+
$maxMatchingProductSubtotal = get_post_meta($coupon->get_id(), '_wt_max_matching_product_subtotal', true);
|
245 |
+
|
246 |
+
if ($minMatchingProductSubtotal !== 0 || $maxMatchingProductSubtotal !== 0) {
|
247 |
+
$subtotalMatchingProduct = $smartCoupon->get_sub_total_of_matching_products($coupon);
|
248 |
+
if ($minMatchingProductSubtotal > 0 && $subtotalMatchingProduct < $minMatchingProductSubtotal) {
|
249 |
+
continue;
|
250 |
+
}
|
251 |
+
if ($maxMatchingProductSubtotal > 0 && $subtotalMatchingProduct > $maxMatchingProductSubtotal) {
|
252 |
+
continue;
|
253 |
+
}
|
254 |
+
}
|
255 |
+
|
256 |
+
// User role restriction
|
257 |
+
$userRoles = get_post_meta($coupon->get_id(), '_wt_sc_user_roles', true);
|
258 |
+
if ('' != $userRoles && !is_array($userRoles)) {
|
259 |
+
$userRoles = explode(',', $userRoles);
|
260 |
+
} else {
|
261 |
+
$userRoles = array();
|
262 |
+
}
|
263 |
+
|
264 |
+
if (sizeof($userRoles) > 0) {
|
265 |
+
if (empty($email) === false) {
|
266 |
+
$user = get_user_by('email', $email);
|
267 |
+
$role = !empty($user) ? $user->roles : [];
|
268 |
+
|
269 |
+
if (!array_intersect($userRoles, $role)) {
|
270 |
+
continue;
|
271 |
+
}
|
272 |
+
} else {
|
273 |
+
continue;
|
274 |
+
}
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
$couponData['promotions'][] = transformCouponResponse($coupon);
|
279 |
+
}
|
280 |
+
}
|
281 |
+
|
282 |
+
$logObj['response'] = $couponData;
|
283 |
+
$statusCode = 200;
|
284 |
+
$logObj['status_code'] = $statusCode;
|
285 |
+
rzpLogInfo(json_encode($logObj));
|
286 |
+
return new WP_REST_Response($couponData, $statusCode);
|
287 |
+
}
|
288 |
+
|
289 |
+
function transformCouponResponse($coupon)
|
290 |
+
{
|
291 |
+
return array(
|
292 |
+
'code' => $coupon->get_code(),
|
293 |
+
'summary' => $coupon->get_description(),
|
294 |
+
'tnc' => [],
|
295 |
+
);
|
296 |
+
}
|
297 |
+
|
298 |
+
function transformAmountForRzp($amount)
|
299 |
+
{
|
300 |
+
return wc_format_decimal($amount, 2) * 100;
|
301 |
+
}
|
includes/api/order.php
ADDED
@@ -0,0 +1,227 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* create order with status pending
|
5 |
+
* user, adddress, coupon and shipping are left blank
|
6 |
+
*/
|
7 |
+
function createWcOrder(WP_REST_Request $request)
|
8 |
+
{
|
9 |
+
rzpLogInfo("createWcOrder");
|
10 |
+
global $woocommerce;
|
11 |
+
$params = $request->get_params();
|
12 |
+
$logObj = array();
|
13 |
+
$logObj['api'] = 'createWcOrder';
|
14 |
+
$logObj['params'] = $params;
|
15 |
+
|
16 |
+
//Abandoment cart plugin decode the coupon code from token
|
17 |
+
$couponCode = null;
|
18 |
+
if (isset($params['token'])) {
|
19 |
+
$token = sanitize_text_field($params['token']);
|
20 |
+
parse_str(base64_decode(urldecode($token)), $token);
|
21 |
+
if (is_array($token) && array_key_exists('wcf_session_id', $token) && isset($token['wcf_coupon_code'])) {
|
22 |
+
$couponCode = $token['wcf_coupon_code'];
|
23 |
+
}
|
24 |
+
}
|
25 |
+
|
26 |
+
$nonce = $request->get_header('X-WP-Nonce');
|
27 |
+
$verifyReq = wp_verify_nonce($nonce, 'wp_rest');
|
28 |
+
|
29 |
+
if ($verifyReq === false) {
|
30 |
+
$response['status'] = false;
|
31 |
+
$response['message'] = 'Authentication failed';
|
32 |
+
|
33 |
+
$statusCode = 401;
|
34 |
+
$logObj['status_code'] = $statusCode;
|
35 |
+
$logObj['response'] = $response;
|
36 |
+
rzpLogError(json_encode($logObj));
|
37 |
+
|
38 |
+
return new WP_REST_Response($response, $statusCode);
|
39 |
+
}
|
40 |
+
|
41 |
+
initCustomerSessionAndCart();
|
42 |
+
|
43 |
+
if (empty($params['pdpCheckout']) === false) {
|
44 |
+
$variations = [];
|
45 |
+
// Cleanup cart.
|
46 |
+
WC()->cart->empty_cart();
|
47 |
+
|
48 |
+
$variation_id = (empty($params['variationId']) === false) ? (int) $params['variationId'] : 0;
|
49 |
+
|
50 |
+
if (empty($params['variations']) === false) {
|
51 |
+
$variations_arr = json_decode($params['variations'], true);
|
52 |
+
|
53 |
+
foreach ($variations_arr as $key => $value) {
|
54 |
+
$var_key = explode('_', $key);
|
55 |
+
$variations_key[] = ucwords(end($var_key));
|
56 |
+
$variations_val[] = ucwords($value);
|
57 |
+
}
|
58 |
+
|
59 |
+
$variations = array_combine($variations_key, $variations_val);
|
60 |
+
}
|
61 |
+
|
62 |
+
//To add custom fields to buy now orders
|
63 |
+
if (empty($params['fieldObj']) === false) {
|
64 |
+
foreach ($params['fieldObj'] as $key => $value) {
|
65 |
+
if (!empty($value)) {
|
66 |
+
$variations[$key] = $value;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
}
|
70 |
+
|
71 |
+
WC()->cart->add_to_cart($params['productId'], $params['quantity'], $variation_id, $variations);
|
72 |
+
}
|
73 |
+
|
74 |
+
// check if cart is empty
|
75 |
+
if (WC()->cart->get_cart_contents_count() == 0) {
|
76 |
+
$response['message'] = 'Cart cannot be empty';
|
77 |
+
$response['code'] = 'BAD_REQUEST_EMPTY_CART';
|
78 |
+
|
79 |
+
$statusCode = 400;
|
80 |
+
$logObj['status_code'] = $statusCode;
|
81 |
+
$logObj['response'] = $response;
|
82 |
+
rzpLogError(json_encode($logObj));
|
83 |
+
|
84 |
+
return new WP_REST_Response($response, $statusCode);
|
85 |
+
}
|
86 |
+
|
87 |
+
$cartHash = WC()->cart->get_cart_hash();
|
88 |
+
|
89 |
+
$orderIdFromHash = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
|
90 |
+
|
91 |
+
if ($orderIdFromHash == null) {
|
92 |
+
$checkout = WC()->checkout();
|
93 |
+
$orderId = $checkout->create_order(array());
|
94 |
+
} else {
|
95 |
+
$existingOrder = wc_get_order($orderIdFromHash);
|
96 |
+
$existingOrder->calculate_totals();
|
97 |
+
|
98 |
+
if ($existingOrder->needs_payment() == false) {
|
99 |
+
$woocommerce->session->__unset(RZP_1CC_CART_HASH . $cartHash);
|
100 |
+
$checkout = WC()->checkout();
|
101 |
+
$orderId = $checkout->create_order(array());
|
102 |
+
} else {
|
103 |
+
$orderId = $woocommerce->session->get(RZP_1CC_CART_HASH . $cartHash);
|
104 |
+
}
|
105 |
+
}
|
106 |
+
|
107 |
+
$order = wc_get_order($orderId);
|
108 |
+
|
109 |
+
//To remove by default shipping method added on order.
|
110 |
+
$items = (array) $order->get_items('shipping');
|
111 |
+
|
112 |
+
if (sizeof($items) > 0) {
|
113 |
+
// Loop through shipping items
|
114 |
+
foreach ($items as $item_id => $item) {
|
115 |
+
$order->remove_item($item_id);
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
$order->calculate_totals();
|
120 |
+
if ($order) {
|
121 |
+
update_post_meta($orderId, 'is_magic_checkout_order', 'yes');
|
122 |
+
|
123 |
+
$minCartAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_min_cart_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_min_cart_amount'] : 0;
|
124 |
+
|
125 |
+
// Response sent to the user when order creation fails
|
126 |
+
if ($order->get_total() < $minCartAmount1cc) {
|
127 |
+
$response['status'] = false;
|
128 |
+
$response['message'] = 'Your current order total is ₹' . $order->get_total() . ' — you must have an order with a minimum of ₹' . $minCartAmount1cc . ' to place your order';
|
129 |
+
$response['code'] = 'MIN_CART_AMOUNT_CHECK_FAILED';
|
130 |
+
|
131 |
+
$status = 400;
|
132 |
+
$logObj['response'] = $response;
|
133 |
+
$logObj['rzp_order_id'] = $rzp_order_id;
|
134 |
+
$logObj['rzp_response'] = $rzp_response;
|
135 |
+
rzpLogError(json_encode($logObj));
|
136 |
+
|
137 |
+
return new WP_REST_Response($response, $status);
|
138 |
+
}
|
139 |
+
|
140 |
+
$razorpay = new WC_Razorpay(false);
|
141 |
+
|
142 |
+
$rzp_order_id = $razorpay->createOrGetRazorpayOrderId($orderId, 'yes');
|
143 |
+
$rzp_response = $razorpay->getDefaultCheckoutArguments($order);
|
144 |
+
|
145 |
+
// Response sent to the user when order creation fails
|
146 |
+
if (empty($rzp_response['order_id'])) {
|
147 |
+
$response['status'] = false;
|
148 |
+
$response['message'] = 'Unable to create order';
|
149 |
+
$response['code'] = 'ORDER_CREATION_FAILED';
|
150 |
+
|
151 |
+
$status = 400;
|
152 |
+
$logObj['response'] = $response;
|
153 |
+
$logObj['rzp_order_id'] = $rzp_order_id;
|
154 |
+
$logObj['rzp_response'] = $rzp_response;
|
155 |
+
rzpLogError(json_encode($logObj));
|
156 |
+
|
157 |
+
return new WP_REST_Response($response, $status);
|
158 |
+
}
|
159 |
+
|
160 |
+
// TODO: getDefaultCheckoutArguments() is already being called in L65 above
|
161 |
+
$response = $razorpay->getDefaultCheckoutArguments($order);
|
162 |
+
|
163 |
+
$current_user = wp_get_current_user();
|
164 |
+
|
165 |
+
if ($current_user instanceof WP_User) {
|
166 |
+
update_post_meta($orderId, '_customer_user', $current_user->ID);
|
167 |
+
$response['prefill']['email'] = $current_user->user_email ?? '';
|
168 |
+
$contact = get_user_meta($current_user->ID, 'billing_phone', true);
|
169 |
+
$response['prefill']['contact'] = $contact ? $contact : '';
|
170 |
+
}
|
171 |
+
|
172 |
+
$response['prefill']['coupon_code'] = $couponCode;
|
173 |
+
|
174 |
+
$response['mandatory_login'] = get_option('woocommerce_razorpay_settings')['enable_1cc_mandatory_login'] === 'yes' ? true : false;
|
175 |
+
|
176 |
+
$response['enable_ga_analytics'] = get_option('woocommerce_razorpay_settings')['enable_1cc_ga_analytics'] === 'yes' ? true : false;
|
177 |
+
$response['enable_fb_analytics'] = get_option('woocommerce_razorpay_settings')['enable_1cc_fb_analytics'] === 'yes' ? true : false;
|
178 |
+
$response['redirect'] = true;
|
179 |
+
$response['one_click_checkout'] = true;
|
180 |
+
|
181 |
+
if ($response['enable_fb_analytics'] === true) {
|
182 |
+
//Customer cart related data for FB analytics.
|
183 |
+
$customer_cart['value'] = (string) WC()->cart->subtotal;
|
184 |
+
$customer_cart['content_type'] = 'product';
|
185 |
+
$customer_cart['currency'] = 'INR';
|
186 |
+
|
187 |
+
$x = 0;
|
188 |
+
// Loop over $cart items
|
189 |
+
foreach (WC()->cart->get_cart() as $cart_item) {
|
190 |
+
|
191 |
+
$customer_cart['contents'][$x]['id'] = (string) $cart_item['product_id'];
|
192 |
+
$customer_cart['contents'][$x]['name'] = $cart_item['data']->get_title();
|
193 |
+
$customer_cart['contents'][$x]['quantity'] = (string) $cart_item['quantity'];
|
194 |
+
$customer_cart['contents'][$x]['value'] = (string) ($cart_item['line_subtotal'] + $cart_item['line_subtotal_tax']) / $cart_item['quantity'];
|
195 |
+
$customer_cart['contents'][$x]['variant_id'] = (string) $cart_item['variation_id'];
|
196 |
+
|
197 |
+
$x++;
|
198 |
+
}
|
199 |
+
|
200 |
+
$response['customer_cart'] = $customer_cart ?? '';
|
201 |
+
}
|
202 |
+
|
203 |
+
if (empty(get_option('woocommerce_razorpay_settings')['enable_1cc_cod_intelligence']) === true
|
204 |
+
|| get_option('woocommerce_razorpay_settings')['enable_1cc_cod_intelligence'] != 'yes') {
|
205 |
+
$response['force_cod'] = true;
|
206 |
+
}
|
207 |
+
|
208 |
+
$woocommerce->session->set(RZP_1CC_CART_HASH . $cartHash, $orderId);
|
209 |
+
set_transient(RZP_1CC_CART_HASH . $orderId, $cartHash, 3600);
|
210 |
+
set_transient($razorpay::SESSION_KEY, $orderId, 3600);
|
211 |
+
|
212 |
+
$logObj['response'] = $response;
|
213 |
+
rzpLogInfo(json_encode($logObj));
|
214 |
+
|
215 |
+
return new WP_REST_Response($response, 200);
|
216 |
+
} else {
|
217 |
+
$response['status'] = false;
|
218 |
+
$response['message'] = 'Unable to create woocommerce order';
|
219 |
+
$response['code'] = 'WOOCOMMERCE_ORDER_CREATION_FAILED';
|
220 |
+
|
221 |
+
$logObj['response'] = $response;
|
222 |
+
$logObj['status_code'] = 400;
|
223 |
+
rzpLogError(json_encode($logObj));
|
224 |
+
|
225 |
+
return new WP_REST_Response($response, 400);
|
226 |
+
}
|
227 |
+
}
|
includes/api/save-abandonment-data.php
ADDED
@@ -0,0 +1,162 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* For abandon cart recovery related API
|
4 |
+
*/
|
5 |
+
|
6 |
+
function saveCartAbandonmentData(WP_REST_Request $request)
|
7 |
+
{
|
8 |
+
global $woocommerce;
|
9 |
+
global $wpdb;
|
10 |
+
|
11 |
+
$params = $request->get_params();
|
12 |
+
$rzpOrderId = sanitize_text_field($params['order_id']);
|
13 |
+
|
14 |
+
$logObj = array();
|
15 |
+
$logObj['api'] = "saveCartAbandonmentData";
|
16 |
+
$logObj['params'] = $params;
|
17 |
+
|
18 |
+
$razorpay = new WC_Razorpay(false);
|
19 |
+
$api = $razorpay->getRazorpayApiInstance();
|
20 |
+
try
|
21 |
+
{
|
22 |
+
$razorpayData = $api->order->fetch($rzpOrderId);
|
23 |
+
} catch (Exception $e) {
|
24 |
+
$response['status'] = false;
|
25 |
+
$response['message'] = 'RZP order id does not exist';
|
26 |
+
$statusCode = 400;
|
27 |
+
|
28 |
+
$logObj['response'] = $response;
|
29 |
+
$logObj['status_code'] = $statusCode;
|
30 |
+
rzpLogError(json_encode($logObj));
|
31 |
+
|
32 |
+
return new WP_REST_Response($response, $statusCode);
|
33 |
+
}
|
34 |
+
|
35 |
+
if (isset($razorpayData['receipt'])) {
|
36 |
+
$wcOrderId = $razorpayData['receipt'];
|
37 |
+
|
38 |
+
$order = wc_get_order($wcOrderId);
|
39 |
+
}
|
40 |
+
|
41 |
+
$razorpay->UpdateOrderAddress($razorpayData, $order);
|
42 |
+
|
43 |
+
initCustomerSessionAndCart();
|
44 |
+
|
45 |
+
$customerEmail = get_post_meta($wcOrderId, '_billing_email', true);
|
46 |
+
|
47 |
+
//Retrieving cart products and their quantities.
|
48 |
+
// check plugin is activated or not
|
49 |
+
rzpLogInfo('Woocommerce order id:');
|
50 |
+
rzpLogInfo(json_encode($wcOrderId));
|
51 |
+
|
52 |
+
if (is_plugin_active('woo-cart-abandonment-recovery/woo-cart-abandonment-recovery.php') && empty($customerEmail) == false) {
|
53 |
+
|
54 |
+
$products = WC()->cart->get_cart();
|
55 |
+
$currentTime = current_time('Y-m-d H:i:s');
|
56 |
+
|
57 |
+
if (isset($razorpayData['shipping_fee'])) {
|
58 |
+
$cartTotal = $razorpayData['amount'] / 100 - $razorpayData['shipping_fee'] / 100;
|
59 |
+
} else {
|
60 |
+
$cartTotal = $razorpayData['amount'] / 100;
|
61 |
+
}
|
62 |
+
|
63 |
+
$otherFields = array(
|
64 |
+
'wcf_billing_company' => "",
|
65 |
+
'wcf_billing_address_1' => $razorpayData['customer_details']['billing_address']['line1'] ?? '',
|
66 |
+
'wcf_billing_address_2' => $razorpayData['customer_details']['billing_address']['line2'] ?? '',
|
67 |
+
'wcf_billing_state' => $razorpayData['customer_details']['billing_address']['state'] ?? '',
|
68 |
+
'wcf_billing_postcode' => $razorpayData['customer_details']['billing_address']['zipcode'] ?? '',
|
69 |
+
'wcf_shipping_first_name' => $razorpayData['customer_details']['billing_address']['name'] ?? '',
|
70 |
+
'wcf_shipping_last_name' => "",
|
71 |
+
'wcf_shipping_company' => "",
|
72 |
+
'wcf_shipping_country' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
|
73 |
+
'wcf_shipping_address_1' => $razorpayData['customer_details']['shipping_address']['line1'] ?? '',
|
74 |
+
'wcf_shipping_address_2' => $razorpayData['customer_details']['shipping_address']['line2'] ?? '',
|
75 |
+
'wcf_shipping_city' => $razorpayData['customer_details']['shipping_address']['city'] ?? '',
|
76 |
+
'wcf_shipping_state' => $razorpayData['customer_details']['shipping_address']['state'] ?? '',
|
77 |
+
'wcf_shipping_postcode' => $razorpayData['customer_details']['shipping_address']['zipcode'] ?? '',
|
78 |
+
'wcf_order_comments' => "",
|
79 |
+
'wcf_first_name' => $razorpayData['customer_details']['shipping_address']['name'] ?? '',
|
80 |
+
'wcf_last_name' => "",
|
81 |
+
'wcf_phone_number' => $razorpayData['customer_details']['shipping_address']['contact'] ?? '',
|
82 |
+
'wcf_location' => $razorpayData['customer_details']['shipping_address']['country'] ?? '',
|
83 |
+
);
|
84 |
+
|
85 |
+
$checkoutDetails = array(
|
86 |
+
'email' => $razorpayData['customer_details']['email'] ?? $customerEmail,
|
87 |
+
'cart_contents' => serialize($products),
|
88 |
+
'cart_total' => sanitize_text_field($cartTotal),
|
89 |
+
'time' => $currentTime,
|
90 |
+
'other_fields' => serialize($otherFields),
|
91 |
+
'checkout_id' => wc_get_page_id('cart'),
|
92 |
+
);
|
93 |
+
|
94 |
+
$sessionId = WC()->session->get('wcf_session_id');
|
95 |
+
|
96 |
+
$cartAbandonmentTable = $wpdb->prefix . "cartflows_ca_cart_abandonment";
|
97 |
+
|
98 |
+
$logObj['checkoutDetails'] = $checkoutDetails;
|
99 |
+
|
100 |
+
if (empty($checkoutDetails) == false) {
|
101 |
+
$result = $wpdb->get_row(
|
102 |
+
$wpdb->prepare('SELECT * FROM `' . $cartAbandonmentTable . '` WHERE session_id = %s and order_status IN (%s, %s)', $sessionId, 'normal', 'abandoned') // phpcs:ignore
|
103 |
+
);
|
104 |
+
|
105 |
+
if (isset($result)) {
|
106 |
+
$wpdb->update(
|
107 |
+
$cartAbandonmentTable,
|
108 |
+
$checkoutDetails,
|
109 |
+
array('session_id' => $sessionId)
|
110 |
+
);
|
111 |
+
|
112 |
+
if ($wpdb->last_error) {
|
113 |
+
$response['status'] = false;
|
114 |
+
$response['message'] = $wpdb->last_error;
|
115 |
+
$statusCode = 400;
|
116 |
+
} else {
|
117 |
+
$response['status'] = true;
|
118 |
+
$response['message'] = 'Data successfully updated for wooCommerce cart abandonment recovery';
|
119 |
+
$statusCode = 200;
|
120 |
+
}
|
121 |
+
|
122 |
+
} else {
|
123 |
+
$sessionId = md5(uniqid(wp_rand(), true));
|
124 |
+
$checkoutDetails['session_id'] = sanitize_text_field($sessionId);
|
125 |
+
|
126 |
+
// Inserting row into Database.
|
127 |
+
$wpdb->insert(
|
128 |
+
$cartAbandonmentTable,
|
129 |
+
$checkoutDetails
|
130 |
+
);
|
131 |
+
|
132 |
+
if ($wpdb->last_error) {
|
133 |
+
$response['status'] = false;
|
134 |
+
$response['message'] = $wpdb->last_error;
|
135 |
+
$statusCode = 400;
|
136 |
+
} else {
|
137 |
+
// Storing session_id in WooCommerce session.
|
138 |
+
WC()->session->set('wcf_session_id', $sessionId);
|
139 |
+
$response['status'] = true;
|
140 |
+
$response['message'] = 'Data successfully inserted for wooCommerce cart abandonment recovery';
|
141 |
+
$statusCode = 200;
|
142 |
+
}
|
143 |
+
}
|
144 |
+
|
145 |
+
$logObj['response'] = $response;
|
146 |
+
$logObj['status_code'] = $statusCode;
|
147 |
+
rzpLogInfo(json_encode($logObj));
|
148 |
+
}
|
149 |
+
|
150 |
+
} else {
|
151 |
+
$response['status'] = false;
|
152 |
+
$response['message'] = 'Failed to insert data';
|
153 |
+
$statusCode = 400;
|
154 |
+
|
155 |
+
$logObj['response'] = $response;
|
156 |
+
$logObj['status_code'] = $statusCode;
|
157 |
+
rzpLogInfo(json_encode($logObj));
|
158 |
+
}
|
159 |
+
|
160 |
+
return new WP_REST_Response($response, $statusCode);
|
161 |
+
|
162 |
+
}
|
includes/api/shipping-info.php
ADDED
@@ -0,0 +1,422 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Given shipping address and product, attempts to calculate available shipping rates for the address.
|
4 |
+
* Doesn't support shipping > 1 address.
|
5 |
+
*
|
6 |
+
* @param WP_REST_Request $request JSON request for shipping endpoint.
|
7 |
+
* @return array|WP_Error|WP_REST_Response
|
8 |
+
* @throws Exception If failed to add items to cart or no shipping options available for address.
|
9 |
+
*/
|
10 |
+
function calculateShipping1cc(WP_REST_Request $request)
|
11 |
+
{
|
12 |
+
$params = $request->get_params();
|
13 |
+
|
14 |
+
$logObj = array();
|
15 |
+
$logObj['api'] = 'calculateShipping1cc';
|
16 |
+
$logObj['params'] = $params;
|
17 |
+
|
18 |
+
$validateInput = validateInput('shipping', $params);
|
19 |
+
|
20 |
+
if ($validateInput != null) {
|
21 |
+
$response['failure_reason'] = $validateInput;
|
22 |
+
$response['failure_code'] = 'VALIDATION_ERROR';
|
23 |
+
$logObj['response'] = $response;
|
24 |
+
rzpLogError(json_encode($logObj));
|
25 |
+
return new WP_REST_Response($response, 400);
|
26 |
+
}
|
27 |
+
|
28 |
+
$cartResponse = false;
|
29 |
+
$orderId = (int) sanitize_text_field($params['order_id']);
|
30 |
+
$addresses = $params['addresses'];
|
31 |
+
|
32 |
+
initCustomerSessionAndCart();
|
33 |
+
// Cleanup cart.
|
34 |
+
WC()->cart->empty_cart();
|
35 |
+
|
36 |
+
$cartResponse = create1ccCart($orderId);
|
37 |
+
|
38 |
+
if ($cartResponse === false) {
|
39 |
+
$response['status'] = false;
|
40 |
+
$response['failure_reason'] = 'Invalid merchant order id';
|
41 |
+
$response['failure_code'] = 'VALIDATION_ERROR';
|
42 |
+
$logObj['response'] = $response;
|
43 |
+
rzpLogError(json_encode($logObj));
|
44 |
+
return new WP_REST_Response($response, 400);
|
45 |
+
}
|
46 |
+
|
47 |
+
foreach ($addresses as $address) {
|
48 |
+
if ($cartResponse) {
|
49 |
+
$customerResponse = shippingUpdateCustomerInformation1cc($address);
|
50 |
+
}
|
51 |
+
|
52 |
+
if ($customerResponse) {
|
53 |
+
$response[] = shippingCalculatePackages1cc($address['id'], $orderId);
|
54 |
+
} else {
|
55 |
+
$response['failure_reason'] = 'Set customer shipping information failed';
|
56 |
+
$response['failure_code'] = 'VALIDATION_ERROR';
|
57 |
+
$logger->log('info', json_encode($response), array('source' => 'rzp1cc'));
|
58 |
+
return new WP_REST_Response($response, 400);
|
59 |
+
}
|
60 |
+
}
|
61 |
+
|
62 |
+
// Cleanup cart.
|
63 |
+
WC()->cart->empty_cart();
|
64 |
+
$logObj['response'] = $response;
|
65 |
+
rzpLogInfo(json_encode($logObj));
|
66 |
+
return new WP_REST_Response(array('addresses' => $response), 200);
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Update customer information.
|
71 |
+
*
|
72 |
+
* @param array $params The request params.
|
73 |
+
*
|
74 |
+
* @return mixed
|
75 |
+
*/
|
76 |
+
function shippingUpdateCustomerInformation1cc($params)
|
77 |
+
{
|
78 |
+
|
79 |
+
$wcStateCode = normalizeWcStateCode($params['state_code']);
|
80 |
+
|
81 |
+
// Update customer information.
|
82 |
+
WC()->customer->set_props(
|
83 |
+
array(
|
84 |
+
'shipping_country' => sanitize_text_field(strtoupper($params['country'])),
|
85 |
+
'shipping_state' => sanitize_text_field(strtoupper($wcStateCode)),
|
86 |
+
'shipping_postcode' => sanitize_text_field($params['zipcode']),
|
87 |
+
'shipping_city' => sanitize_text_field($params['city']), //This field is required for custom shipping plugin support.
|
88 |
+
)
|
89 |
+
);
|
90 |
+
|
91 |
+
// Calculate shipping.
|
92 |
+
WC()->cart->calculate_shipping();
|
93 |
+
WC()->cart->calculate_totals();
|
94 |
+
|
95 |
+
// See if we need to calculate anything
|
96 |
+
if (!WC()->cart->needs_shipping()) {
|
97 |
+
return new WP_Error('shipping_methods_error', 'no shipping methods available for product and address', array('status' => 400));
|
98 |
+
}
|
99 |
+
|
100 |
+
// Return true for no error.
|
101 |
+
return true;
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Calculate packages
|
106 |
+
*
|
107 |
+
* @return mixed
|
108 |
+
*/
|
109 |
+
function shippingCalculatePackages1cc($id, $orderId)
|
110 |
+
{
|
111 |
+
// Get packages for the cart.
|
112 |
+
$packages = WC()->cart->get_shipping_packages();
|
113 |
+
|
114 |
+
// Currently we only support 1 shipping address per package.
|
115 |
+
if (count($packages) > 1) {
|
116 |
+
// Perform address check to make sure all are the same
|
117 |
+
for ($x = 1; $x < count($packages); $x++) {
|
118 |
+
if ($packages[0]->destination !== $packages[$x]->destination) {
|
119 |
+
return new WP_Error('shipping_packages', 'Shipping package to > 1 address is not supported', array('status' => 400));
|
120 |
+
}
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
$vendorId = array();
|
125 |
+
$isStoreShippingEnabled = "";
|
126 |
+
|
127 |
+
// check shipping option in multivendor plugin
|
128 |
+
if (class_exists('WCFMmp')) {
|
129 |
+
$shippingOptions = get_option('wcfm_shipping_options', array());
|
130 |
+
// By default store shipping should be consider enable
|
131 |
+
$isStoreShippingEnabled = isset($shippingOptions['enable_store_shipping']) ? $shippingOptions['enable_store_shipping'] : 'yes';
|
132 |
+
}
|
133 |
+
|
134 |
+
// Add package ID to array.
|
135 |
+
foreach ($packages as $key => $package) {
|
136 |
+
if (!isset($packages[$key]['package_id'])) {
|
137 |
+
$packages[$key]['package_id'] = $key;
|
138 |
+
}
|
139 |
+
|
140 |
+
if (isset($packages[$key]['vendor_id']) && $isStoreShippingEnabled == 'yes') {
|
141 |
+
$vendorId[] = $packages[$key]['vendor_id'];
|
142 |
+
}
|
143 |
+
}
|
144 |
+
$calculatedPackages = wc()->shipping()->calculate_shipping($packages);
|
145 |
+
|
146 |
+
return getItemResponse1cc($calculatedPackages, $id, $vendorId, $orderId);
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Build JSON response for line item.
|
151 |
+
*
|
152 |
+
* @param array $package WooCommerce shipping packages.
|
153 |
+
* @return array
|
154 |
+
*/
|
155 |
+
function getItemResponse1cc($package, $id, $vendorId, $orderId)
|
156 |
+
{
|
157 |
+
|
158 |
+
// Add product names and quantities.
|
159 |
+
$items = array();
|
160 |
+
|
161 |
+
//To support advancd free shipping plugin
|
162 |
+
if (is_plugin_active('woocommerce-advanced-free-shipping/woocommerce-advanced-free-shipping.php')) {
|
163 |
+
include_once ABSPATH . 'wp-content/plugins/woocommerce-advanced-free-shipping/woocommerce-advanced-free-shipping.php';
|
164 |
+
|
165 |
+
if (class_exists('Wafs_Free_Shipping_Method')) {
|
166 |
+
$wasp_method = new Wafs_Free_Shipping_Method();
|
167 |
+
$advancedFreeShipping = $wasp_method->calculate_shipping($package[0]);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
|
171 |
+
$shippingResponse = prepareRatesResponse1cc($package, $vendorId, $orderId);
|
172 |
+
|
173 |
+
$isServiceable = count($shippingResponse) > 0 ? true : false;
|
174 |
+
// TODO: also return 'state'?
|
175 |
+
return array(
|
176 |
+
'id' => $id,
|
177 |
+
'zipcode' => $package[0]['destination']['postcode'],
|
178 |
+
'state_code' => $package[0]['destination']['state'],
|
179 |
+
'country' => $package[0]['destination']['country'],
|
180 |
+
'serviceable' => $isServiceable,
|
181 |
+
'cod' => $isServiceable === false ? false : $shippingResponse['cod'],
|
182 |
+
'shipping_fee' => isset($shippingResponse['shipping_fee']) ? ($shippingResponse['shipping_fee'] + $shippingResponse['shipping_fee_tax']) : 0,
|
183 |
+
// hardcode as null as wc does not provide support
|
184 |
+
'cod_fee' => null,
|
185 |
+
);
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Prepare an array of rates from a package for the response.
|
190 |
+
*
|
191 |
+
* @param array $package Shipping package complete with rates from WooCommerce.
|
192 |
+
* @return array
|
193 |
+
*/
|
194 |
+
function prepareRatesResponse1cc($package, $vendorId, $orderId)
|
195 |
+
{
|
196 |
+
|
197 |
+
$response = array();
|
198 |
+
|
199 |
+
if (isset($vendorId)) {
|
200 |
+
foreach ($vendorId as $id) {
|
201 |
+
$rates = $package[$id]['rates'];
|
202 |
+
foreach ($rates as $rate) {
|
203 |
+
$response[] = getRateResponse1cc($rate, $id, $orderId);
|
204 |
+
}
|
205 |
+
}
|
206 |
+
}
|
207 |
+
|
208 |
+
$rates = $package[0]['rates'];
|
209 |
+
foreach ($rates as $val) {
|
210 |
+
$response[] = getRateResponse1cc($val, "", $orderId);
|
211 |
+
}
|
212 |
+
|
213 |
+
if (empty($response) === true) {
|
214 |
+
return array();
|
215 |
+
}
|
216 |
+
// add shipping in postmeta for multivendor plugin
|
217 |
+
add_post_meta($orderId, '1cc_shippinginfo', $response);
|
218 |
+
|
219 |
+
// Choosing the lowest shipping rate
|
220 |
+
$price = array();
|
221 |
+
foreach ($response as $key => $row) {
|
222 |
+
$price[$key] = $row['price'];
|
223 |
+
}
|
224 |
+
// we only consider the lowest shipping fee
|
225 |
+
array_multisort($price, SORT_ASC, $response);
|
226 |
+
|
227 |
+
if (!empty($vendorId)) {
|
228 |
+
foreach ($response as $key => $row) {
|
229 |
+
$response['shipping_fee'] += isset($response[$key]['price']) ? $response[$key]['price'] : 0;
|
230 |
+
$response['shipping_fee_tax'] += !empty($response[$key]['taxes']) ? 0 : 0; //By default tax is considered as zero.
|
231 |
+
}
|
232 |
+
} else {
|
233 |
+
$response['shipping_fee'] = isset($response[0]['price']) ? $response[0]['price'] : 0;
|
234 |
+
$response['shipping_fee_tax'] = !empty($response[0]['taxes']) ? 0 : 0; //By default tax is considered as zero.
|
235 |
+
}
|
236 |
+
$response['cod'] = isset($response[0]['cod']) ? $response[0]['cod'] : false;
|
237 |
+
|
238 |
+
return $response;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Response for a single rate.
|
243 |
+
*
|
244 |
+
* @param WC_Shipping_Rate $rate Rate object.
|
245 |
+
* @return array
|
246 |
+
*/
|
247 |
+
|
248 |
+
function getRateResponse1cc($rate, $vendorId, $orderId)
|
249 |
+
{
|
250 |
+
|
251 |
+
return array_merge(
|
252 |
+
array(
|
253 |
+
'rate_id' => getRateProp1cc($rate, 'id'),
|
254 |
+
'name' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'label')),
|
255 |
+
'description' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'description')),
|
256 |
+
'delivery_time' => prepareHtmlResponse1cc(getRateProp1cc($rate, 'delivery_time')),
|
257 |
+
'price' => convertToPaisa(getRateProp1cc($rate, 'cost')),
|
258 |
+
'taxes' => getRateProp1cc($rate, 'taxes'),
|
259 |
+
'instance_id' => getRateProp1cc($rate, 'instance_id'),
|
260 |
+
'method_id' => getRateProp1cc($rate, 'method_id'),
|
261 |
+
'meta_data' => getRateMetaData1cc($rate),
|
262 |
+
'vendor_id' => $vendorId,
|
263 |
+
'cod' => getCodShippingInfo1cc(getRateProp1cc($rate, 'instance_id'), getRateProp1cc($rate, 'method_id'), $orderId),
|
264 |
+
),
|
265 |
+
getStoreCurrencyResponse1cc()
|
266 |
+
);
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Verify whether COD availbale for the shipping method
|
271 |
+
*
|
272 |
+
* @returns bool
|
273 |
+
*/
|
274 |
+
function getCodShippingInfo1cc($instanceId, $methodId, $orderId)
|
275 |
+
{
|
276 |
+
|
277 |
+
global $woocommerce;
|
278 |
+
|
279 |
+
$availablePaymentMethods = WC()->payment_gateways->payment_gateways();
|
280 |
+
|
281 |
+
if (!isset($availablePaymentMethods['cod']) || 'no' == $availablePaymentMethods['cod']->enabled || !(($minCODAmount1cc <= $amount) && ($maxCODAmount1cc <= $amount))) {
|
282 |
+
return false;
|
283 |
+
}
|
284 |
+
|
285 |
+
$minCODAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_min_COD_slab_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_min_COD_slab_amount'] : 0;
|
286 |
+
$maxCODAmount1cc = !empty(get_option('woocommerce_razorpay_settings')['1cc_max_COD_slab_amount']) ? get_option('woocommerce_razorpay_settings')['1cc_max_COD_slab_amount'] : 0;
|
287 |
+
|
288 |
+
$order = wc_get_order($orderId);
|
289 |
+
$amount = floatval($order->get_total());
|
290 |
+
|
291 |
+
//To verify the min order amount required to place COD order
|
292 |
+
if (!($minCODAmount1cc <= $amount)) {
|
293 |
+
return false;
|
294 |
+
}
|
295 |
+
|
296 |
+
//To verify the max order amount restriction to place COD order
|
297 |
+
if ($maxCODAmount1cc != 0 && ($maxCODAmount1cc <= $amount)) {
|
298 |
+
return false;
|
299 |
+
}
|
300 |
+
|
301 |
+
if (isset($availablePaymentMethods['cod'])) {
|
302 |
+
$shipping_method_ids_cod = $availablePaymentMethods['cod']->enable_for_methods;
|
303 |
+
|
304 |
+
foreach ($shipping_method_ids_cod as $shipping_method_id) {
|
305 |
+
|
306 |
+
$shippingInstanceId[] = end(explode(':', $shipping_method_id));
|
307 |
+
|
308 |
+
if (in_array('flat_rate', $shippingInstanceId) && ($methodId === 'flat_rate')) {
|
309 |
+
return true;
|
310 |
+
} elseif (in_array('free_shipping', $shippingInstanceId) && ($methodId === 'free_shipping')) {
|
311 |
+
return true;
|
312 |
+
} elseif (in_array($instanceId, $shippingInstanceId)) {
|
313 |
+
return true;
|
314 |
+
}
|
315 |
+
}
|
316 |
+
}
|
317 |
+
return false;
|
318 |
+
}
|
319 |
+
|
320 |
+
/**
|
321 |
+
* Convert to paisa
|
322 |
+
* @returns int
|
323 |
+
*/
|
324 |
+
function convertToPaisa($price)
|
325 |
+
{
|
326 |
+
if (is_string($price)) {
|
327 |
+
$price = (int) $price;
|
328 |
+
}
|
329 |
+
return $price * 100;
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Prepares a list of store currency data to return in responses.
|
334 |
+
* @return array
|
335 |
+
*/
|
336 |
+
function getStoreCurrencyResponse1cc()
|
337 |
+
{
|
338 |
+
$position = get_option('woocommerce_currency_pos');
|
339 |
+
$symbol = html_entity_decode(get_woocommerce_currency_symbol());
|
340 |
+
$prefix = '';
|
341 |
+
$suffix = '';
|
342 |
+
|
343 |
+
switch ($position) {
|
344 |
+
case 'left_space':
|
345 |
+
$prefix = $symbol . ' ';
|
346 |
+
break;
|
347 |
+
case 'left':
|
348 |
+
$prefix = $symbol;
|
349 |
+
break;
|
350 |
+
case 'right_space':
|
351 |
+
$suffix = ' ' . $symbol;
|
352 |
+
break;
|
353 |
+
case 'right':
|
354 |
+
$suffix = $symbol;
|
355 |
+
break;
|
356 |
+
default:
|
357 |
+
break;
|
358 |
+
}
|
359 |
+
|
360 |
+
return array(
|
361 |
+
'currency_code' => get_woocommerce_currency(),
|
362 |
+
'currency_symbol' => $symbol,
|
363 |
+
'currency_minor_unit' => wc_get_price_decimals(),
|
364 |
+
'currency_decimal_separator' => wc_get_price_decimal_separator(),
|
365 |
+
'currency_thousand_separator' => wc_get_price_thousand_separator(),
|
366 |
+
'currency_prefix' => $prefix,
|
367 |
+
'currency_suffix' => $suffix,
|
368 |
+
);
|
369 |
+
}
|
370 |
+
|
371 |
+
/**
|
372 |
+
* Gets a prop of the rate object, if callable.
|
373 |
+
*
|
374 |
+
* @param WC_Shipping_Rate $rate Rate object.
|
375 |
+
* @param string $prop Prop name.
|
376 |
+
* @return string
|
377 |
+
*/
|
378 |
+
function getRateProp1cc($rate, $prop)
|
379 |
+
{
|
380 |
+
$getter = 'get_' . $prop;
|
381 |
+
return \is_callable(array($rate, $getter)) ? $rate->$getter() : '';
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* Converts rate meta data into a suitable response object.
|
386 |
+
*
|
387 |
+
* @param WC_Shipping_Rate $rate Rate object.
|
388 |
+
* @return array
|
389 |
+
*/
|
390 |
+
function getRateMetaData1cc($rate)
|
391 |
+
{
|
392 |
+
$metaData = $rate->get_meta_data();
|
393 |
+
|
394 |
+
return array_reduce(
|
395 |
+
array_keys($metaData),
|
396 |
+
function ($return, $key) use ($metaData) {
|
397 |
+
$return[] = array(
|
398 |
+
'key' => $key,
|
399 |
+
'value' => $metaData[$key],
|
400 |
+
);
|
401 |
+
return $return;
|
402 |
+
},
|
403 |
+
array()
|
404 |
+
);
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Prepares HTML based content, such as post titles and content, for the API response.
|
409 |
+
*
|
410 |
+
* The wptexturize, convert_chars, and trim functions are also used in the `the_title` filter.
|
411 |
+
* The function wp_kses_post removes disallowed HTML tags.
|
412 |
+
*
|
413 |
+
* @param string|array $response Data to format.
|
414 |
+
* @return string|array Formatted data.
|
415 |
+
*/
|
416 |
+
function prepareHtmlResponse1cc($response)
|
417 |
+
{
|
418 |
+
if (is_array($response)) {
|
419 |
+
return array_map('prepareHtmlResponse1cc', $response);
|
420 |
+
}
|
421 |
+
return is_scalar($response) ? wp_kses_post(trim(convert_chars(wptexturize($response)))) : $response;
|
422 |
+
}
|
includes/debug.php
ADDED
@@ -0,0 +1,141 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Log a message if Razorpay debug mode is enabled.
|
5 |
+
*
|
6 |
+
* @param string $level
|
7 |
+
* 'emergency': System is unusable.
|
8 |
+
* 'alert': Action must be taken immediately.
|
9 |
+
* 'critical': Critical conditions.
|
10 |
+
* 'error': Error conditions.
|
11 |
+
* 'warning': Warning conditions.
|
12 |
+
* 'notice': Normal but significant condition.
|
13 |
+
* 'info': Informational messages.
|
14 |
+
* 'debug': Debug-level messages.
|
15 |
+
* @param string $message Message to log.
|
16 |
+
*/
|
17 |
+
define('RAZORPAY_LOG_NAME', 'razorpay-logs');
|
18 |
+
|
19 |
+
function rzpLog($level, $message)
|
20 |
+
{
|
21 |
+
if (isDebugModeEnabled()) {
|
22 |
+
$logger = wc_get_logger();
|
23 |
+
$logger->log($level, $message, array('source' => RAZORPAY_LOG_NAME));
|
24 |
+
}
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Adds an emergency level message if Razorpay debug mode is enabled
|
29 |
+
*
|
30 |
+
* System is unusable.
|
31 |
+
*
|
32 |
+
* @see WC_Logger::log
|
33 |
+
*
|
34 |
+
* @param string $message Message to log.
|
35 |
+
*/
|
36 |
+
function rzpLogEmergency($message)
|
37 |
+
{
|
38 |
+
rzpLog('emergency', $message);
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Adds an alert level message if Razorpay debug mode is enabled.
|
43 |
+
*
|
44 |
+
* Action must be taken immediately.
|
45 |
+
* Example: Entire website down, database unavailable, etc.
|
46 |
+
*
|
47 |
+
* @see WC_Logger::log
|
48 |
+
*
|
49 |
+
* @param string $message Message to log.
|
50 |
+
*/
|
51 |
+
function rzpLogAlert($message)
|
52 |
+
{
|
53 |
+
rzpLog('alert', $message);
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Adds a critical level message if Razorpay debug mode is enabled.
|
58 |
+
*
|
59 |
+
* Critical conditions.
|
60 |
+
* Example: Application component unavailable, unexpected exception.
|
61 |
+
*
|
62 |
+
* @see WC_Logger::log
|
63 |
+
*
|
64 |
+
* @param string $message Message to log.
|
65 |
+
*/
|
66 |
+
function rzpLogCritical($message)
|
67 |
+
{
|
68 |
+
rzpLog('critical', $message);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Adds an error level message if Razorpay debug mode is enabled.
|
73 |
+
*
|
74 |
+
* Runtime errors that do not require immediate action but should typically be logged
|
75 |
+
* and monitored.
|
76 |
+
*
|
77 |
+
* @see WC_Logger::log
|
78 |
+
*
|
79 |
+
* @param string $message Message to log.
|
80 |
+
*/
|
81 |
+
function rzpLogError($message)
|
82 |
+
{
|
83 |
+
rzpLog('error', $message);
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Adds a warning level message if Razorpay debug mode is enabled.
|
88 |
+
*
|
89 |
+
* Exceptional occurrences that are not errors.
|
90 |
+
*
|
91 |
+
* Example: Use of deprecated APIs, poor use of an API, undesirable things that are not
|
92 |
+
* necessarily wrong.
|
93 |
+
*
|
94 |
+
* @see WC_Logger::log
|
95 |
+
*
|
96 |
+
* @param string $message Message to log.
|
97 |
+
*/
|
98 |
+
function rzpRazorpay_log_warning($message)
|
99 |
+
{
|
100 |
+
rzpLog('warning', $message);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Adds a notice level message if Razorpay debug mode is enabled.
|
105 |
+
*
|
106 |
+
* Normal but significant events.
|
107 |
+
*
|
108 |
+
* @see WC_Logger::log
|
109 |
+
*
|
110 |
+
* @param string $message Message to log.
|
111 |
+
*/
|
112 |
+
function rzpLogNotice($message)
|
113 |
+
{
|
114 |
+
rzpLog('notice', $message);
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Adds a info level message if Razorpay debug mode is enabled
|
119 |
+
*
|
120 |
+
* Interesting events.
|
121 |
+
* Example: User logs in, SQL logs
|
122 |
+
*
|
123 |
+
* @see WC_Logger::log
|
124 |
+
*
|
125 |
+
* @param string $message Message to log.
|
126 |
+
*/
|
127 |
+
function rzpLogInfo($message)
|
128 |
+
{
|
129 |
+
rzpLog('info', $message);
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Adds a debug level message if Razorpay debug mode is enabled
|
134 |
+
* Detailed debug information
|
135 |
+
* @see WC_Logger::log
|
136 |
+
* @param string $message Message to log
|
137 |
+
*/
|
138 |
+
function rzpLogDebug($message)
|
139 |
+
{
|
140 |
+
rzpLog('debug', $message);
|
141 |
+
}
|
includes/razorpay-route.php
CHANGED
@@ -1039,12 +1039,12 @@ function razorpayPaymentsView(){
|
|
1039 |
function adminEnqueueScriptsFunc()
|
1040 |
{
|
1041 |
//$name, $src, $dependencies, $version, $in_footer
|
1042 |
-
wp_enqueue_script( 'route-script', plugin_dir_url(dirname(__FILE__)) . 'js/woo_route.js', array( 'jquery' ), null, true );
|
1043 |
-
wp_enqueue_script( 'bootstrap-script', plugin_dir_url(dirname(__FILE__)) . 'js/bootstrap.min.js', array( 'jquery' ), null, true );
|
1044 |
|
1045 |
-
wp_register_style('bootstrap-css', plugin_dir_url(dirname(__FILE__)) . 'css/bootstrap.min.css',
|
1046 |
null, null);
|
1047 |
-
wp_register_style('woo_route-css', plugin_dir_url(dirname(__FILE__)) . 'css/woo_route.css',
|
1048 |
null, null);
|
1049 |
wp_enqueue_style('bootstrap-css');
|
1050 |
wp_enqueue_style('woo_route-css');
|
1039 |
function adminEnqueueScriptsFunc()
|
1040 |
{
|
1041 |
//$name, $src, $dependencies, $version, $in_footer
|
1042 |
+
wp_enqueue_script( 'route-script', plugin_dir_url(dirname(__FILE__)) . 'public/js/woo_route.js', array( 'jquery' ), null, true );
|
1043 |
+
wp_enqueue_script( 'bootstrap-script', plugin_dir_url(dirname(__FILE__)) . 'public/js/bootstrap.min.js', array( 'jquery' ), null, true );
|
1044 |
|
1045 |
+
wp_register_style('bootstrap-css', plugin_dir_url(dirname(__FILE__)) . 'public/css/bootstrap.min.css',
|
1046 |
null, null);
|
1047 |
+
wp_register_style('woo_route-css', plugin_dir_url(dirname(__FILE__)) . 'public/css/woo_route.css',
|
1048 |
null, null);
|
1049 |
wp_enqueue_style('bootstrap-css');
|
1050 |
wp_enqueue_style('woo_route-css');
|
includes/razorpay-webhook.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
require_once __DIR__.'/../woo-razorpay.php';
|
4 |
-
require_once __DIR__.'/../razorpay-sdk/Razorpay.php';
|
5 |
|
6 |
use Razorpay\Api\Api;
|
7 |
use Razorpay\Api\Errors;
|
@@ -23,13 +23,13 @@ class RZP_Webhook
|
|
23 |
/**
|
24 |
* Event constants
|
25 |
*/
|
26 |
-
const PAYMENT_AUTHORIZED
|
27 |
-
const PAYMENT_FAILED
|
28 |
-
const SUBSCRIPTION_CANCELLED
|
29 |
-
const REFUNDED_CREATED
|
30 |
-
const VIRTUAL_ACCOUNT_CREDITED
|
31 |
-
const SUBSCRIPTION_PAUSED
|
32 |
-
const SUBSCRIPTION_RESUMED
|
33 |
|
34 |
protected $eventsArray = [
|
35 |
self::PAYMENT_AUTHORIZED,
|
@@ -38,7 +38,7 @@ class RZP_Webhook
|
|
38 |
self::PAYMENT_FAILED,
|
39 |
self::SUBSCRIPTION_CANCELLED,
|
40 |
self::SUBSCRIPTION_PAUSED,
|
41 |
-
self::SUBSCRIPTION_RESUMED
|
42 |
];
|
43 |
|
44 |
public function __construct()
|
@@ -70,54 +70,50 @@ class RZP_Webhook
|
|
70 |
|
71 |
$data = json_decode($post, true);
|
72 |
|
73 |
-
if (json_last_error() !== 0)
|
74 |
-
{
|
75 |
return;
|
76 |
}
|
77 |
|
78 |
$enabled = $this->razorpay->getSetting('enable_webhook');
|
79 |
|
80 |
if (($enabled === 'yes') and
|
81 |
-
(empty($data['event']) === false))
|
82 |
-
{
|
83 |
// Skip the webhook if not the valid data and event
|
84 |
-
if ($this->shouldConsumeWebhook($data) === false)
|
85 |
-
{
|
86 |
return;
|
87 |
}
|
88 |
|
89 |
-
if (isset($_SERVER['HTTP_X_RAZORPAY_SIGNATURE']) === true)
|
90 |
-
{
|
91 |
$razorpayWebhookSecret = $this->razorpay->getSetting('webhook_secret');
|
92 |
|
93 |
//
|
94 |
// If the webhook secret isn't set on wordpress, return
|
95 |
//
|
96 |
-
if (empty($razorpayWebhookSecret) === true)
|
97 |
-
{
|
98 |
return;
|
99 |
}
|
100 |
|
101 |
try
|
102 |
{
|
103 |
$this->api->utility->verifyWebhookSignature($post,
|
104 |
-
|
105 |
-
|
106 |
-
}
|
107 |
-
catch (Errors\SignatureVerificationError $e)
|
108 |
-
{
|
109 |
$log = array(
|
110 |
-
'message'
|
111 |
-
'data'
|
112 |
-
'event'
|
113 |
);
|
114 |
|
115 |
error_log(json_encode($log));
|
116 |
return;
|
117 |
}
|
118 |
|
119 |
-
|
120 |
-
|
|
|
|
|
|
|
121 |
case self::PAYMENT_AUTHORIZED:
|
122 |
return $this->paymentAuthorized($data);
|
123 |
|
@@ -190,8 +186,7 @@ class RZP_Webhook
|
|
190 |
protected function paymentAuthorized(array $data)
|
191 |
{
|
192 |
// We don't process subscription/invoice payments here
|
193 |
-
if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
|
194 |
-
{
|
195 |
return;
|
196 |
}
|
197 |
|
@@ -200,11 +195,27 @@ class RZP_Webhook
|
|
200 |
//
|
201 |
$orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
|
202 |
|
|
|
|
|
203 |
$order = wc_get_order($orderId);
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
// If it is already marked as paid, ignore the event
|
206 |
-
if ($order->needs_payment() === false)
|
207 |
-
|
|
|
208 |
return;
|
209 |
}
|
210 |
|
@@ -214,16 +225,13 @@ class RZP_Webhook
|
|
214 |
|
215 |
$amount = $this->getOrderAmountAsInteger($order);
|
216 |
|
217 |
-
$success
|
218 |
$errorMessage = 'The payment has failed.';
|
219 |
|
220 |
-
if ($payment['status'] === 'captured')
|
221 |
-
{
|
222 |
$success = true;
|
223 |
-
}
|
224 |
-
|
225 |
-
($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE))
|
226 |
-
{
|
227 |
//
|
228 |
// If the payment is only authorized, we capture it
|
229 |
// If the merchant has enabled auto capture
|
@@ -233,16 +241,14 @@ class RZP_Webhook
|
|
233 |
$payment->capture(array('amount' => $amount));
|
234 |
|
235 |
$success = true;
|
236 |
-
}
|
237 |
-
catch (Exception $e)
|
238 |
-
{
|
239 |
//
|
240 |
// Capture will fail if the payment is already captured
|
241 |
//
|
242 |
$log = array(
|
243 |
-
'message'
|
244 |
-
'payment_id'
|
245 |
-
'event'
|
246 |
);
|
247 |
|
248 |
error_log(json_encode($log));
|
@@ -252,14 +258,16 @@ class RZP_Webhook
|
|
252 |
//
|
253 |
$payment = $this->getPaymentEntity($razorpayPaymentId, $data);
|
254 |
|
255 |
-
if ($payment['status'] === 'captured')
|
256 |
-
{
|
257 |
$success = true;
|
258 |
}
|
259 |
}
|
260 |
}
|
261 |
|
262 |
$this->razorpay->updateOrder($order, $success, $errorMessage, $razorpayPaymentId, null, true);
|
|
|
|
|
|
|
263 |
|
264 |
// Graceful exit since payment is now processed.
|
265 |
exit;
|
@@ -273,8 +281,7 @@ class RZP_Webhook
|
|
273 |
protected function virtualAccountCredited(array $data)
|
274 |
{
|
275 |
// We don't process subscription/invoice payments here
|
276 |
-
if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
|
277 |
-
{
|
278 |
return;
|
279 |
}
|
280 |
|
@@ -286,8 +293,7 @@ class RZP_Webhook
|
|
286 |
$order = wc_get_order($orderId);
|
287 |
|
288 |
// If it is already marked as paid, ignore the event
|
289 |
-
if ($order->needs_payment() === false)
|
290 |
-
{
|
291 |
return;
|
292 |
}
|
293 |
|
@@ -299,16 +305,13 @@ class RZP_Webhook
|
|
299 |
|
300 |
$amount = $this->getOrderAmountAsInteger($order);
|
301 |
|
302 |
-
$success
|
303 |
$errorMessage = 'The payment has failed.';
|
304 |
|
305 |
-
if ($payment['status'] === 'captured' and $amountPaid === $amount)
|
306 |
-
{
|
307 |
$success = true;
|
308 |
-
}
|
309 |
-
|
310 |
-
($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE))
|
311 |
-
{
|
312 |
//
|
313 |
// If the payment is only authorized, we capture it
|
314 |
// If the merchant has enabled auto capture
|
@@ -318,16 +321,14 @@ class RZP_Webhook
|
|
318 |
$payment->capture(array('amount' => $amount));
|
319 |
|
320 |
$success = true;
|
321 |
-
}
|
322 |
-
catch (Exception $e)
|
323 |
-
{
|
324 |
//
|
325 |
// Capture will fail if the payment is already captured
|
326 |
//
|
327 |
$log = array(
|
328 |
-
'message'
|
329 |
-
'payment_id'
|
330 |
-
'event'
|
331 |
);
|
332 |
|
333 |
error_log(json_encode($log));
|
@@ -337,8 +338,7 @@ class RZP_Webhook
|
|
337 |
//
|
338 |
$payment = $this->getPaymentEntity($razorpayPaymentId, $data);
|
339 |
|
340 |
-
if ($payment['status'] === 'captured')
|
341 |
-
{
|
342 |
$success = true;
|
343 |
}
|
344 |
}
|
@@ -355,13 +355,11 @@ class RZP_Webhook
|
|
355 |
try
|
356 |
{
|
357 |
$payment = $this->api->payment->fetch($razorpayPaymentId);
|
358 |
-
}
|
359 |
-
catch (Exception $e)
|
360 |
-
{
|
361 |
$log = array(
|
362 |
-
'message'
|
363 |
-
'payment_id'
|
364 |
-
'event'
|
365 |
);
|
366 |
|
367 |
error_log(json_encode($log));
|
@@ -379,8 +377,7 @@ class RZP_Webhook
|
|
379 |
{
|
380 |
if ((isset($data['event']) === true) and
|
381 |
(in_array($data['event'], $this->eventsArray) === true) and
|
382 |
-
isset($data['payload']['payment']['entity']['notes']['woocommerce_order_number']) === true)
|
383 |
-
{
|
384 |
return true;
|
385 |
}
|
386 |
|
@@ -394,8 +391,7 @@ class RZP_Webhook
|
|
394 |
*/
|
395 |
public function getOrderAmountAsInteger($order)
|
396 |
{
|
397 |
-
if (version_compare(WOOCOMMERCE_VERSION, '3.0.0', '>='))
|
398 |
-
{
|
399 |
return (int) round($order->get_total() * 100);
|
400 |
}
|
401 |
|
@@ -411,14 +407,12 @@ class RZP_Webhook
|
|
411 |
public function refundedCreated(array $data)
|
412 |
{
|
413 |
// We don't process subscription/invoice payments here
|
414 |
-
if (isset($data['payload']['payment']['entity']['invoice_id']) === true)
|
415 |
-
{
|
416 |
return;
|
417 |
}
|
418 |
|
419 |
//Avoid to recreate refund, If already refund saved and initiated from woocommerce website.
|
420 |
-
if (isset($data['payload']['refund']['entity']['notes']['refund_from_website']) === true)
|
421 |
-
{
|
422 |
return;
|
423 |
}
|
424 |
|
@@ -436,25 +430,22 @@ class RZP_Webhook
|
|
436 |
$order = wc_get_order($orderId);
|
437 |
|
438 |
// If it is already marked as unpaid, ignore the event
|
439 |
-
if ($order->needs_payment() === true)
|
440 |
-
{
|
441 |
return;
|
442 |
}
|
443 |
|
444 |
// If it's something else such as a WC_Order_Refund, we don't want that.
|
445 |
-
if(
|
446 |
-
{
|
447 |
$log = array(
|
448 |
-
'Error' =>
|
449 |
);
|
450 |
|
451 |
error_log(json_encode($log));
|
452 |
}
|
453 |
|
454 |
-
if(
|
455 |
-
{
|
456 |
$log = array(
|
457 |
-
'Error' =>
|
458 |
);
|
459 |
|
460 |
error_log(json_encode($log));
|
@@ -466,27 +457,25 @@ class RZP_Webhook
|
|
466 |
|
467 |
try
|
468 |
{
|
469 |
-
wc_create_refund(
|
470 |
'amount' => $refundAmount,
|
471 |
'reason' => $refundReason,
|
472 |
'order_id' => $orderId,
|
473 |
'refund_id' => $refundId,
|
474 |
'line_items' => array(),
|
475 |
-
'refund_payment' => false
|
476 |
));
|
477 |
|
478 |
-
$order->add_order_note(
|
479 |
|
480 |
-
}
|
481 |
-
catch (Exception $e)
|
482 |
-
{
|
483 |
//
|
484 |
// Capture will fail if the payment is already captured
|
485 |
//
|
486 |
$log = array(
|
487 |
-
'message'
|
488 |
'payment_id' => $razorpayPaymentId,
|
489 |
-
'event'
|
490 |
);
|
491 |
|
492 |
error_log(json_encode($log));
|
1 |
<?php
|
2 |
|
3 |
+
require_once __DIR__ . '/../woo-razorpay.php';
|
4 |
+
require_once __DIR__ . '/../razorpay-sdk/Razorpay.php';
|
5 |
|
6 |
use Razorpay\Api\Api;
|
7 |
use Razorpay\Api\Errors;
|
23 |
/**
|
24 |
* Event constants
|
25 |
*/
|
26 |
+
const PAYMENT_AUTHORIZED = 'payment.authorized';
|
27 |
+
const PAYMENT_FAILED = 'payment.failed';
|
28 |
+
const SUBSCRIPTION_CANCELLED = 'subscription.cancelled';
|
29 |
+
const REFUNDED_CREATED = 'refund.created';
|
30 |
+
const VIRTUAL_ACCOUNT_CREDITED = 'virtual_account.credited';
|
31 |
+
const SUBSCRIPTION_PAUSED = 'subscription.paused';
|
32 |
+
const SUBSCRIPTION_RESUMED = 'subscription.resumed';
|
33 |
|
34 |
protected $eventsArray = [
|
35 |
self::PAYMENT_AUTHORIZED,
|
38 |
self::PAYMENT_FAILED,
|
39 |
self::SUBSCRIPTION_CANCELLED,
|
40 |
self::SUBSCRIPTION_PAUSED,
|
41 |
+
self::SUBSCRIPTION_RESUMED,
|
42 |
];
|
43 |
|
44 |
public function __construct()
|
70 |
|
71 |
$data = json_decode($post, true);
|
72 |
|
73 |
+
if (json_last_error() !== 0) {
|
|
|
74 |
return;
|
75 |
}
|
76 |
|
77 |
$enabled = $this->razorpay->getSetting('enable_webhook');
|
78 |
|
79 |
if (($enabled === 'yes') and
|
80 |
+
(empty($data['event']) === false)) {
|
|
|
81 |
// Skip the webhook if not the valid data and event
|
82 |
+
if ($this->shouldConsumeWebhook($data) === false) {
|
|
|
83 |
return;
|
84 |
}
|
85 |
|
86 |
+
if (isset($_SERVER['HTTP_X_RAZORPAY_SIGNATURE']) === true) {
|
|
|
87 |
$razorpayWebhookSecret = $this->razorpay->getSetting('webhook_secret');
|
88 |
|
89 |
//
|
90 |
// If the webhook secret isn't set on wordpress, return
|
91 |
//
|
92 |
+
if (empty($razorpayWebhookSecret) === true) {
|
|
|
93 |
return;
|
94 |
}
|
95 |
|
96 |
try
|
97 |
{
|
98 |
$this->api->utility->verifyWebhookSignature($post,
|
99 |
+
$_SERVER['HTTP_X_RAZORPAY_SIGNATURE'],
|
100 |
+
$razorpayWebhookSecret);
|
101 |
+
} catch (Errors\SignatureVerificationError $e) {
|
|
|
|
|
102 |
$log = array(
|
103 |
+
'message' => $e->getMessage(),
|
104 |
+
'data' => $data,
|
105 |
+
'event' => 'razorpay.wc.signature.verify_failed',
|
106 |
);
|
107 |
|
108 |
error_log(json_encode($log));
|
109 |
return;
|
110 |
}
|
111 |
|
112 |
+
$orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
|
113 |
+
|
114 |
+
rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated");
|
115 |
+
|
116 |
+
switch ($data['event']) {
|
117 |
case self::PAYMENT_AUTHORIZED:
|
118 |
return $this->paymentAuthorized($data);
|
119 |
|
186 |
protected function paymentAuthorized(array $data)
|
187 |
{
|
188 |
// We don't process subscription/invoice payments here
|
189 |
+
if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
|
|
|
190 |
return;
|
191 |
}
|
192 |
|
195 |
//
|
196 |
$orderId = $data['payload']['payment']['entity']['notes']['woocommerce_order_number'];
|
197 |
|
198 |
+
rzpLogInfo("Woocommerce orderId: $orderId webhook process intitiated for payment authorized event");
|
199 |
+
|
200 |
$order = wc_get_order($orderId);
|
201 |
|
202 |
+
//To give the priority to callback script to compleate the execution fist adding this locking.
|
203 |
+
$transientData = get_transient('webhook_trigger_count_for_' . $orderId);
|
204 |
+
|
205 |
+
if (empty($transientData) || $transientData == 1) {
|
206 |
+
rzpLogInfo("Woocommerce orderId: $orderId with transientData: $transientData webhook halted for 60 sec");
|
207 |
+
|
208 |
+
sleep(60);
|
209 |
+
}
|
210 |
+
|
211 |
+
$triggerCount = !empty($transientData) ? ($transientData + 1) : 1;
|
212 |
+
|
213 |
+
set_transient('webhook_trigger_count_for_' . $orderId, $triggerCount, 180);
|
214 |
+
|
215 |
// If it is already marked as paid, ignore the event
|
216 |
+
if ($order->needs_payment() === false) {
|
217 |
+
rzpLogInfo("Woocommerce orderId: $orderId webhook process exited");
|
218 |
+
|
219 |
return;
|
220 |
}
|
221 |
|
225 |
|
226 |
$amount = $this->getOrderAmountAsInteger($order);
|
227 |
|
228 |
+
$success = false;
|
229 |
$errorMessage = 'The payment has failed.';
|
230 |
|
231 |
+
if ($payment['status'] === 'captured') {
|
|
|
232 |
$success = true;
|
233 |
+
} else if (($payment['status'] === 'authorized') and
|
234 |
+
($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE)) {
|
|
|
|
|
235 |
//
|
236 |
// If the payment is only authorized, we capture it
|
237 |
// If the merchant has enabled auto capture
|
241 |
$payment->capture(array('amount' => $amount));
|
242 |
|
243 |
$success = true;
|
244 |
+
} catch (Exception $e) {
|
|
|
|
|
245 |
//
|
246 |
// Capture will fail if the payment is already captured
|
247 |
//
|
248 |
$log = array(
|
249 |
+
'message' => $e->getMessage(),
|
250 |
+
'payment_id' => $razorpayPaymentId,
|
251 |
+
'event' => $data['event'],
|
252 |
);
|
253 |
|
254 |
error_log(json_encode($log));
|
258 |
//
|
259 |
$payment = $this->getPaymentEntity($razorpayPaymentId, $data);
|
260 |
|
261 |
+
if ($payment['status'] === 'captured') {
|
|
|
262 |
$success = true;
|
263 |
}
|
264 |
}
|
265 |
}
|
266 |
|
267 |
$this->razorpay->updateOrder($order, $success, $errorMessage, $razorpayPaymentId, null, true);
|
268 |
+
rzpLogInfo("Woocommerce orderId: $orderId webhook process finished the update order function");
|
269 |
+
|
270 |
+
rzpLogInfo("Woocommerce orderId: $orderId webhook process finished the updateOrder function");
|
271 |
|
272 |
// Graceful exit since payment is now processed.
|
273 |
exit;
|
281 |
protected function virtualAccountCredited(array $data)
|
282 |
{
|
283 |
// We don't process subscription/invoice payments here
|
284 |
+
if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
|
|
|
285 |
return;
|
286 |
}
|
287 |
|
293 |
$order = wc_get_order($orderId);
|
294 |
|
295 |
// If it is already marked as paid, ignore the event
|
296 |
+
if ($order->needs_payment() === false) {
|
|
|
297 |
return;
|
298 |
}
|
299 |
|
305 |
|
306 |
$amount = $this->getOrderAmountAsInteger($order);
|
307 |
|
308 |
+
$success = false;
|
309 |
$errorMessage = 'The payment has failed.';
|
310 |
|
311 |
+
if ($payment['status'] === 'captured' and $amountPaid === $amount) {
|
|
|
312 |
$success = true;
|
313 |
+
} else if (($payment['status'] === 'authorized') and $amountPaid === $amount and
|
314 |
+
($this->razorpay->getSetting('payment_action') === WC_Razorpay::CAPTURE)) {
|
|
|
|
|
315 |
//
|
316 |
// If the payment is only authorized, we capture it
|
317 |
// If the merchant has enabled auto capture
|
321 |
$payment->capture(array('amount' => $amount));
|
322 |
|
323 |
$success = true;
|
324 |
+
} catch (Exception $e) {
|
|
|
|
|
325 |
//
|
326 |
// Capture will fail if the payment is already captured
|
327 |
//
|
328 |
$log = array(
|
329 |
+
'message' => $e->getMessage(),
|
330 |
+
'payment_id' => $razorpayPaymentId,
|
331 |
+
'event' => $data['event'],
|
332 |
);
|
333 |
|
334 |
error_log(json_encode($log));
|
338 |
//
|
339 |
$payment = $this->getPaymentEntity($razorpayPaymentId, $data);
|
340 |
|
341 |
+
if ($payment['status'] === 'captured') {
|
|
|
342 |
$success = true;
|
343 |
}
|
344 |
}
|
355 |
try
|
356 |
{
|
357 |
$payment = $this->api->payment->fetch($razorpayPaymentId);
|
358 |
+
} catch (Exception $e) {
|
|
|
|
|
359 |
$log = array(
|
360 |
+
'message' => $e->getMessage(),
|
361 |
+
'payment_id' => $razorpayPaymentId,
|
362 |
+
'event' => $data['event'],
|
363 |
);
|
364 |
|
365 |
error_log(json_encode($log));
|
377 |
{
|
378 |
if ((isset($data['event']) === true) and
|
379 |
(in_array($data['event'], $this->eventsArray) === true) and
|
380 |
+
isset($data['payload']['payment']['entity']['notes']['woocommerce_order_number']) === true) {
|
|
|
381 |
return true;
|
382 |
}
|
383 |
|
391 |
*/
|
392 |
public function getOrderAmountAsInteger($order)
|
393 |
{
|
394 |
+
if (version_compare(WOOCOMMERCE_VERSION, '3.0.0', '>=')) {
|
|
|
395 |
return (int) round($order->get_total() * 100);
|
396 |
}
|
397 |
|
407 |
public function refundedCreated(array $data)
|
408 |
{
|
409 |
// We don't process subscription/invoice payments here
|
410 |
+
if (isset($data['payload']['payment']['entity']['invoice_id']) === true) {
|
|
|
411 |
return;
|
412 |
}
|
413 |
|
414 |
//Avoid to recreate refund, If already refund saved and initiated from woocommerce website.
|
415 |
+
if (isset($data['payload']['refund']['entity']['notes']['refund_from_website']) === true) {
|
|
|
416 |
return;
|
417 |
}
|
418 |
|
430 |
$order = wc_get_order($orderId);
|
431 |
|
432 |
// If it is already marked as unpaid, ignore the event
|
433 |
+
if ($order->needs_payment() === true) {
|
|
|
434 |
return;
|
435 |
}
|
436 |
|
437 |
// If it's something else such as a WC_Order_Refund, we don't want that.
|
438 |
+
if (!is_a($order, 'WC_Order')) {
|
|
|
439 |
$log = array(
|
440 |
+
'Error' => 'Provided ID is not a WC Order',
|
441 |
);
|
442 |
|
443 |
error_log(json_encode($log));
|
444 |
}
|
445 |
|
446 |
+
if ('refunded' == $order->get_status()) {
|
|
|
447 |
$log = array(
|
448 |
+
'Error' => 'Order has been already refunded for Order Id -' . $orderId,
|
449 |
);
|
450 |
|
451 |
error_log(json_encode($log));
|
457 |
|
458 |
try
|
459 |
{
|
460 |
+
wc_create_refund(array(
|
461 |
'amount' => $refundAmount,
|
462 |
'reason' => $refundReason,
|
463 |
'order_id' => $orderId,
|
464 |
'refund_id' => $refundId,
|
465 |
'line_items' => array(),
|
466 |
+
'refund_payment' => false,
|
467 |
));
|
468 |
|
469 |
+
$order->add_order_note(__('Refund Id: ' . $refundId, 'woocommerce'));
|
470 |
|
471 |
+
} catch (Exception $e) {
|
|
|
|
|
472 |
//
|
473 |
// Capture will fail if the payment is already captured
|
474 |
//
|
475 |
$log = array(
|
476 |
+
'message' => $e->getMessage(),
|
477 |
'payment_id' => $razorpayPaymentId,
|
478 |
+
'event' => $data['event'],
|
479 |
);
|
480 |
|
481 |
error_log(json_encode($log));
|
includes/state-map.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Map the state name & state code according to the woocommerce standerds, so that the state name should be properly mapped with state code in billing and shipping address and tax calculation should not break.
|
5 |
+
*/
|
6 |
+
function getWcStateCodeFromName($stateName)
|
7 |
+
{
|
8 |
+
$stateCodeMap = [
|
9 |
+
'ANDAMAN&NICOBARISLANDS' => 'AN',
|
10 |
+
'ANDAMANANDNICOBARISLANDS' => 'AN',
|
11 |
+
'ANDHRAPRADESH' => 'AP',
|
12 |
+
'ARUNACHALPRADESH' => 'AR',
|
13 |
+
'ASSAM' => 'AS',
|
14 |
+
'BIHAR' => 'BR',
|
15 |
+
'CHANDIGARH' => 'CH',
|
16 |
+
'CHATTISGARH' => 'CT',
|
17 |
+
'CHHATTISGARH' => 'CT',
|
18 |
+
'DADRA&NAGARHAVELI' => 'DN',
|
19 |
+
'DADRAANDNAGARHAVELI' => 'DN',
|
20 |
+
'DAMAN&DIU' => 'DD',
|
21 |
+
'DAMANANDDIU' => 'DD',
|
22 |
+
'DELHI' => 'DL',
|
23 |
+
'GOA' => 'GA',
|
24 |
+
'GUJARAT' => 'GJ',
|
25 |
+
'HARYANA' => 'HR',
|
26 |
+
'HIMACHALPRADESH' => 'HP',
|
27 |
+
'JAMMU&KASHMIR' => 'JK',
|
28 |
+
'JAMMUANDKASHMIR' => 'JK',
|
29 |
+
'JAMMUKASHMIR' => 'JK',
|
30 |
+
'JHARKHAND' => 'JH',
|
31 |
+
'KARNATAKA' => 'KA',
|
32 |
+
'KERALA' => 'KL',
|
33 |
+
'LAKSHADWEEP' => 'LD',
|
34 |
+
'LAKSHADEEP' => 'LD',
|
35 |
+
'LADAKH' => 'LA',
|
36 |
+
'MADHYAPRADESH' => 'MP',
|
37 |
+
'MAHARASHTRA' => 'MH',
|
38 |
+
'MANIPUR' => 'MN',
|
39 |
+
'MEGHALAYA' => 'ML',
|
40 |
+
'MIZORAM' => 'MZ',
|
41 |
+
'NAGALAND' => 'NL',
|
42 |
+
'ODISHA' => 'OR',
|
43 |
+
'PONDICHERRY' => 'PY',
|
44 |
+
'PUNJAB' => 'PB',
|
45 |
+
'RAJASTHAN' => 'RJ',
|
46 |
+
'SIKKIM' => 'SK',
|
47 |
+
'TAMILNADU' => 'TN',
|
48 |
+
'TRIPURA' => 'TR',
|
49 |
+
'TELANGANA' => 'TS',
|
50 |
+
'UTTARPRADESH' => 'UP',
|
51 |
+
'UTTARAKHAND' => 'UK',
|
52 |
+
'WESTBENGAL' => 'WB',
|
53 |
+
];
|
54 |
+
|
55 |
+
return $stateCodeMap[$stateName];
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Mapping the state code passed in rest API with the wc state code.
|
60 |
+
*
|
61 |
+
*/
|
62 |
+
function normalizeWcStateCode($stateCode)
|
63 |
+
{
|
64 |
+
|
65 |
+
$shippingStateCodeMap = [
|
66 |
+
'AN' => 'AN',
|
67 |
+
'AP' => 'AP',
|
68 |
+
'AD' => 'AP',
|
69 |
+
'AR' => 'AR',
|
70 |
+
'AS' => 'AS',
|
71 |
+
'BI' => 'BR',
|
72 |
+
'BH' => 'BR',
|
73 |
+
'CH' => 'CH',
|
74 |
+
'CT' => 'CT',
|
75 |
+
'DN' => 'DN',
|
76 |
+
'DD' => 'DD',
|
77 |
+
'DL' => 'DL',
|
78 |
+
'GO' => 'GA',
|
79 |
+
'GJ' => 'GJ',
|
80 |
+
'HA' => 'HR',
|
81 |
+
'HP' => 'HP',
|
82 |
+
'JK' => 'JK',
|
83 |
+
'JH' => 'JH',
|
84 |
+
'KA' => 'KA',
|
85 |
+
'KE' => 'KL',
|
86 |
+
'LD' => 'LD',
|
87 |
+
'LA' => 'LA',
|
88 |
+
'MP' => 'MP',
|
89 |
+
'MH' => 'MH',
|
90 |
+
'MA' => 'MN',
|
91 |
+
'ME' => 'ML',
|
92 |
+
'MI' => 'MZ',
|
93 |
+
'NA' => 'NL',
|
94 |
+
'OR' => 'OR',
|
95 |
+
'PO' => 'PY',
|
96 |
+
'PB' => 'PB',
|
97 |
+
'RJ' => 'RJ',
|
98 |
+
'SK' => 'SK',
|
99 |
+
'TN' => 'TN',
|
100 |
+
'TR' => 'TR',
|
101 |
+
'TG' => 'TS',
|
102 |
+
'UP' => 'UP',
|
103 |
+
'UT' => 'UK',
|
104 |
+
'WB' => 'WB',
|
105 |
+
];
|
106 |
+
|
107 |
+
$wcStateCode = isset($shippingStateCodeMap[$stateCode]) ? $shippingStateCodeMap[$stateCode] : $stateCode;
|
108 |
+
|
109 |
+
return $wcStateCode;
|
110 |
+
}
|
includes/utils.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* controls visibility of 1cc buttons
|
4 |
+
* checks test mode, metrics collection config
|
5 |
+
* NOTE: we add additional check to see if the config field exists as it may cause issues
|
6 |
+
* during plugin updates
|
7 |
+
*/
|
8 |
+
|
9 |
+
/**
|
10 |
+
* payment plugins are loaded even if they are disabled which triggers the 1cc button flow
|
11 |
+
* we need to check if the plugin is disabled
|
12 |
+
*/
|
13 |
+
function isRazorpayPluginEnabled()
|
14 |
+
{
|
15 |
+
return (
|
16 |
+
empty(get_option('woocommerce_razorpay_settings')['enabled']) === false
|
17 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enabled']
|
18 |
+
);
|
19 |
+
}
|
20 |
+
|
21 |
+
function isTestModeEnabled()
|
22 |
+
{
|
23 |
+
return (
|
24 |
+
empty(get_option('woocommerce_razorpay_settings')['enable_1cc_test_mode']) === false
|
25 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_test_mode']
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
function is1ccEnabled()
|
30 |
+
{
|
31 |
+
return (
|
32 |
+
empty(get_option('woocommerce_razorpay_settings')['enable_1cc']) === false
|
33 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc']
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
function isProductSupported()
|
38 |
+
{
|
39 |
+
|
40 |
+
}
|
41 |
+
|
42 |
+
function isCartSupported()
|
43 |
+
{
|
44 |
+
|
45 |
+
}
|
46 |
+
|
47 |
+
function isDebugModeEnabled()
|
48 |
+
{
|
49 |
+
return (
|
50 |
+
empty(get_option('woocommerce_razorpay_settings')['enable_1cc_debug_mode']) === false
|
51 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_debug_mode']
|
52 |
+
);
|
53 |
+
}
|
54 |
+
|
55 |
+
function isPdpCheckoutEnabled()
|
56 |
+
{
|
57 |
+
return (
|
58 |
+
empty(get_option('woocommerce_razorpay_settings')['enable_1cc_pdp_checkout']) === false
|
59 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_pdp_checkout']
|
60 |
+
);
|
61 |
+
}
|
62 |
+
|
63 |
+
function isMiniCartCheckoutEnabled()
|
64 |
+
{
|
65 |
+
return (
|
66 |
+
empty(get_option('woocommerce_razorpay_settings')['enable_1cc_mini_cart_checkout']) === false
|
67 |
+
&& 'yes' == get_option('woocommerce_razorpay_settings')['enable_1cc_mini_cart_checkout']
|
68 |
+
);
|
69 |
+
}
|
70 |
+
|
71 |
+
function validateInput($route, $param)
|
72 |
+
{
|
73 |
+
$failure_reason = null;
|
74 |
+
|
75 |
+
switch ($route) {
|
76 |
+
case 'list':
|
77 |
+
if (empty(sanitize_text_field($param['amount'])) === true) {
|
78 |
+
$failure_reason = 'Field amount is required.';
|
79 |
+
}
|
80 |
+
break;
|
81 |
+
|
82 |
+
case 'apply':
|
83 |
+
if (empty(sanitize_text_field($param['code'])) === true) {
|
84 |
+
$failure_reason = 'Field code is required.';
|
85 |
+
|
86 |
+
} elseif (empty(sanitize_text_field($param['order_id'])) === true) {
|
87 |
+
|
88 |
+
$failure_reason = 'Field order id is required.';
|
89 |
+
|
90 |
+
}
|
91 |
+
break;
|
92 |
+
|
93 |
+
case 'shipping':
|
94 |
+
if (empty(sanitize_text_field($param['order_id'])) === true) {
|
95 |
+
$failure_reason = 'Field order id is required.';
|
96 |
+
|
97 |
+
} elseif (empty($param['addresses']) === true) {
|
98 |
+
|
99 |
+
$failure_reason = 'Field addresses is required.';
|
100 |
+
|
101 |
+
}
|
102 |
+
break;
|
103 |
+
|
104 |
+
default:
|
105 |
+
|
106 |
+
break;
|
107 |
+
}
|
108 |
+
|
109 |
+
return $failure_reason;
|
110 |
+
}
|
public/css/1cc-product-checkout.css
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#btn-1cc {
|
2 |
+
display: block !important;
|
3 |
+
width: 100%;
|
4 |
+
}
|
5 |
+
#btn-1cc-mini-cart {
|
6 |
+
display: block !important;
|
7 |
+
width: 100%;
|
8 |
+
}
|
9 |
+
#btn-1cc-pdp {
|
10 |
+
margin-left: 5px;
|
11 |
+
}
|
12 |
+
#rzp-spinner-backdrop {
|
13 |
+
position: fixed;
|
14 |
+
top: 0;
|
15 |
+
left: 0;
|
16 |
+
z-index: 9999;
|
17 |
+
width: 100%;
|
18 |
+
height: 100%;
|
19 |
+
background: rgba(0, 0, 0);
|
20 |
+
visibility: hidden;
|
21 |
+
opacity: 0;
|
22 |
+
}
|
23 |
+
#rzp-spinner-backdrop.show {
|
24 |
+
visibility: visible;
|
25 |
+
opacity: 0.4;
|
26 |
+
}
|
27 |
+
#rzp-spinner {
|
28 |
+
visibility: hidden;
|
29 |
+
opacity: 0;
|
30 |
+
/* positioning and centering */
|
31 |
+
position: fixed;
|
32 |
+
left: 0;
|
33 |
+
top: 0;
|
34 |
+
bottom: 0;
|
35 |
+
right: 0;
|
36 |
+
margin: auto;
|
37 |
+
z-index: 10000;
|
38 |
+
display: flex !important;
|
39 |
+
align-items: center;
|
40 |
+
justify-content: center;
|
41 |
+
}
|
42 |
+
#rzp-spinner.show {
|
43 |
+
visibility: visible;
|
44 |
+
opacity: 1;
|
45 |
+
}
|
46 |
+
@keyframes rotate {
|
47 |
+
0% {
|
48 |
+
transform: rotate(0);
|
49 |
+
}
|
50 |
+
100% {
|
51 |
+
transform: rotate(360deg);
|
52 |
+
}
|
53 |
+
}
|
54 |
+
#loading-indicator {
|
55 |
+
border-radius: 50%;
|
56 |
+
width: 80px;
|
57 |
+
height: 80px;
|
58 |
+
border: 4px solid;
|
59 |
+
border-color: rgb(59, 124, 245) transparent rgb(59, 124, 245) rgb(59, 124, 245) !important;
|
60 |
+
animation: 1s linear 0s infinite normal none running rotate;
|
61 |
+
margin-top: 2px;
|
62 |
+
box-sizing: content-box;
|
63 |
+
}
|
64 |
+
#icon {
|
65 |
+
position: absolute;
|
66 |
+
}
|
67 |
+
#rzp-logo{
|
68 |
+
width: auto;
|
69 |
+
height: 80px !important;
|
70 |
+
}
|
71 |
+
@media (max-device-height: 768px), (max-device-width: 768px) {
|
72 |
+
#loading-indicator {
|
73 |
+
width: 45px;
|
74 |
+
height: 45px;
|
75 |
+
}
|
76 |
+
#rzp-logo {
|
77 |
+
height: 45px !important;
|
78 |
+
}
|
79 |
+
}
|
public/css/bootstrap.min.css
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
+
* Copyright 2011-2020 The Bootstrap Authors
|
4 |
+
* Copyright 2011-2020 Twitter, Inc.
|
5 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
6 |
+
*/:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}
|
7 |
+
/*# sourceMappingURL=bootstrap.min.css.map */
|
public/css/woo_route.css
ADDED
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.wrap {
|
2 |
+
font-family: Helvetica;
|
3 |
+
}
|
4 |
+
.rzp-container {
|
5 |
+
border: 1px solid #dfe5e7;
|
6 |
+
margin-top: 30px;
|
7 |
+
background-color: #f0f3f4;
|
8 |
+
margin-left: 5px !important;
|
9 |
+
}
|
10 |
+
.rzp-dashicons {
|
11 |
+
margin-top: 3px;
|
12 |
+
}
|
13 |
+
.text {
|
14 |
+
display: inline-block;
|
15 |
+
white-space: nowrap;
|
16 |
+
overflow: hidden;
|
17 |
+
text-overflow: ellipsis;
|
18 |
+
vertical-align: bottom;
|
19 |
+
font-weight: 600;
|
20 |
+
width: 48%;
|
21 |
+
}
|
22 |
+
.panel-heading {
|
23 |
+
line-height: 74px;
|
24 |
+
vertical-align: middle;
|
25 |
+
font-size: 18px;
|
26 |
+
padding: 0 20px;
|
27 |
+
border-bottom: 1px solid #fff;
|
28 |
+
}
|
29 |
+
.Button {
|
30 |
+
background-color: #fff;
|
31 |
+
padding: 5px 11px;
|
32 |
+
line-height: 16px;
|
33 |
+
outline: none;
|
34 |
+
transition: .15s,.3s border;
|
35 |
+
vertical-align: middle;
|
36 |
+
font-size: 13px;
|
37 |
+
color: #528ff0;
|
38 |
+
border: 1px solid #528ff0;
|
39 |
+
border-radius: 3px;
|
40 |
+
}
|
41 |
+
.content-header a:hover{
|
42 |
+
text-decoration: none;
|
43 |
+
}
|
44 |
+
.panel-body {
|
45 |
+
margin: 10px 0;
|
46 |
+
}
|
47 |
+
.panel-body-left .row{
|
48 |
+
padding: 5px;
|
49 |
+
font-size: 14px;
|
50 |
+
}
|
51 |
+
.button-items-detail{
|
52 |
+
margin: 10px 0;
|
53 |
+
background-color: #f9f9f9;
|
54 |
+
padding: 10px;
|
55 |
+
border-radius: 3px;
|
56 |
+
font-size: 14px;
|
57 |
+
}
|
58 |
+
.panel-label{
|
59 |
+
color: #8991ae;
|
60 |
+
}
|
61 |
+
.panel-value{
|
62 |
+
color: #58666e;
|
63 |
+
}
|
64 |
+
|
65 |
+
button:hover {
|
66 |
+
opacity:1;
|
67 |
+
}
|
68 |
+
|
69 |
+
.overlay, .rev_trf_overlay, .trf_settlement_overlay {
|
70 |
+
position: fixed;
|
71 |
+
top: 0;
|
72 |
+
left: 0;
|
73 |
+
width: 100vw;
|
74 |
+
height: 100vh;
|
75 |
+
background-color: rgba(128,128,128,0.5);
|
76 |
+
display: none;
|
77 |
+
}
|
78 |
+
|
79 |
+
.modal {
|
80 |
+
position: relative;
|
81 |
+
display: block;
|
82 |
+
height: 365px;
|
83 |
+
width: 325px;
|
84 |
+
margin: 70px auto;
|
85 |
+
border-radius: 5px;
|
86 |
+
background-color: white;
|
87 |
+
}
|
88 |
+
.modal-content {
|
89 |
+
border: 0;
|
90 |
+
}
|
91 |
+
.modal-header {
|
92 |
+
padding: 24px 22px 0;
|
93 |
+
border-bottom: 0;
|
94 |
+
}
|
95 |
+
.modal-title {
|
96 |
+
font-size: 18px;
|
97 |
+
font-weight: bold;
|
98 |
+
line-height: 1em;
|
99 |
+
margin: 0;
|
100 |
+
}
|
101 |
+
.btn-default {
|
102 |
+
color: #58666e;
|
103 |
+
background-color: #fafafa;
|
104 |
+
border-color: #58666e;
|
105 |
+
font-size: 14px;
|
106 |
+
padding: 6px 12px;
|
107 |
+
font-weight: 400;
|
108 |
+
}
|
109 |
+
.btn-primary {
|
110 |
+
background-color: #528ff0;
|
111 |
+
border-color: #3b80ee;
|
112 |
+
}
|
113 |
+
.rzp-currency {
|
114 |
+
font-weight: normal;
|
115 |
+
color: inherit;
|
116 |
+
opacity: 0.7;
|
117 |
+
white-space: nowrap;
|
118 |
+
font-size: 100%;
|
119 |
+
}
|
120 |
+
p:empty:before {
|
121 |
+
display: none;
|
122 |
+
}
|
123 |
+
|
124 |
+
.route-container header {
|
125 |
+
line-height: 50px;
|
126 |
+
border: 1px solid #e2e8ea;
|
127 |
+
position: relative;
|
128 |
+
background-color: #e2e8ea;
|
129 |
+
padding: 0 12px 0 24px;
|
130 |
+
margin-bottom: 20px;
|
131 |
+
}
|
132 |
+
.route-container header a {
|
133 |
+
color: #555;
|
134 |
+
border-bottom: 3px solid transparent;
|
135 |
+
display: inline-block;
|
136 |
+
margin: 0 16px;
|
137 |
+
font-weight: bold;
|
138 |
+
position: relative;
|
139 |
+
bottom: -1px;
|
140 |
+
}
|
141 |
+
.route-container header a:hover { text-decoration: none; }
|
142 |
+
|
143 |
+
.route-container header > a:first-child {
|
144 |
+
margin-left: 0;
|
145 |
+
}
|
146 |
+
.route-container header a.active {
|
147 |
+
color: #528ff0;
|
148 |
+
border-color: #528ff0;
|
149 |
+
}
|
150 |
+
|
151 |
+
.trf_settlement_label {
|
152 |
+
margin-left: 5px !important;
|
153 |
+
width: 100px !important;
|
154 |
+
}
|
155 |
+
|
156 |
+
.rzp_transfer_custom_field input{
|
157 |
+
margin-right: 5px !important;
|
158 |
+
}
|
159 |
+
.rzp_transfer_custom_field input[type=text], .rzp_transfer_custom_field input[type=number]{
|
160 |
+
width: 220px !important;
|
161 |
+
}
|
162 |
+
.rzp_transfer_custom_field .remove_field{ float: right;}
|
163 |
+
.rzp_transfer_custom_field .add_field_button{ float: right;}
|
164 |
+
|
165 |
+
.pay_search_label{ float: left;position: relative; left: 704px;font-size: 15px;}
|
166 |
+
.input-group { position: relative; display: table; }
|
167 |
+
.input-group .input-group-addon {
|
168 |
+
padding: 6px 12px;
|
169 |
+
font-size: 14px;
|
170 |
+
line-height: 1;
|
171 |
+
color: #555;
|
172 |
+
text-align: center;
|
173 |
+
background-color: #eee;
|
174 |
+
border: 1px solid #cfdadd;
|
175 |
+
border-radius: 2px;
|
176 |
+
width: 1%;
|
177 |
+
vertical-align: middle;
|
178 |
+
display: table-cell;
|
179 |
+
}
|
180 |
+
|
181 |
+
.modal .btn{ width: 100%; }
|
182 |
+
|
183 |
+
#revTransferModal{ height: 270px !important; }
|
184 |
+
#paymentTransferModal{ height: 540px !important; width: 350px !important; }
|
185 |
+
.RadioButton{ margin: 12px auto; }
|
186 |
+
span.trf-status{ margin-right: 10px; }
|
187 |
+
.panel-heading strong{ margin-left: 10px;}
|
188 |
+
.panel-value button{ margin-left: 10px !important;}
|
189 |
+
.btn-default:hover{ background-color: #dee5e7}
|
190 |
+
.rzp_transfer_from_field li{ float: left}
|
191 |
+
.rzp_transfer_from_field li label{ width: 330px;}
|
192 |
+
.rzp_transfer_from_field .woocommerce-help-tip{ right: 146px;}
|
193 |
+
.post-type-shop_order .wp-list-table .check-column { width: 15px !important; }
|
public/images/payment.png
ADDED
Binary file
|
public/images/rzp-spinner.svg
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<svg width="33" height="33" viewBox="0 0 33 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
2 |
+
<circle cx="16.5" cy="16.5" r="16.5" fill="#DFECFB"/>
|
3 |
+
<path d="M10.5788 19.7215L9.30762 24.5381H15.6016C15.6016 24.5381 18.1759 14.7421 18.1766 14.7393C18.1742 14.7408 10.5788 19.7215 10.5788 19.7215Z" fill="#1F2849"/>
|
4 |
+
<path d="M15.5556 13.0953L14.7476 16.1153L19.3712 13.0784L16.3475 24.536L19.418 24.5388L23.8848 7.61572L15.5556 13.0953Z" fill="#3395FF"/>
|
5 |
+
</svg>
|
public/js/admin-rzp-settings.js
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
window.onload = function() {
|
2 |
+
// for confirmation of toggling 1cc
|
3 |
+
var enableRzpCheckout = document.getElementById('woocommerce_razorpay_enable_1cc');
|
4 |
+
if (enableRzpCheckout) {
|
5 |
+
enableRzpCheckout.onclick = function(e) {
|
6 |
+
var current_val = enableRzpCheckout.checked;
|
7 |
+
if (current_val) {
|
8 |
+
var message = 'Do you want to activate Magic Checkout?'
|
9 |
+
} else {
|
10 |
+
var message = 'Are you sure you want to deactivate Magic Checkout?'
|
11 |
+
}
|
12 |
+
if (!confirm(message)) {
|
13 |
+
if (current_val) {
|
14 |
+
enableRzpCheckout.checked = false;
|
15 |
+
} else {
|
16 |
+
enableRzpCheckout.checked = true;
|
17 |
+
}
|
18 |
+
}
|
19 |
+
}
|
20 |
+
}
|
21 |
+
}
|
public/js/bootstrap.min.js
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Bootstrap v4.5.2 (https://getbootstrap.com/)
|
3 |
+
* Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
|
4 |
+
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
5 |
+
*/
|
6 |
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e,n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n;function r(t){var n=this,i=!1;return e(this).one(a.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||a.triggerTransitionEnd(n)}),t),this}var a={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),s=parseFloat(i);return o||s?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],s=e[i],r=s&&a.isElement(s)?"element":null===(l=s)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+r+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};a.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[a.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var l="alert",c=e.fn[l],h=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=a.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=a.getTransitionDurationFromElement(t);e(t).one(a.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),e.fn[l]=h._jQueryInterface,e.fn[l].Constructor=h,e.fn[l].noConflict=function(){return e.fn[l]=c,h._jQueryInterface};var u=e.fn.button,d=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var s=i.querySelector(".active");s&&e(s).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&d._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var s=0,r=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;s<r;s++){var a=t[s];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=d._jQueryInterface,e.fn.button.Constructor=d,e.fn.button.noConflict=function(){return e.fn.button=u,d._jQueryInterface};var f="carousel",g=".bs.carousel",m=e.fn[f],p={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},v={TOUCH:"touch",PEN:"pen"},b=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(a.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(g),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=s({},p,t),a.typeCheckConfig(f,t,_),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),s=this._items.length-1;if((i&&0===o||n&&o===s)&&!this._config.wrap)return e;var r=(o+("prev"===t?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),s=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(s),s},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,s,r=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),d=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",s="left"):(i="carousel-item-right",o="carousel-item-prev",s="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,s).isDefaultPrevented()&&l&&h){this._isSliding=!0,d&&this.pause(),this._setActiveIndicatorElement(h);var f=e.Event("slid.bs.carousel",{relatedTarget:h,direction:s,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),a.reflow(h),e(l).addClass(i),e(h).addClass(i);var g=parseInt(h.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=a.getTransitionDurationFromElement(l);e(l).one(a.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),r._isSliding=!1,setTimeout((function(){return e(r._element).trigger(f)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(f);d&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=s({},p,e(this).data());"object"==typeof n&&(o=s({},o,n));var r="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof r){if("undefined"==typeof i[r])throw new TypeError('No method named "'+r+'"');i[r]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=a.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var r=s({},e(o).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(r.interval=!1),t._jQueryInterface.call(e(o),r),l&&e(o).data("bs.carousel").to(l),n.preventDefault()}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return p}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",b._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);b._jQueryInterface.call(o,o.data())}})),e.fn[f]=b._jQueryInterface,e.fn[f].Constructor=b,e.fn[f].noConflict=function(){return e.fn[f]=m,b._jQueryInterface};var y="collapse",E=e.fn[y],w={toggle:!0,parent:""},T={toggle:"boolean",parent:"(string|element)"},C=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var s=n[i],r=a.getSelectorFromElement(s),l=[].slice.call(document.querySelectorAll(r)).filter((function(e){return e===t}));null!==r&&l.length>0&&(this._selector=r,this._triggerArray.push(s))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var s=e.Event("show.bs.collapse");if(e(this._element).trigger(s),!s.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var r=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[r]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(r[0].toUpperCase()+r.slice(1)),c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[r]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[r]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",a.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var s=0;s<o;s++){var r=this._triggerArray[s],l=a.getSelectorFromElement(r);if(null!==l)e([].slice.call(document.querySelectorAll(l))).hasClass("show")||e(r).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=s({},w,t)).toggle=Boolean(t.toggle),a.typeCheckConfig(y,t,T),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;a.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',s=[].slice.call(n.querySelectorAll(o));return e(s).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=a.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),r=s({},w,i.data(),"object"==typeof n&&n?n:{});if(!o&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),o||(o=new t(this,r),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return w}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=a.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();C._jQueryInterface.call(t,i)}))})),e.fn[y]=C._jQueryInterface,e.fn[y].Constructor=C,e.fn[y].noConflict=function(){return e.fn[y]=E,C._jQueryInterface};var S="dropdown",k=e.fn[S],D=new RegExp("38|40|27"),N={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},A={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},I=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var i=t.prototype;return i.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},i.show=function(i){if(void 0===i&&(i=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var o={relatedTarget:this._element},s=e.Event("show.bs.dropdown",o),r=t._getParentFromElement(this._element);if(e(r).trigger(s),!s.isDefaultPrevented()){if(!this._inNavbar&&i){if("undefined"==typeof n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var l=this._element;"parent"===this._config.reference?l=r:a.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new n(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",o))}}},i.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},i.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},i.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},i._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},i._getConfig=function(t){return t=s({},this.constructor.Default,e(this._element).data(),t),a.typeCheckConfig(S,t,this.constructor.DefaultType),t},i._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},i._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},i._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},i._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},i._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),s({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,s=i.length;o<s;o++){var r=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(r).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(r,n.target))){var h=e.Event("hide.bs.dropdown",l);e(r).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(r).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=a.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!D.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var s=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==s.length){var r=s.indexOf(n.target);38===n.which&&r>0&&r--,40===n.which&&r<s.length-1&&r++,r<0&&(r=0),s[r].focus()}}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return N}},{key:"DefaultType",get:function(){return A}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',I._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",I._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",I._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),I._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[S]=I._jQueryInterface,e.fn[S].Constructor=I,e.fn[S].noConflict=function(){return e.fn[S]=k,I._jQueryInterface};var O=e.fn.modal,j={backdrop:!0,keyboard:!0,focus:!0,show:!0},x={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},P=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var s=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(s)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=s({},j,t),a.typeCheckConfig("modal",t,x),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;var i=this._element.scrollHeight>document.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=a.getTransitionDurationFromElement(this._dialog);e(this._element).off(a.TRANSITION_END),e(this._element).one(a.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(a.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&a.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var s=e.Event("shown.bs.modal",{relatedTarget:t}),r=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(s)};if(i){var l=a.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(a.TRANSITION_END,r).emulateTransitionEnd(l)}else r()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&a.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var s=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var r=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,s=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(s)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,s=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(s)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,s=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(s)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),r=s({},j,e(this).data(),"object"==typeof n&&n?n:{});if(o||(o=new t(this,r),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else r.show&&o.show(i)}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return j}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=a.getSelectorFromElement(this);o&&(n=document.querySelector(o));var r=e(n).data("bs.modal")?"toggle":s({},e(n).data(),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var l=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||l.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));P._jQueryInterface.call(e(n),r,this)})),e.fn.modal=P._jQueryInterface,e.fn.modal.Constructor=P,e.fn.modal.noConflict=function(){return e.fn.modal=O,P._jQueryInterface};var R=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],L={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},q=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,F=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Q(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),s=[].slice.call(i.body.querySelectorAll("*")),r=function(t,n){var i=s[t],r=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[r]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===R.indexOf(n)||Boolean(t.nodeValue.match(q)||t.nodeValue.match(F));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,s=i.length;o<s;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=s.length;a<l;a++)r(a);return i.body.innerHTML}var B="tooltip",H=e.fn[B],U=new RegExp("(^|\\s)bs-tooltip\\S+","g"),M=["sanitize","whiteList","sanitizeFn"],W={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},V={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},z={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:L,popperConfig:null},K={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},X=function(){function t(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var i=t.prototype;return i.enable=function(){this._isEnabled=!0},i.disable=function(){this._isEnabled=!1},i.toggleEnabled=function(){this._isEnabled=!this._isEnabled},i.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},i.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},i.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var i=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(i);var o=a.findShadowRoot(this.element),s=e.contains(null!==o?o:this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),l=a.getUID(this.constructor.NAME);r.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&e(r).addClass("fade");var c="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(c);this.addAttachmentClass(h);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,this._getPopperConfig(h)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var d=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=a.getTransitionDurationFromElement(this.tip);e(this.tip).one(a.TRANSITION_END,d).emulateTransitionEnd(f)}else d()}},i.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),s=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var r=a.getTransitionDurationFromElement(i);e(i).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s();this._hoverState=""}},i.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},i.isWithContent=function(){return Boolean(this.getTitle())},i.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},i.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},i.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},i.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Q(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},i.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},i._getPopperConfig=function(t){var e=this;return s({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},i._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},i._getContainer=function(){return!1===this.config.container?document.body:a.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},i._getAttachment=function(t){return V[t.toUpperCase()]},i._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},i._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},i._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},i._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},i._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},i._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==M.indexOf(t)&&delete n[t]})),"number"==typeof(t=s({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a.typeCheckConfig(B,t,this.constructor.DefaultType),t.sanitize&&(t.template=Q(t.template,t.whiteList,t.sanitizeFn)),t},i._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},i._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(U);null!==n&&n.length&&t.removeClass(n.join(""))},i._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},i._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return z}},{key:"NAME",get:function(){return B}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return K}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return W}}]),t}();e.fn[B]=X._jQueryInterface,e.fn[B].Constructor=X,e.fn[B].noConflict=function(){return e.fn[B]=H,X._jQueryInterface};var Y="popover",$=e.fn[Y],J=new RegExp("(^|\\s)bs-popover\\S+","g"),G=s({},X.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Z=s({},X.DefaultType,{content:"(string|element|function)"}),tt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},et=function(t){var n,i;function s(){return t.apply(this,arguments)||this}i=t,(n=s).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=s.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},r.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(J);null!==n&&n.length>0&&t.removeClass(n.join(""))},s._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new s(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},o(s,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return G}},{key:"NAME",get:function(){return Y}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return tt}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Z}}]),s}(X);e.fn[Y]=et._jQueryInterface,e.fn[Y].Constructor=et,e.fn[Y].noConflict=function(){return e.fn[Y]=$,et._jQueryInterface};var nt="scrollspy",it=e.fn[nt],ot={offset:10,method:"auto",target:""},st={offset:"number",method:"string",target:"(string|element)"},rt=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,s=a.getSelectorFromElement(t);if(s&&(n=document.querySelector(s)),n){var r=n.getBoundingClientRect();if(r.width||r.height)return[e(n)[i]().top+o,s]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=s({},ot,"object"==typeof t&&t?t:{})).target&&a.isElement(t.target)){var n=e(t.target).attr("id");n||(n=a.getUID(nt),e(t.target).attr("id",n)),t.target="#"+n}return a.typeCheckConfig(nt,t,st),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ot}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);rt._jQueryInterface.call(i,i.data())}})),e.fn[nt]=rt._jQueryInterface,e.fn[nt].Constructor=rt,e.fn[nt].noConflict=function(){return e.fn[nt]=it,rt._jQueryInterface};var at=e.fn.tab,lt=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],s=a.getSelectorFromElement(this._element);if(o){var r="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(r)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){s&&(n=document.querySelector(s)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,s=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],r=i&&s&&e(s).hasClass("fade"),l=function(){return o._transitionComplete(t,s,i)};if(s&&r){var c=a.getTransitionDurationFromElement(s);e(s).removeClass("show").one(a.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),a.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var s=e(t).closest(".dropdown")[0];if(s){var r=[].slice.call(s.querySelectorAll(".dropdown-toggle"));e(r).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),lt._jQueryInterface.call(e(this),"show")})),e.fn.tab=lt._jQueryInterface,e.fn.tab.Constructor=lt,e.fn.tab.noConflict=function(){return e.fn.tab=at,lt._jQueryInterface};var ct=e.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},ut={animation:!0,autohide:!0,delay:500},dt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),a.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=s({},ut,e(this._element).data(),"object"==typeof t&&t?t:{}),a.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return ut}}]),t}();e.fn.toast=dt._jQueryInterface,e.fn.toast.Constructor=dt,e.fn.toast.noConflict=function(){return e.fn.toast=ct,dt._jQueryInterface},t.Alert=h,t.Button=d,t.Carousel=b,t.Collapse=C,t.Dropdown=I,t.Modal=P,t.Popover=et,t.Scrollspy=rt,t.Tab=lt,t.Toast=dt,t.Tooltip=X,t.Util=a,Object.defineProperty(t,"__esModule",{value:!0})}));
|
7 |
+
//# sourceMappingURL=bootstrap.min.js.map
|
public/js/woo_route.js
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
var $ = jQuery;
|
2 |
+
|
3 |
+
var max_fields = 5; //maximum input boxes allowed
|
4 |
+
var wrapper = $(".rzp_transfer_custom_field"); //Fields wrapper
|
5 |
+
var add_button = $(".add_field_button"); //Add button ID
|
6 |
+
|
7 |
+
var x = 1;
|
8 |
+
$(add_button).click(function (e) {
|
9 |
+
e.preventDefault();
|
10 |
+
if (x < max_fields) {
|
11 |
+
x++;
|
12 |
+
$(wrapper).append('<p><input type="text" name="LA_number[]" placeholder="Linked Account Number"/><input type="number" name="LA_transfer_amount[]" class="LA_transfer_amount" placeholder="Amount"><label class="trf_settlement_label">Hold Settlement:</label><select name="LA_transfer_status[]"><optgroup label="On Hold"> <option value="1"> Yes</option><option value="0" selected> No</option></optgroup></select> <a href="#" class="remove_field">Remove</a></p>'); //add input box
|
13 |
+
}
|
14 |
+
});
|
15 |
+
|
16 |
+
$(wrapper).on("click", ".remove_field", function (e) { //user click on remove text
|
17 |
+
e.preventDefault();
|
18 |
+
$(this).parent('p').remove();
|
19 |
+
x--;
|
20 |
+
});
|
21 |
+
|
22 |
+
$(document).on('keyup', ".LA_transfer_amount",function () {
|
23 |
+
|
24 |
+
var productPrice = $('#_regular_price').val();
|
25 |
+
var trfAmount = 0;
|
26 |
+
|
27 |
+
$('input[name^=LA_transfer_amount]').each(function () {
|
28 |
+
var price = $(this).val();
|
29 |
+
trfAmount += Number(price);
|
30 |
+
});
|
31 |
+
if (trfAmount > productPrice) {
|
32 |
+
$('#transfer_err_msg').text('The sum of amount requested for transfer is greater than the product price');
|
33 |
+
} else {
|
34 |
+
$('#transfer_err_msg').text('');
|
35 |
+
}
|
36 |
+
});
|
37 |
+
|
38 |
+
$(document).on('keyup', "#trf_reversal_amount", function () {
|
39 |
+
var defaultValue = parseInt($(this).attr('value'));
|
40 |
+
var newValue = parseInt($(this).prop('value'));
|
41 |
+
if (newValue > defaultValue) {
|
42 |
+
$('#trf_reverse_text').text('Amount can\'t be greater than the total Reversible Amount.');
|
43 |
+
$('#reverse_transfer_btn').attr("disabled", true);
|
44 |
+
}else {
|
45 |
+
$('#trf_reverse_text').text('');
|
46 |
+
$("#reverse_transfer_btn").removeAttr("disabled");
|
47 |
+
}
|
48 |
+
});
|
49 |
+
|
50 |
+
$(document).on('keyup', "#payment_trf_amount", function () {
|
51 |
+
var defaultValue = parseInt($(this).attr('value'));
|
52 |
+
var newValue = parseInt($(this).prop('value'));
|
53 |
+
if (newValue > defaultValue) {
|
54 |
+
$('#payment_trf_error').text('Transfer amount can not exceed payment amount.');
|
55 |
+
$('#payment_transfer_btn').attr("disabled", true);
|
56 |
+
}else {
|
57 |
+
$('#payment_trf_error').text('');
|
58 |
+
$("#payment_transfer_btn").removeAttr("disabled");
|
59 |
+
}
|
60 |
+
});
|
61 |
+
|
62 |
+
$(function(){
|
63 |
+
$('input[name="rzp_transfer_from"]').click(function(){
|
64 |
+
var $routeTransferRadio = $(this);
|
65 |
+
|
66 |
+
// if this was previously checked
|
67 |
+
if ($routeTransferRadio.data('waschecked') == true)
|
68 |
+
{
|
69 |
+
$routeTransferRadio.prop('checked', false);
|
70 |
+
$routeTransferRadio.data('waschecked', false);
|
71 |
+
}
|
72 |
+
else
|
73 |
+
$routeTransferRadio.data('waschecked', true);
|
74 |
+
|
75 |
+
// remove was checked from other radios
|
76 |
+
$routeTransferRadio.siblings('input[name="rzp_transfer_from"]').data('waschecked', false);
|
77 |
+
});
|
78 |
+
});
|
79 |
+
|
80 |
+
|
81 |
+
$(".enable_hold_until").click(function() {
|
82 |
+
$("#hold_until").attr("disabled", false);
|
83 |
+
});
|
84 |
+
|
85 |
+
$(".disable_hold_until").click(function() {
|
86 |
+
$("#hold_until").attr("disabled", true);
|
87 |
+
});
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: razorpay
|
|
3 |
Tags: razorpay, payments, india, woocommerce, ecommerce
|
4 |
Requires at least: 3.9.2
|
5 |
Tested up to: 5.9
|
6 |
-
Stable tag:
|
7 |
Requires PHP: 5.6
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
@@ -41,6 +41,9 @@ This is compatible with WooCommerce>=2.4, including the new 3.0 release. It has
|
|
41 |
|
42 |
== Changelog ==
|
43 |
|
|
|
|
|
|
|
44 |
= 2.8.6 =
|
45 |
* Bug fix for not reflecting an updated order success message.
|
46 |
* Tested upto Wordpress 5.9
|
3 |
Tags: razorpay, payments, india, woocommerce, ecommerce
|
4 |
Requires at least: 3.9.2
|
5 |
Tested up to: 5.9
|
6 |
+
Stable tag: 3.0.0
|
7 |
Requires PHP: 5.6
|
8 |
License: GPLv2 or later
|
9 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
41 |
|
42 |
== Changelog ==
|
43 |
|
44 |
+
= 3.0.0 =
|
45 |
+
* Added Magic Checkout feature.
|
46 |
+
|
47 |
= 2.8.6 =
|
48 |
* Bug fix for not reflecting an updated order success message.
|
49 |
* Tested upto Wordpress 5.9
|
templates/rzp-cart-checkout-btn.php
ADDED
@@ -0,0 +1,23 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<style type="text/css">
|
2 |
+
.checkout-button {
|
3 |
+
display: none !important;
|
4 |
+
}
|
5 |
+
</style>
|
6 |
+
<div>
|
7 |
+
<button
|
8 |
+
id="btn-1cc"
|
9 |
+
class="rzp-checkout-button button alt wc-forward"
|
10 |
+
type="button"
|
11 |
+
>PROCEED TO CHECKOUT
|
12 |
+
</button>
|
13 |
+
</div>
|
14 |
+
|
15 |
+
<div id="rzp-spinner-backdrop"></div>
|
16 |
+
<div id="rzp-spinner">
|
17 |
+
<div id="loading-indicator"></div>
|
18 |
+
<div id="icon">
|
19 |
+
<img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
|
20 |
+
</div>
|
21 |
+
</div>
|
22 |
+
<div id="error-message">
|
23 |
+
</div>
|
templates/rzp-mini-checkout-btn.php
ADDED
@@ -0,0 +1,17 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div>
|
2 |
+
<button
|
3 |
+
id="btn-1cc-mini-cart"
|
4 |
+
class="button checkout wc-forward"
|
5 |
+
type="button"
|
6 |
+
>CHECKOUT
|
7 |
+
</button>
|
8 |
+
</div>
|
9 |
+
<div id="rzp-spinner-backdrop"></div>
|
10 |
+
<div id="rzp-spinner">
|
11 |
+
<div id="loading-indicator"></div>
|
12 |
+
<div id="icon">
|
13 |
+
<img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
|
14 |
+
</div>
|
15 |
+
</div>
|
16 |
+
<div id="error-message">
|
17 |
+
</div>
|
templates/rzp-pdp-checkout-btn.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
global $product;
|
3 |
+
$productData = wp_json_encode(['id' => $product->get_id(), 'quantity' => 1]);
|
4 |
+
?>
|
5 |
+
<button
|
6 |
+
id="btn-1cc-pdp"
|
7 |
+
class="button alt single_add_to_cart_button"
|
8 |
+
type="button"
|
9 |
+
product_id="<?php echo esc_attr($product->get_id()); ?>"
|
10 |
+
pdp_checkout="<?php echo true; ?>"
|
11 |
+
>BUY NOW
|
12 |
+
</button>
|
13 |
+
|
14 |
+
<div id="rzp-spinner-backdrop"></div>
|
15 |
+
<div id="rzp-spinner">
|
16 |
+
<div id="loading-indicator"></div>
|
17 |
+
<div id="icon">
|
18 |
+
<img src="<?php echo plugin_dir_url(dirname(__FILE__)) . 'public/images/rzp-spinner.svg'; ?>" alt="Loading" id="rzp-logo" />
|
19 |
+
</div>
|
20 |
+
</div>
|
21 |
+
<div id="error-message">
|
22 |
+
</div>
|
23 |
+
|
24 |
+
<script type="">
|
25 |
+
var quantity = document.getElementsByClassName("qty")[0].value;
|
26 |
+
|
27 |
+
var btnPdp = document.getElementById('btn-1cc-pdp');
|
28 |
+
|
29 |
+
btnPdp.setAttribute('quantity', quantity);
|
30 |
+
|
31 |
+
jQuery('.qty').on('change',function(e)
|
32 |
+
{
|
33 |
+
var quantity = document.getElementsByClassName("qty")[0].value;
|
34 |
+
btnPdp.setAttribute('quantity', quantity);
|
35 |
+
|
36 |
+
if(quantity <= 0)
|
37 |
+
{
|
38 |
+
btnPdp.classList.add("disabled");
|
39 |
+
btnPdp.disabled = true;
|
40 |
+
}
|
41 |
+
else
|
42 |
+
{
|
43 |
+
btnPdp.classList.remove("disabled");
|
44 |
+
btnPdp.disabled = false;
|
45 |
+
}
|
46 |
+
});
|
47 |
+
|
48 |
+
(function($){
|
49 |
+
|
50 |
+
$('form.variations_form').on('show_variation', function(event, data){
|
51 |
+
|
52 |
+
btnPdp.classList.remove("disabled");
|
53 |
+
btnPdp.disabled = false;
|
54 |
+
|
55 |
+
btnPdp.setAttribute('variation_id', data.variation_id);
|
56 |
+
|
57 |
+
var variationArr = {};
|
58 |
+
|
59 |
+
$.each( data.attributes, function( key, value ) {
|
60 |
+
variationArr[key] = $("[name="+key+"]").val();
|
61 |
+
});
|
62 |
+
|
63 |
+
btnPdp.setAttribute('variations', JSON.stringify(variationArr));
|
64 |
+
|
65 |
+
}).on('hide_variation', function() {
|
66 |
+
|
67 |
+
btnPdp.classList.add("disabled");
|
68 |
+
btnPdp.disabled = true;
|
69 |
+
});
|
70 |
+
})(jQuery);
|
71 |
+
</script>
|
woo-razorpay.php
CHANGED
@@ -3,8 +3,8 @@
|
|
3 |
* Plugin Name: Razorpay for WooCommerce
|
4 |
* Plugin URI: https://razorpay.com
|
5 |
* Description: Razorpay Payment Gateway Integration for WooCommerce
|
6 |
-
* Version:
|
7 |
-
* Stable tag:
|
8 |
* Author: Team Razorpay
|
9 |
* WC tested up to: 6.2.0
|
10 |
* Author URI: https://razorpay.com
|
@@ -20,6 +20,9 @@ require_once __DIR__.'/razorpay-sdk/Razorpay.php';
|
|
20 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
21 |
require_once __DIR__.'/includes/razorpay-route.php';
|
22 |
require_once __DIR__ .'/includes/razorpay-route-actions.php';
|
|
|
|
|
|
|
23 |
|
24 |
use Razorpay\Api\Api;
|
25 |
use Razorpay\Api\Errors;
|
@@ -40,6 +43,7 @@ function woocommerce_razorpay_init()
|
|
40 |
const SESSION_KEY = 'razorpay_wc_order_id';
|
41 |
const RAZORPAY_PAYMENT_ID = 'razorpay_payment_id';
|
42 |
const RAZORPAY_ORDER_ID = 'razorpay_order_id';
|
|
|
43 |
const RAZORPAY_SIGNATURE = 'razorpay_signature';
|
44 |
const RAZORPAY_WC_FORM_SUBMIT = 'razorpay_wc_form_submit';
|
45 |
|
@@ -142,6 +146,38 @@ function woocommerce_razorpay_init()
|
|
142 |
public function __construct($hooks = true)
|
143 |
{
|
144 |
$this->icon = "https://cdn.razorpay.com/static/assets/logo/payment.svg";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
|
146 |
$this->init_form_fields();
|
147 |
$this->init_settings();
|
@@ -170,11 +206,13 @@ function woocommerce_razorpay_init()
|
|
170 |
{
|
171 |
add_action("woocommerce_update_options_payment_gateways_{$this->id}", $cb);
|
172 |
add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'autoEnableWebhook'));
|
|
|
173 |
}
|
174 |
else
|
175 |
{
|
176 |
add_action('woocommerce_update_options_payment_gateways', $cb);
|
177 |
add_action( "woocommerce_update_options_payment_gateways", array($this, 'autoEnableWebhook'));
|
|
|
178 |
}
|
179 |
|
180 |
add_filter( 'woocommerce_thankyou_order_received_text', array($this, 'getCustomOrdercreationMessage'), 20, 2 );
|
@@ -257,7 +295,6 @@ function woocommerce_razorpay_init()
|
|
257 |
'description' => __('Webhook secret is used for webhook signature verification. This has to match the one added <a href="https://dashboard.razorpay.com/#/app/webhooks">here</a>', $this->id),
|
258 |
'default' => ''
|
259 |
),
|
260 |
-
|
261 |
);
|
262 |
|
263 |
do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
|
@@ -393,6 +430,30 @@ function woocommerce_razorpay_init()
|
|
393 |
|
394 |
}
|
395 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
396 |
protected function webhookAPI($method, $url, $data = array())
|
397 |
{
|
398 |
$webhook = [];
|
@@ -446,6 +507,12 @@ function woocommerce_razorpay_init()
|
|
446 |
*/
|
447 |
protected function getOrderSessionKey($orderId)
|
448 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
449 |
return self::RAZORPAY_ORDER_ID . $orderId;
|
450 |
}
|
451 |
|
@@ -458,18 +525,26 @@ function woocommerce_razorpay_init()
|
|
458 |
* @param string $orderId Order Id
|
459 |
* @return mixed Razorpay Order Id or Exception
|
460 |
*/
|
461 |
-
|
462 |
{
|
463 |
global $woocommerce;
|
464 |
-
|
465 |
-
$sessionKey = $this->getOrderSessionKey($orderId);
|
466 |
|
467 |
$create = false;
|
468 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
469 |
try
|
470 |
{
|
471 |
$razorpayOrderId = get_transient($sessionKey);
|
472 |
-
|
|
|
|
|
473 |
// If we don't have an Order
|
474 |
// or the if the order is present in transient but doesn't match what we have saved
|
475 |
if (($razorpayOrderId === false) or
|
@@ -521,7 +596,8 @@ function woocommerce_razorpay_init()
|
|
521 |
'wc-api' => $this->id,
|
522 |
'order_key' => $order->get_order_key(),
|
523 |
];
|
524 |
-
|
|
|
525 |
}
|
526 |
|
527 |
/**
|
@@ -532,6 +608,7 @@ function woocommerce_razorpay_init()
|
|
532 |
*/
|
533 |
protected function getRazorpayPaymentParams($orderId)
|
534 |
{
|
|
|
535 |
$razorpayOrderId = $this->createOrGetRazorpayOrderId($orderId);
|
536 |
|
537 |
if ($razorpayOrderId === null)
|
@@ -581,7 +658,7 @@ function woocommerce_razorpay_init()
|
|
581 |
* @param WC_Order $order WC Order
|
582 |
* @return array checkout params
|
583 |
*/
|
584 |
-
|
585 |
{
|
586 |
global $woocommerce;
|
587 |
|
@@ -591,7 +668,8 @@ function woocommerce_razorpay_init()
|
|
591 |
|
592 |
$callbackUrl = $this->getRedirectUrl($wcOrderId);
|
593 |
|
594 |
-
$sessionKey = $this->getOrderSessionKey($
|
|
|
595 |
$razorpayOrderId = get_transient($sessionKey);
|
596 |
|
597 |
$productinfo = "Order $orderId";
|
@@ -665,13 +743,15 @@ function woocommerce_razorpay_init()
|
|
665 |
|
666 |
protected function createRazorpayOrderId($orderId, $sessionKey)
|
667 |
{
|
|
|
668 |
// Calls the helper function to create order data
|
669 |
global $woocommerce;
|
670 |
|
671 |
$api = $this->getRazorpayApiInstance();
|
672 |
|
673 |
$data = $this->getOrderCreationData($orderId);
|
674 |
-
|
|
|
675 |
try
|
676 |
{
|
677 |
$razorpayOrder = $api->order->create($data);
|
@@ -684,9 +764,9 @@ function woocommerce_razorpay_init()
|
|
684 |
$razorpayOrderId = $razorpayOrder['id'];
|
685 |
|
686 |
set_transient($sessionKey, $razorpayOrderId, 3600);
|
687 |
-
|
688 |
$woocommerce->session->set($sessionKey, $razorpayOrderId);
|
689 |
|
|
|
690 |
//update it in order comments
|
691 |
$order = wc_get_order($orderId);
|
692 |
|
@@ -697,6 +777,7 @@ function woocommerce_razorpay_init()
|
|
697 |
|
698 |
protected function verifyOrderAmount($razorpayOrderId, $orderId)
|
699 |
{
|
|
|
700 |
$order = wc_get_order($orderId);
|
701 |
|
702 |
$api = $this->getRazorpayApiInstance();
|
@@ -708,6 +789,7 @@ function woocommerce_razorpay_init()
|
|
708 |
catch (Exception $e)
|
709 |
{
|
710 |
$message = $e->getMessage();
|
|
|
711 |
return "RAZORPAY ERROR: Order fetch failed with the message '$message'";
|
712 |
}
|
713 |
|
@@ -735,8 +817,11 @@ function woocommerce_razorpay_init()
|
|
735 |
|
736 |
private function getOrderCreationData($orderId)
|
737 |
{
|
|
|
738 |
$order = wc_get_order($orderId);
|
739 |
|
|
|
|
|
740 |
$data = array(
|
741 |
'receipt' => $orderId,
|
742 |
'amount' => (int) round($order->get_total() * 100),
|
@@ -748,7 +833,7 @@ function woocommerce_razorpay_init()
|
|
748 |
),
|
749 |
);
|
750 |
|
751 |
-
if($this->getSetting('route_enable') == 'yes')
|
752 |
{
|
753 |
$razorpayRoute = new RZP_Route_Action();
|
754 |
$orderTransferArr = $razorpayRoute->getOrderTransferData($orderId);
|
@@ -762,10 +847,23 @@ function woocommerce_razorpay_init()
|
|
762 |
}
|
763 |
}
|
764 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
765 |
return $data;
|
766 |
}
|
767 |
|
768 |
-
|
769 |
{
|
770 |
if($data === 'checkoutForm' || $data === 'routeAnalyticsForm')
|
771 |
{
|
@@ -930,10 +1028,15 @@ EOT;
|
|
930 |
**/
|
931 |
function process_payment($order_id)
|
932 |
{
|
|
|
|
|
933 |
global $woocommerce;
|
934 |
|
935 |
$order = wc_get_order($order_id);
|
936 |
|
|
|
|
|
|
|
937 |
$orderKey = $this->getOrderKey($order);
|
938 |
|
939 |
if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
|
@@ -968,37 +1071,55 @@ EOT;
|
|
968 |
|
969 |
/**
|
970 |
* Check for valid razorpay server callback
|
971 |
-
|
|
|
972 |
function check_razorpay_response()
|
973 |
{
|
974 |
global $woocommerce;
|
975 |
global $wpdb;
|
976 |
|
977 |
$order = false;
|
|
|
978 |
|
979 |
$post_type = 'shop_order';
|
|
|
980 |
$post_password = sanitize_text_field($_GET['order_key']);
|
981 |
|
982 |
$postIds = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts AS P WHERE post_type=%s AND post_password = %s", $post_type, $post_password ) );
|
983 |
|
984 |
-
if(count($postIds) > 0)
|
985 |
{
|
986 |
$orderId = $postIds[0];
|
987 |
$order = wc_get_order($orderId);
|
|
|
988 |
}
|
989 |
|
990 |
-
|
|
|
991 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
992 |
wp_redirect(wc_get_checkout_url());
|
993 |
exit;
|
994 |
}
|
995 |
|
996 |
-
//
|
997 |
// If the order has already been paid for
|
998 |
// redirect user to success page
|
999 |
-
//
|
1000 |
if ($order->needs_payment() === false)
|
1001 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1002 |
$this->redirectUser($order);
|
1003 |
}
|
1004 |
|
@@ -1014,6 +1135,15 @@ EOT;
|
|
1014 |
$this->verifySignature($orderId);
|
1015 |
$success = true;
|
1016 |
$razorpayPaymentId = sanitize_text_field($_POST[self::RAZORPAY_PAYMENT_ID]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1017 |
}
|
1018 |
catch (Errors\SignatureVerificationError $e)
|
1019 |
{
|
@@ -1022,7 +1152,7 @@ EOT;
|
|
1022 |
}
|
1023 |
else
|
1024 |
{
|
1025 |
-
if($_POST[self::RAZORPAY_WC_FORM_SUBMIT] ==1)
|
1026 |
{
|
1027 |
$success = false;
|
1028 |
$error = 'Customer cancelled the payment';
|
@@ -1033,9 +1163,27 @@ EOT;
|
|
1033 |
$error = "Payment Failed.";
|
1034 |
}
|
1035 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1036 |
$this->handleErrorCase($order);
|
1037 |
$this->updateOrder($order, $success, $error, $razorpayPaymentId, null);
|
1038 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1039 |
wp_redirect(wc_get_checkout_url());
|
1040 |
exit;
|
1041 |
}
|
@@ -1055,6 +1203,8 @@ EOT;
|
|
1055 |
|
1056 |
protected function verifySignature($orderId)
|
1057 |
{
|
|
|
|
|
1058 |
global $woocommerce;
|
1059 |
|
1060 |
$api = $this->getRazorpayApiInstance();
|
@@ -1065,7 +1215,6 @@ EOT;
|
|
1065 |
);
|
1066 |
|
1067 |
$sessionKey = $this->getOrderSessionKey($orderId);
|
1068 |
-
|
1069 |
//Check the transient data for razorpay order id, if it's not available then look into session data.
|
1070 |
if(get_transient($sessionKey))
|
1071 |
{
|
@@ -1077,7 +1226,8 @@ EOT;
|
|
1077 |
}
|
1078 |
|
1079 |
$attributes[self::RAZORPAY_ORDER_ID] = $razorpayOrderId?? '';
|
1080 |
-
|
|
|
1081 |
$api->utility->verifyPaymentSignature($attributes);
|
1082 |
}
|
1083 |
|
@@ -1089,6 +1239,8 @@ EOT;
|
|
1089 |
protected function getErrorMessage($orderId)
|
1090 |
{
|
1091 |
// We don't have a proper order id
|
|
|
|
|
1092 |
if ($orderId !== null)
|
1093 |
{
|
1094 |
$message = 'An error occured while processing this payment';
|
@@ -1112,7 +1264,7 @@ EOT;
|
|
1112 |
{
|
1113 |
$message = 'An error occured. Please contact administrator for assistance';
|
1114 |
}
|
1115 |
-
|
1116 |
return $message;
|
1117 |
}
|
1118 |
|
@@ -1127,9 +1279,42 @@ EOT;
|
|
1127 |
|
1128 |
$orderId = $order->get_order_number();
|
1129 |
|
|
|
|
|
1130 |
if (($success === true) and ($order->needs_payment() === true))
|
1131 |
{
|
1132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1133 |
$order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
|
1134 |
|
1135 |
if($this->getSetting('route_enable') == 'yes')
|
@@ -1168,13 +1353,276 @@ EOT;
|
|
1168 |
if ($webhook === false)
|
1169 |
{
|
1170 |
$this->add_notice($this->msg['message'], $this->msg['class']);
|
|
|
|
|
|
|
|
|
|
|
|
|
1171 |
}
|
1172 |
}
|
1173 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1174 |
protected function handleErrorCase(& $order)
|
1175 |
{
|
1176 |
$orderId = $order->get_order_number();
|
1177 |
-
|
1178 |
$this->msg['class'] = 'error';
|
1179 |
$this->msg['message'] = $this->getErrorMessage($orderId);
|
1180 |
}
|
@@ -1236,6 +1684,34 @@ EOT;
|
|
1236 |
|
1237 |
}
|
1238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1239 |
/**
|
1240 |
* Add the Gateway to WooCommerce
|
1241 |
**/
|
@@ -1245,7 +1721,7 @@ EOT;
|
|
1245 |
return $methods;
|
1246 |
}
|
1247 |
|
1248 |
-
add_filter('woocommerce_payment_gateways', 'woocommerce_add_razorpay_gateway'
|
1249 |
|
1250 |
/**
|
1251 |
* Creating the settings link from the plugins page
|
@@ -1273,3 +1749,151 @@ function razorpay_webhook_init()
|
|
1273 |
|
1274 |
$rzpWebhook->process();
|
1275 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
* Plugin Name: Razorpay for WooCommerce
|
4 |
* Plugin URI: https://razorpay.com
|
5 |
* Description: Razorpay Payment Gateway Integration for WooCommerce
|
6 |
+
* Version: 3.0.0
|
7 |
+
* Stable tag: 3.0.0
|
8 |
* Author: Team Razorpay
|
9 |
* WC tested up to: 6.2.0
|
10 |
* Author URI: https://razorpay.com
|
20 |
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
21 |
require_once __DIR__.'/includes/razorpay-route.php';
|
22 |
require_once __DIR__ .'/includes/razorpay-route-actions.php';
|
23 |
+
require_once __DIR__.'/includes/api/api.php';
|
24 |
+
require_once __DIR__.'/includes/utils.php';
|
25 |
+
require_once __DIR__.'/includes/state-map.php';
|
26 |
|
27 |
use Razorpay\Api\Api;
|
28 |
use Razorpay\Api\Errors;
|
43 |
const SESSION_KEY = 'razorpay_wc_order_id';
|
44 |
const RAZORPAY_PAYMENT_ID = 'razorpay_payment_id';
|
45 |
const RAZORPAY_ORDER_ID = 'razorpay_order_id';
|
46 |
+
const RAZORPAY_ORDER_ID_1CC = 'razorpay_order_id_1cc';
|
47 |
const RAZORPAY_SIGNATURE = 'razorpay_signature';
|
48 |
const RAZORPAY_WC_FORM_SUBMIT = 'razorpay_wc_form_submit';
|
49 |
|
146 |
public function __construct($hooks = true)
|
147 |
{
|
148 |
$this->icon = "https://cdn.razorpay.com/static/assets/logo/payment.svg";
|
149 |
+
// 1cc flags should be enabled only if merchant has access to 1cc feature
|
150 |
+
$is1ccAvailable = false;
|
151 |
+
|
152 |
+
try {
|
153 |
+
$api = new Api($this->getSetting('key_id'), '');
|
154 |
+
$merchantPreferences = $api->request->request('GET', 'preferences');
|
155 |
+
|
156 |
+
if (!empty($merchantPreferences['features']['one_click_checkout'])) {
|
157 |
+
$is1ccAvailable = true;
|
158 |
+
}
|
159 |
+
|
160 |
+
} catch (\Exception $e) {
|
161 |
+
rzpLogError($e->getMessage());
|
162 |
+
}
|
163 |
+
|
164 |
+
|
165 |
+
if ($is1ccAvailable) {
|
166 |
+
$this->visibleSettings = array_merge($this->visibleSettings, array(
|
167 |
+
'enable_1cc',
|
168 |
+
'enable_1cc_mandatory_login',
|
169 |
+
'enable_1cc_cod_intelligence',
|
170 |
+
'enable_1cc_test_mode',
|
171 |
+
'enable_1cc_debug_mode',
|
172 |
+
'enable_1cc_pdp_checkout',
|
173 |
+
'enable_1cc_mini_cart_checkout',
|
174 |
+
'enable_1cc_ga_analytics',
|
175 |
+
'enable_1cc_fb_analytics',
|
176 |
+
'1cc_min_cart_amount',
|
177 |
+
'1cc_min_COD_slab_amount',
|
178 |
+
'1cc_max_COD_slab_amount',
|
179 |
+
));
|
180 |
+
}
|
181 |
|
182 |
$this->init_form_fields();
|
183 |
$this->init_settings();
|
206 |
{
|
207 |
add_action("woocommerce_update_options_payment_gateways_{$this->id}", $cb);
|
208 |
add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'autoEnableWebhook'));
|
209 |
+
add_action( "woocommerce_update_options_payment_gateways_{$this->id}", array($this, 'addAdminCheckoutSettingsAlert'));
|
210 |
}
|
211 |
else
|
212 |
{
|
213 |
add_action('woocommerce_update_options_payment_gateways', $cb);
|
214 |
add_action( "woocommerce_update_options_payment_gateways", array($this, 'autoEnableWebhook'));
|
215 |
+
add_action( "woocommerce_update_options_payment_gateways", array($this, 'addAdminCheckoutSettingsAlert'));
|
216 |
}
|
217 |
|
218 |
add_filter( 'woocommerce_thankyou_order_received_text', array($this, 'getCustomOrdercreationMessage'), 20, 2 );
|
295 |
'description' => __('Webhook secret is used for webhook signature verification. This has to match the one added <a href="https://dashboard.razorpay.com/#/app/webhooks">here</a>', $this->id),
|
296 |
'default' => ''
|
297 |
),
|
|
|
298 |
);
|
299 |
|
300 |
do_action_ref_array( 'setup_extra_setting_fields', array( &$defaultFormFields ) );
|
430 |
|
431 |
}
|
432 |
|
433 |
+
// showing notice : status of 1cc active / inactive message in admin dashboard
|
434 |
+
function addAdminCheckoutSettingsAlert() {
|
435 |
+
$enable_1cc = $this->getSetting('enable_1cc');
|
436 |
+
if($enable_1cc == 'no')
|
437 |
+
{
|
438 |
+
?>
|
439 |
+
<div class="notice error is-dismissible" >
|
440 |
+
<p><b><?php _e( 'We are sorry to see you opt out of Magic Checkout experience. Please help us understand what went wrong by filling up this form.'); ?></b></p>
|
441 |
+
</div>
|
442 |
+
<?php
|
443 |
+
error_log('1cc is disabled.');
|
444 |
+
return;
|
445 |
+
}
|
446 |
+
elseif ($enable_1cc == 'yes')
|
447 |
+
{
|
448 |
+
?>
|
449 |
+
<div class="notice notice-success is-dismissible" >
|
450 |
+
<p><b><?php _e( 'You are Live with Magic Checkout.'); ?></b></p>
|
451 |
+
</div>
|
452 |
+
<?php
|
453 |
+
return;
|
454 |
+
}
|
455 |
+
}
|
456 |
+
|
457 |
protected function webhookAPI($method, $url, $data = array())
|
458 |
{
|
459 |
$webhook = [];
|
507 |
*/
|
508 |
protected function getOrderSessionKey($orderId)
|
509 |
{
|
510 |
+
$is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
|
511 |
+
|
512 |
+
if($is1ccOrder == 'yes')
|
513 |
+
{
|
514 |
+
return self::RAZORPAY_ORDER_ID_1CC . $orderId;
|
515 |
+
}
|
516 |
return self::RAZORPAY_ORDER_ID . $orderId;
|
517 |
}
|
518 |
|
525 |
* @param string $orderId Order Id
|
526 |
* @return mixed Razorpay Order Id or Exception
|
527 |
*/
|
528 |
+
public function createOrGetRazorpayOrderId($orderId, $is1ccCheckout = 'no')
|
529 |
{
|
530 |
global $woocommerce;
|
531 |
+
rzpLogInfo("createOrGetRazorpayOrderId $orderId");
|
|
|
532 |
|
533 |
$create = false;
|
534 |
|
535 |
+
if($is1ccCheckout == 'no')
|
536 |
+
{
|
537 |
+
update_post_meta( $orderId, 'is_magic_checkout_order', 'no' );
|
538 |
+
}
|
539 |
+
|
540 |
+
$sessionKey = $this->getOrderSessionKey($orderId);
|
541 |
+
|
542 |
try
|
543 |
{
|
544 |
$razorpayOrderId = get_transient($sessionKey);
|
545 |
+
rzpLogInfo("razorpayOrderId $razorpayOrderId | sessionKey $sessionKey");
|
546 |
+
rzpLogInfo("verifying amt");
|
547 |
+
rzpLogInfo($this->verifyOrderAmount($razorpayOrderId, $orderId));
|
548 |
// If we don't have an Order
|
549 |
// or the if the order is present in transient but doesn't match what we have saved
|
550 |
if (($razorpayOrderId === false) or
|
596 |
'wc-api' => $this->id,
|
597 |
'order_key' => $order->get_order_key(),
|
598 |
];
|
599 |
+
|
600 |
+
return add_query_arg($query, trailingslashit(get_home_url()));
|
601 |
}
|
602 |
|
603 |
/**
|
608 |
*/
|
609 |
protected function getRazorpayPaymentParams($orderId)
|
610 |
{
|
611 |
+
rzpLogInfo("getRazorpayPaymentParams $orderId");
|
612 |
$razorpayOrderId = $this->createOrGetRazorpayOrderId($orderId);
|
613 |
|
614 |
if ($razorpayOrderId === null)
|
658 |
* @param WC_Order $order WC Order
|
659 |
* @return array checkout params
|
660 |
*/
|
661 |
+
public function getDefaultCheckoutArguments($order)
|
662 |
{
|
663 |
global $woocommerce;
|
664 |
|
668 |
|
669 |
$callbackUrl = $this->getRedirectUrl($wcOrderId);
|
670 |
|
671 |
+
$sessionKey = $this->getOrderSessionKey($wcOrderId);
|
672 |
+
|
673 |
$razorpayOrderId = get_transient($sessionKey);
|
674 |
|
675 |
$productinfo = "Order $orderId";
|
743 |
|
744 |
protected function createRazorpayOrderId($orderId, $sessionKey)
|
745 |
{
|
746 |
+
rzpLogInfo("Called createRazorpayOrderId with params orderId $orderId and sessionKey $sessionKey");
|
747 |
// Calls the helper function to create order data
|
748 |
global $woocommerce;
|
749 |
|
750 |
$api = $this->getRazorpayApiInstance();
|
751 |
|
752 |
$data = $this->getOrderCreationData($orderId);
|
753 |
+
rzpLogInfo('For order ' . $orderId);
|
754 |
+
rzpLogInfo(json_encode($data));
|
755 |
try
|
756 |
{
|
757 |
$razorpayOrder = $api->order->create($data);
|
764 |
$razorpayOrderId = $razorpayOrder['id'];
|
765 |
|
766 |
set_transient($sessionKey, $razorpayOrderId, 3600);
|
|
|
767 |
$woocommerce->session->set($sessionKey, $razorpayOrderId);
|
768 |
|
769 |
+
rzpLogInfo('For order session key ' . $sessionKey);
|
770 |
//update it in order comments
|
771 |
$order = wc_get_order($orderId);
|
772 |
|
777 |
|
778 |
protected function verifyOrderAmount($razorpayOrderId, $orderId)
|
779 |
{
|
780 |
+
rzpLogInfo("Called verifyOrderAmount with params orderId $orderId and rzporderId $razorpayOrderId");
|
781 |
$order = wc_get_order($orderId);
|
782 |
|
783 |
$api = $this->getRazorpayApiInstance();
|
789 |
catch (Exception $e)
|
790 |
{
|
791 |
$message = $e->getMessage();
|
792 |
+
rzpLogInfo("Failed at verifyOrderAmount with $message");
|
793 |
return "RAZORPAY ERROR: Order fetch failed with the message '$message'";
|
794 |
}
|
795 |
|
817 |
|
818 |
private function getOrderCreationData($orderId)
|
819 |
{
|
820 |
+
rzpLogInfo("Called getOrderCreationData with params orderId $orderId");
|
821 |
$order = wc_get_order($orderId);
|
822 |
|
823 |
+
$is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
|
824 |
+
|
825 |
$data = array(
|
826 |
'receipt' => $orderId,
|
827 |
'amount' => (int) round($order->get_total() * 100),
|
833 |
),
|
834 |
);
|
835 |
|
836 |
+
if ($this->getSetting('route_enable') == 'yes')
|
837 |
{
|
838 |
$razorpayRoute = new RZP_Route_Action();
|
839 |
$orderTransferArr = $razorpayRoute->getOrderTransferData($orderId);
|
847 |
}
|
848 |
}
|
849 |
|
850 |
+
if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
|
851 |
+
{
|
852 |
+
$data = $this->orderArg1CC($data, $order);
|
853 |
+
}
|
854 |
+
|
855 |
+
return $data;
|
856 |
+
}
|
857 |
+
|
858 |
+
public function orderArg1CC($data, $order)
|
859 |
+
{
|
860 |
+
// TODO: trim to 2 deciamls
|
861 |
+
$data['line_items_total'] = $order->get_total()*100;
|
862 |
+
|
863 |
return $data;
|
864 |
}
|
865 |
|
866 |
+
private function enqueueCheckoutScripts($data)
|
867 |
{
|
868 |
if($data === 'checkoutForm' || $data === 'routeAnalyticsForm')
|
869 |
{
|
1028 |
**/
|
1029 |
function process_payment($order_id)
|
1030 |
{
|
1031 |
+
rzpLogInfo("Called process_payment with params order_id $order_id");
|
1032 |
+
|
1033 |
global $woocommerce;
|
1034 |
|
1035 |
$order = wc_get_order($order_id);
|
1036 |
|
1037 |
+
set_transient(self::SESSION_KEY, $order_id, 3600);
|
1038 |
+
rzpLogInfo("Set transient with key " . self::SESSION_KEY . " params order_id $order_id");
|
1039 |
+
|
1040 |
$orderKey = $this->getOrderKey($order);
|
1041 |
|
1042 |
if (version_compare(WOOCOMMERCE_VERSION, '2.1', '>='))
|
1071 |
|
1072 |
/**
|
1073 |
* Check for valid razorpay server callback
|
1074 |
+
* Called once payment is completed using redirect method
|
1075 |
+
*/
|
1076 |
function check_razorpay_response()
|
1077 |
{
|
1078 |
global $woocommerce;
|
1079 |
global $wpdb;
|
1080 |
|
1081 |
$order = false;
|
1082 |
+
rzpLogInfo("Called check_razorpay_response");
|
1083 |
|
1084 |
$post_type = 'shop_order';
|
1085 |
+
|
1086 |
$post_password = sanitize_text_field($_GET['order_key']);
|
1087 |
|
1088 |
$postIds = $wpdb->get_col( $wpdb->prepare("SELECT ID FROM $wpdb->posts AS P WHERE post_type=%s AND post_password = %s", $post_type, $post_password ) );
|
1089 |
|
1090 |
+
if (count($postIds) > 0)
|
1091 |
{
|
1092 |
$orderId = $postIds[0];
|
1093 |
$order = wc_get_order($orderId);
|
1094 |
+
rzpLogInfo("get_transient in check_razorpay_response: orderId $orderId");
|
1095 |
}
|
1096 |
|
1097 |
+
// TODO: Handle redirect
|
1098 |
+
if ($order === false)
|
1099 |
{
|
1100 |
+
// TODO: Add test mode condition
|
1101 |
+
if (is1ccEnabled())
|
1102 |
+
{
|
1103 |
+
wp_redirect(wc_get_cart_url());
|
1104 |
+
exit;
|
1105 |
+
}
|
1106 |
wp_redirect(wc_get_checkout_url());
|
1107 |
exit;
|
1108 |
}
|
1109 |
|
|
|
1110 |
// If the order has already been paid for
|
1111 |
// redirect user to success page
|
|
|
1112 |
if ($order->needs_payment() === false)
|
1113 |
{
|
1114 |
+
$cartHash = get_transient(RZP_1CC_CART_HASH.$orderId);
|
1115 |
+
|
1116 |
+
if ($cartHash != false)
|
1117 |
+
{
|
1118 |
+
// Need to delete the cart hash stored in transient.
|
1119 |
+
// Becuase the cart hash will be depending on the cart items so this will cause the issue when order api triggers.
|
1120 |
+
$woocommerce->session->__unset(RZP_1CC_CART_HASH.$cartHash);
|
1121 |
+
}
|
1122 |
+
|
1123 |
$this->redirectUser($order);
|
1124 |
}
|
1125 |
|
1135 |
$this->verifySignature($orderId);
|
1136 |
$success = true;
|
1137 |
$razorpayPaymentId = sanitize_text_field($_POST[self::RAZORPAY_PAYMENT_ID]);
|
1138 |
+
|
1139 |
+
$cartHash = get_transient(RZP_1CC_CART_HASH.$orderId);
|
1140 |
+
|
1141 |
+
if ($cartHash != false)
|
1142 |
+
{
|
1143 |
+
// Need to delete the cart hash stored in transient.
|
1144 |
+
// Becuase the cart hash will be depending on the cart items so this will cause the issue when order api triggers.
|
1145 |
+
$woocommerce->session->__unset(RZP_1CC_CART_HASH.$cartHash);
|
1146 |
+
}
|
1147 |
}
|
1148 |
catch (Errors\SignatureVerificationError $e)
|
1149 |
{
|
1152 |
}
|
1153 |
else
|
1154 |
{
|
1155 |
+
if(isset($_POST[self::RAZORPAY_WC_FORM_SUBMIT]) && $_POST[self::RAZORPAY_WC_FORM_SUBMIT] ==1)
|
1156 |
{
|
1157 |
$success = false;
|
1158 |
$error = 'Customer cancelled the payment';
|
1163 |
$error = "Payment Failed.";
|
1164 |
}
|
1165 |
|
1166 |
+
$is1ccOrder = get_post_meta( $orderId, 'is_magic_checkout_order', true );
|
1167 |
+
|
1168 |
+
if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
|
1169 |
+
{
|
1170 |
+
$api = $this->getRazorpayApiInstance();
|
1171 |
+
$sessionKey = $this->getOrderSessionKey($orderId);
|
1172 |
+
$razorpayOrderId = get_transient($sessionKey);
|
1173 |
+
$razorpayData = $api->order->fetch($razorpayOrderId);
|
1174 |
+
|
1175 |
+
$this->updateOrderAddress($razorpayData['items'][0], $order);
|
1176 |
+
}
|
1177 |
+
|
1178 |
$this->handleErrorCase($order);
|
1179 |
$this->updateOrder($order, $success, $error, $razorpayPaymentId, null);
|
1180 |
|
1181 |
+
if (is1ccEnabled())
|
1182 |
+
{
|
1183 |
+
wp_redirect(wc_get_cart_url());
|
1184 |
+
exit;
|
1185 |
+
}
|
1186 |
+
|
1187 |
wp_redirect(wc_get_checkout_url());
|
1188 |
exit;
|
1189 |
}
|
1203 |
|
1204 |
protected function verifySignature($orderId)
|
1205 |
{
|
1206 |
+
rzpLogInfo("verifySignature orderId: $orderId");
|
1207 |
+
|
1208 |
global $woocommerce;
|
1209 |
|
1210 |
$api = $this->getRazorpayApiInstance();
|
1215 |
);
|
1216 |
|
1217 |
$sessionKey = $this->getOrderSessionKey($orderId);
|
|
|
1218 |
//Check the transient data for razorpay order id, if it's not available then look into session data.
|
1219 |
if(get_transient($sessionKey))
|
1220 |
{
|
1226 |
}
|
1227 |
|
1228 |
$attributes[self::RAZORPAY_ORDER_ID] = $razorpayOrderId?? '';
|
1229 |
+
rzpLogInfo("verifySignature attr");
|
1230 |
+
rzpLogInfo(json_encode($attributes));
|
1231 |
$api->utility->verifyPaymentSignature($attributes);
|
1232 |
}
|
1233 |
|
1239 |
protected function getErrorMessage($orderId)
|
1240 |
{
|
1241 |
// We don't have a proper order id
|
1242 |
+
rzpLogInfo("getErrorMessage orderId: $orderId");
|
1243 |
+
|
1244 |
if ($orderId !== null)
|
1245 |
{
|
1246 |
$message = 'An error occured while processing this payment';
|
1264 |
{
|
1265 |
$message = 'An error occured. Please contact administrator for assistance';
|
1266 |
}
|
1267 |
+
rzpLogInfo("returning $getErrorMessage");
|
1268 |
return $message;
|
1269 |
}
|
1270 |
|
1279 |
|
1280 |
$orderId = $order->get_order_number();
|
1281 |
|
1282 |
+
rzpLogInfo("updateOrder orderId: $orderId , errorMessage: $errorMessage, razorpayPaymentId: $razorpayPaymentId , success: $success");
|
1283 |
+
|
1284 |
if (($success === true) and ($order->needs_payment() === true))
|
1285 |
{
|
1286 |
+
try
|
1287 |
+
{
|
1288 |
+
$wcOrderId = $order->get_id();
|
1289 |
+
|
1290 |
+
$is1ccOrder = get_post_meta( $wcOrderId, 'is_magic_checkout_order', true );
|
1291 |
+
|
1292 |
+
if (is1ccEnabled() && !empty($is1ccOrder) && $is1ccOrder == 'yes')
|
1293 |
+
{
|
1294 |
+
//To verify whether the 1cc update order function already under execution or not
|
1295 |
+
if(get_transient('wc_order_under_process_'.$wcOrderId) === false)
|
1296 |
+
{
|
1297 |
+
$this->update1ccOrderWC($order, $wcOrderId, $razorpayPaymentId);
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
}
|
1301 |
+
} catch (Exception $e) {
|
1302 |
+
$message = $e->getMessage();
|
1303 |
+
rzpLogError("Failed to update 1cc flow with error : $message");
|
1304 |
+
}
|
1305 |
+
|
1306 |
+
$payment_method=$order->get_payment_method();
|
1307 |
+
|
1308 |
+
// Need to set the status manually to processing incase of COD payment method.
|
1309 |
+
if ($payment_method == "cod")
|
1310 |
+
{
|
1311 |
+
$order->update_status( 'processing' );
|
1312 |
+
}
|
1313 |
+
else
|
1314 |
+
{
|
1315 |
+
$order->payment_complete($razorpayPaymentId);
|
1316 |
+
}
|
1317 |
+
|
1318 |
$order->add_order_note("Razorpay payment successful <br/>Razorpay Id: $razorpayPaymentId");
|
1319 |
|
1320 |
if($this->getSetting('route_enable') == 'yes')
|
1353 |
if ($webhook === false)
|
1354 |
{
|
1355 |
$this->add_notice($this->msg['message'], $this->msg['class']);
|
1356 |
+
|
1357 |
+
rzpLogInfo("Woocommerce orderId: $orderId processed through callback");
|
1358 |
+
}
|
1359 |
+
else
|
1360 |
+
{
|
1361 |
+
rzpLogInfo("Woocommerce orderId: $orderId processed through webhook");
|
1362 |
}
|
1363 |
}
|
1364 |
|
1365 |
+
public function update1ccOrderWC(& $order, $wcOrderId, $razorpayPaymentId)
|
1366 |
+
{
|
1367 |
+
$logObj = array();
|
1368 |
+
rzpLogInfo("update1ccOrderWC wcOrderId: $wcOrderId, razorpayPaymentId: $razorpayPaymentId");
|
1369 |
+
|
1370 |
+
//To avoid the symultanious update from callback and webhook
|
1371 |
+
set_transient('wc_order_under_process_'.$wcOrderId, true, 300);
|
1372 |
+
|
1373 |
+
$api = $this->getRazorpayApiInstance();
|
1374 |
+
$sessionKey = $this->getOrderSessionKey($wcOrderId);
|
1375 |
+
$razorpayOrderId = get_transient($sessionKey);
|
1376 |
+
$razorpayData = $api->order->fetch($razorpayOrderId);
|
1377 |
+
|
1378 |
+
$this->updateOrderAddress($razorpayData, $order);
|
1379 |
+
|
1380 |
+
|
1381 |
+
if (empty($razorpayData['promotions'][0]) === false)
|
1382 |
+
{
|
1383 |
+
$couponKey = $razorpayData['promotions'][0]['code'];
|
1384 |
+
}
|
1385 |
+
|
1386 |
+
//Apply coupon to woo-order
|
1387 |
+
if (empty($couponKey) === false)
|
1388 |
+
{
|
1389 |
+
//TODO: Convert all razorpay amount in paise to rupees
|
1390 |
+
$discount_total = $razorpayData['promotions'][0]['value']/100;
|
1391 |
+
|
1392 |
+
//TODO: Verify source code implementation
|
1393 |
+
// Loop through products and apply the coupon discount
|
1394 |
+
foreach($order->get_items() as $order_item)
|
1395 |
+
{
|
1396 |
+
$total = $order_item->get_total();
|
1397 |
+
$order_item->set_subtotal($total);
|
1398 |
+
$order_item->set_total($total - $discount_total);
|
1399 |
+
$order_item->save();
|
1400 |
+
}
|
1401 |
+
// TODO: Test if individual use coupon fails by hardcoding here
|
1402 |
+
$isApplied = $order->apply_coupon($couponKey);
|
1403 |
+
$order->save();
|
1404 |
+
}
|
1405 |
+
|
1406 |
+
//Apply shipping charges to woo-order
|
1407 |
+
if(isset($razorpayData['shipping_fee']) === true)
|
1408 |
+
{
|
1409 |
+
// Get a new instance of the WC_Order_Item_Shipping Object
|
1410 |
+
$item = new WC_Order_Item_Shipping();
|
1411 |
+
|
1412 |
+
// if shipping charges zero
|
1413 |
+
if($razorpayData['shipping_fee'] == 0)
|
1414 |
+
{
|
1415 |
+
$item->set_method_title( 'Free Shipping' );
|
1416 |
+
}
|
1417 |
+
else
|
1418 |
+
{
|
1419 |
+
$isStoreShippingEnabled = "";
|
1420 |
+
$shippingData = get_post_meta( $wcOrderId, '1cc_shippinginfo', true );
|
1421 |
+
|
1422 |
+
if (class_exists('WCFMmp'))
|
1423 |
+
{
|
1424 |
+
$shippingOptions = get_option( 'wcfm_shipping_options', array());
|
1425 |
+
// By default store shipping should be consider enable
|
1426 |
+
$isStoreShippingEnabled = isset( $shippingOptions['enable_store_shipping'] ) ? $shippingOptions['enable_store_shipping'] : 'yes';
|
1427 |
+
}
|
1428 |
+
|
1429 |
+
if ($isStoreShippingEnabled == 'yes')
|
1430 |
+
{
|
1431 |
+
foreach ($shippingData as $key => $value)
|
1432 |
+
{
|
1433 |
+
$item = new WC_Order_Item_Shipping();
|
1434 |
+
//$item->set_method_id($test[$key]['rate_id']);
|
1435 |
+
$item->set_method_title($shippingData[$key]['name']);
|
1436 |
+
$item->set_total($shippingData[$key]['price']/100 );
|
1437 |
+
$order->add_item($item);
|
1438 |
+
$item->save();
|
1439 |
+
$itemId = $item->get_id();
|
1440 |
+
|
1441 |
+
$wcfmCommissionOptions = get_option( 'wcfm_commission_options', array() );
|
1442 |
+
|
1443 |
+
$vendorGetShipping = isset( $wcfmCommissionOptions['get_shipping'] ) ? $wcfmCommissionOptions['get_shipping'] : 'yes';
|
1444 |
+
|
1445 |
+
if (isset($shippingData[$key]['vendor_id']) && $vendorGetShipping == 'yes')
|
1446 |
+
{
|
1447 |
+
$itemData = array(
|
1448 |
+
'method_id' => $shippingData[$key]['method_id'],
|
1449 |
+
'instance_id' => $shippingData[$key]['instance_id'],
|
1450 |
+
'vendor_id' => $shippingData[$key]['vendor_id'],
|
1451 |
+
'Items' => $shippingData[$key]['meta_data'][0]['value']
|
1452 |
+
);
|
1453 |
+
updateVendorDetails($shippingData[$key]['price']/100, $shippingData[$key]['vendor_id'], $wcOrderId);
|
1454 |
+
|
1455 |
+
foreach ($itemData as $itemkey => $itemval)
|
1456 |
+
{
|
1457 |
+
wc_update_order_item_meta( $itemId, $itemkey, $itemval);
|
1458 |
+
}
|
1459 |
+
}
|
1460 |
+
|
1461 |
+
}
|
1462 |
+
}
|
1463 |
+
else
|
1464 |
+
{
|
1465 |
+
$item = new WC_Order_Item_Shipping();
|
1466 |
+
|
1467 |
+
// if shipping charges zero
|
1468 |
+
if ($razorpayData['shipping_fee'] == 0)
|
1469 |
+
{
|
1470 |
+
$item->set_method_title( 'Free Shipping' );
|
1471 |
+
}
|
1472 |
+
else
|
1473 |
+
{
|
1474 |
+
$item->set_method_title($shippingData[0]['name']);
|
1475 |
+
}
|
1476 |
+
|
1477 |
+
// set an non existing Shipping method rate ID will mark the order as completed instead of processing status
|
1478 |
+
// $item->set_method_id( "flat_rate:1" );
|
1479 |
+
$item->set_total( $razorpayData['shipping_fee']/100 );
|
1480 |
+
|
1481 |
+
$order->add_item( $item );
|
1482 |
+
|
1483 |
+
$item->save();
|
1484 |
+
}
|
1485 |
+
// Calculate totals and save
|
1486 |
+
$order->calculate_totals();
|
1487 |
+
|
1488 |
+
}
|
1489 |
+
}
|
1490 |
+
|
1491 |
+
// set default payment method
|
1492 |
+
$payment_method = $this->id;
|
1493 |
+
|
1494 |
+
// To verify the payment method for particular payment id.
|
1495 |
+
$razorpayPyamentData = $api->payment->fetch($razorpayPaymentId);
|
1496 |
+
|
1497 |
+
$paymentDoneBy = $razorpayPyamentData['method'];
|
1498 |
+
|
1499 |
+
if (($paymentDoneBy === 'cod') && isset($razorpayData['cod_fee']) == true)
|
1500 |
+
{
|
1501 |
+
$codKey = $razorpayData['cod_fee']/100;
|
1502 |
+
$payment_method = 'cod';
|
1503 |
+
}
|
1504 |
+
|
1505 |
+
//update payment method title
|
1506 |
+
$order->set_payment_method($payment_method);
|
1507 |
+
$order->save();
|
1508 |
+
|
1509 |
+
if (($paymentDoneBy === 'cod') && isset($razorpayData['cod_fee']) == true)
|
1510 |
+
{
|
1511 |
+
// Get a new instance of the WC_Order_Item_Fee Object
|
1512 |
+
$itemFee = new WC_Order_Item_Fee();
|
1513 |
+
|
1514 |
+
$itemFee->set_name('COD Fee'); // Generic fee name
|
1515 |
+
$itemFee->set_amount($codKey); // Fee amount
|
1516 |
+
// $itemFee->set_tax_class(''); // default for ''
|
1517 |
+
$itemFee->set_tax_status( 'none' ); // If we don't set tax status then it will consider by dafalut tax class.
|
1518 |
+
$itemFee->set_total($codKey); // Fee amount
|
1519 |
+
|
1520 |
+
// Calculating Fee taxes
|
1521 |
+
// $itemFee->calculate_taxes( $calculateTaxFor );
|
1522 |
+
|
1523 |
+
// Add Fee item to the order
|
1524 |
+
$order->add_item($itemFee);
|
1525 |
+
$order->calculate_totals();
|
1526 |
+
$order->save();
|
1527 |
+
}
|
1528 |
+
|
1529 |
+
$note = __('Order placed through Razorpay Magic Checkout');
|
1530 |
+
$order->add_order_note( $note );
|
1531 |
+
}
|
1532 |
+
|
1533 |
+
//To update customer address info to wc order.
|
1534 |
+
public function updateOrderAddress($razorpayData, $order)
|
1535 |
+
{
|
1536 |
+
if (isset($razorpayData['customer_details']['shipping_address']))
|
1537 |
+
{
|
1538 |
+
$shippingAddressKey = $razorpayData['customer_details']['shipping_address'];
|
1539 |
+
|
1540 |
+
$shippingAddress = [];
|
1541 |
+
|
1542 |
+
$shippingAddress['first_name'] = $shippingAddressKey['name'];
|
1543 |
+
$shippingAddress['address_1'] = $shippingAddressKey['line1'];
|
1544 |
+
$shippingAddress['address_2'] = $shippingAddressKey['line2'];
|
1545 |
+
$shippingAddress['city'] = $shippingAddressKey['city'];
|
1546 |
+
$shippingAddress['country'] = strtoupper($shippingAddressKey['country']);
|
1547 |
+
$shippingAddress['postcode'] = $shippingAddressKey['zipcode'];
|
1548 |
+
$shippingAddress['email'] = $razorpayData['customer_details']['email'];
|
1549 |
+
$shippingAddress['phone'] = $shippingAddressKey['contact'];
|
1550 |
+
|
1551 |
+
$order->set_address( $shippingAddress, 'shipping' );
|
1552 |
+
|
1553 |
+
$shippingState = strtoupper($shippingAddressKey['state']);
|
1554 |
+
$shippingStateName = str_replace(" ", '', $shippingState);
|
1555 |
+
$shippingStateCode = getWcStateCodeFromName($shippingStateName);
|
1556 |
+
$order->set_shipping_state($shippingStateCode);
|
1557 |
+
|
1558 |
+
$this->updateUserAddressInfo('shipping_', $shippingAddress, $shippingStateCode, $order);
|
1559 |
+
|
1560 |
+
if (empty($razorpayData['customer_details']['billing_address']) == false)
|
1561 |
+
{
|
1562 |
+
$billingAddress['first_name'] = $razorpayData['customer_details']['billing_address']['name'];
|
1563 |
+
$billingAddress['address_1'] = $razorpayData['customer_details']['billing_address']['line1'];
|
1564 |
+
$billingAddress['address_2'] = $razorpayData['customer_details']['billing_address']['line2'];
|
1565 |
+
$billingAddress['city'] = $razorpayData['customer_details']['billing_address']['city'];
|
1566 |
+
$billingAddress['country'] = strtoupper($razorpayData['customer_details']['billing_address']['country']);
|
1567 |
+
$billingAddress['postcode'] = $razorpayData['customer_details']['billing_address']['zipcode'];
|
1568 |
+
$billingAddress['email'] = $razorpayData['customer_details']['email'];
|
1569 |
+
$billingAddress['phone'] = $razorpayData['customer_details']['billing_address']['contact'];
|
1570 |
+
$order->set_address( $billingAddress, 'billing' );
|
1571 |
+
|
1572 |
+
$billingState = strtoupper($razorpayData['customer_details']['billing_address']['state']);
|
1573 |
+
$billingStateName = str_replace(" ", '', $billingState);
|
1574 |
+
$billingStateCode = getWcStateCodeFromName($billingStateName);
|
1575 |
+
$order->set_billing_state($billingStateCode);
|
1576 |
+
|
1577 |
+
$this->updateUserAddressInfo('billing_', $billingAddress, $billingStateCode, $order);
|
1578 |
+
}
|
1579 |
+
else
|
1580 |
+
{
|
1581 |
+
$order->set_address( $shippingAddress, 'billing' );
|
1582 |
+
$order->set_billing_state($shippingStateCode);
|
1583 |
+
|
1584 |
+
$this->updateUserAddressInfo('billing_', $shippingAddress, $shippingStateCode, $order);
|
1585 |
+
}
|
1586 |
+
|
1587 |
+
$order->save();
|
1588 |
+
}
|
1589 |
+
}
|
1590 |
+
|
1591 |
+
/**
|
1592 |
+
* Retrieve a Shipping Zone by it's ID.
|
1593 |
+
*
|
1594 |
+
* @param int $zone_id Shipping Zone ID.
|
1595 |
+
* @return WC_Shipping_Zone|WP_Error
|
1596 |
+
*/
|
1597 |
+
// TODO: can't we directly return the statement?
|
1598 |
+
protected function getShippingZone($zoneId)
|
1599 |
+
{
|
1600 |
+
$zone = WC_Shipping_Zones::get_zone_by('zone_id', $zoneId);
|
1601 |
+
|
1602 |
+
return $zone;
|
1603 |
+
}
|
1604 |
+
|
1605 |
+
|
1606 |
+
|
1607 |
+
|
1608 |
+
// Update user billing and shipping information
|
1609 |
+
protected function updateUserAddressInfo($addressKeyPrefix, $addressValue, $stateValue, $order)
|
1610 |
+
{
|
1611 |
+
foreach ($addressValue as $key => $value)
|
1612 |
+
{
|
1613 |
+
$metaKey = $addressKeyPrefix;
|
1614 |
+
$metaKey .= $key;
|
1615 |
+
|
1616 |
+
update_user_meta($order->get_user_id(), $metaKey, $value);
|
1617 |
+
}
|
1618 |
+
|
1619 |
+
update_user_meta($order->get_user_id(), $addressKeyPrefix . 'state', $stateValue);
|
1620 |
+
}
|
1621 |
+
|
1622 |
protected function handleErrorCase(& $order)
|
1623 |
{
|
1624 |
$orderId = $order->get_order_number();
|
1625 |
+
rzpLogInfo('handleErrorCase');
|
1626 |
$this->msg['class'] = 'error';
|
1627 |
$this->msg['message'] = $this->getErrorMessage($orderId);
|
1628 |
}
|
1684 |
|
1685 |
}
|
1686 |
|
1687 |
+
//update vendor data into wp_wcfm_marketplace_orders
|
1688 |
+
function updateVendorDetails($shippingFee, $vendorId, $orderId)
|
1689 |
+
{
|
1690 |
+
global $woocommerce;
|
1691 |
+
global $wpdb;
|
1692 |
+
$commission = $wpdb->get_results(
|
1693 |
+
$wpdb->prepare(
|
1694 |
+
'SELECT * FROM `' . $wpdb->prefix . 'wcfm_marketplace_orders` WHERE vendor_id = %d AND order_id = %d',
|
1695 |
+
$vendorId,
|
1696 |
+
$orderId
|
1697 |
+
)
|
1698 |
+
);
|
1699 |
+
|
1700 |
+
if (count($commission) > 0)
|
1701 |
+
{
|
1702 |
+
$totalComm = $commission[0]->total_commission+$shippingFee;
|
1703 |
+
$wpdb->query(
|
1704 |
+
$wpdb->prepare(
|
1705 |
+
'UPDATE `' . $wpdb->prefix . 'wcfm_marketplace_orders` SET shipping = %d, total_commission = %d WHERE vendor_id = %d AND order_id = %d',
|
1706 |
+
$shippingFee,
|
1707 |
+
$totalComm,
|
1708 |
+
$vendorId,
|
1709 |
+
$orderId
|
1710 |
+
)
|
1711 |
+
);
|
1712 |
+
}
|
1713 |
+
}
|
1714 |
+
|
1715 |
/**
|
1716 |
* Add the Gateway to WooCommerce
|
1717 |
**/
|
1721 |
return $methods;
|
1722 |
}
|
1723 |
|
1724 |
+
add_filter('woocommerce_payment_gateways', 'woocommerce_add_razorpay_gateway');
|
1725 |
|
1726 |
/**
|
1727 |
* Creating the settings link from the plugins page
|
1749 |
|
1750 |
$rzpWebhook->process();
|
1751 |
}
|
1752 |
+
|
1753 |
+
define('RZP_PATH', plugin_dir_path( __FILE__ ));
|
1754 |
+
define('RZP_CHECKOUTJS_URL', 'https://checkout.razorpay.com/v1/checkout.js');
|
1755 |
+
define('RZP_1CC_CSS_SCRIPT', 'RZP_1CC_CSS_SCRIPT');
|
1756 |
+
|
1757 |
+
|
1758 |
+
function enqueueScriptsFor1cc()
|
1759 |
+
{
|
1760 |
+
$siteurl = get_option('siteurl');
|
1761 |
+
|
1762 |
+
$domain = parse_url($siteurl, PHP_URL_HOST);
|
1763 |
+
$domain_ip = gethostbyname($domain);
|
1764 |
+
|
1765 |
+
//Consider https if site url is not localhost server.
|
1766 |
+
if (filter_var($domain_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE))
|
1767 |
+
{
|
1768 |
+
$siteurl = str_replace('http://', 'https://', $siteurl);
|
1769 |
+
}
|
1770 |
+
|
1771 |
+
wp_register_script('1cc_razorpay_checkout', RZP_CHECKOUTJS_URL, null, null);
|
1772 |
+
wp_enqueue_script('1cc_razorpay_checkout');
|
1773 |
+
|
1774 |
+
wp_register_style(RZP_1CC_CSS_SCRIPT, plugin_dir_url(__FILE__) . 'public/css/1cc-product-checkout.css', null, null);
|
1775 |
+
wp_enqueue_style(RZP_1CC_CSS_SCRIPT);
|
1776 |
+
|
1777 |
+
wp_register_script('btn_1cc_checkout', plugin_dir_url(__FILE__) . 'btn-1cc-checkout.js', null, null);
|
1778 |
+
wp_localize_script('btn_1cc_checkout', 'rzp1ccCheckoutData', array(
|
1779 |
+
'nonce' => wp_create_nonce("wp_rest"),
|
1780 |
+
'siteurl' => $siteurl,
|
1781 |
+
'blogname' => get_bloginfo('name'),
|
1782 |
+
) );
|
1783 |
+
wp_enqueue_script('btn_1cc_checkout');
|
1784 |
+
}
|
1785 |
+
|
1786 |
+
add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
|
1787 |
+
|
1788 |
+
//To add 1CC button on cart page.
|
1789 |
+
add_action( 'woocommerce_proceed_to_checkout', 'addCheckoutButton');
|
1790 |
+
|
1791 |
+
function addCheckoutButton()
|
1792 |
+
{
|
1793 |
+
add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
|
1794 |
+
|
1795 |
+
if (isRazorpayPluginEnabled() && is1ccEnabled() )
|
1796 |
+
{
|
1797 |
+
if (isTestModeEnabled()) {
|
1798 |
+
$current_user = wp_get_current_user();
|
1799 |
+
if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
|
1800 |
+
$tempTest = RZP_PATH . 'templates/rzp-cart-checkout-btn.php';
|
1801 |
+
load_template( $tempTest, false, array() );
|
1802 |
+
}
|
1803 |
+
} else {
|
1804 |
+
$tempTest = RZP_PATH . 'templates/rzp-cart-checkout-btn.php';
|
1805 |
+
load_template( $tempTest, false, array() );
|
1806 |
+
}
|
1807 |
+
}
|
1808 |
+
else
|
1809 |
+
{
|
1810 |
+
return;
|
1811 |
+
}
|
1812 |
+
}
|
1813 |
+
|
1814 |
+
//To add 1CC Mini cart checkout button
|
1815 |
+
if(isRazorpayPluginEnabled() && is1ccEnabled() && isMiniCartCheckoutEnabled())
|
1816 |
+
{
|
1817 |
+
add_action( 'woocommerce_widget_shopping_cart_buttons', function()
|
1818 |
+
{
|
1819 |
+
// Removing Buttons
|
1820 |
+
remove_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_proceed_to_checkout', 20 );
|
1821 |
+
|
1822 |
+
add_action('woocommerce_cart_updated', 'enqueueScriptsFor1cc', 10);
|
1823 |
+
|
1824 |
+
add_action( 'woocommerce_widget_shopping_cart_buttons', 'addMiniCheckoutButton', 20 );
|
1825 |
+
}, 1 );
|
1826 |
+
}
|
1827 |
+
|
1828 |
+
function addMiniCheckoutButton()
|
1829 |
+
{
|
1830 |
+
add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
|
1831 |
+
|
1832 |
+
if (isTestModeEnabled()) {
|
1833 |
+
$current_user = wp_get_current_user();
|
1834 |
+
if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
|
1835 |
+
$tempTest = RZP_PATH . 'templates/rzp-mini-checkout-btn.php';
|
1836 |
+
load_template( $tempTest, false, array() );
|
1837 |
+
}
|
1838 |
+
} else {
|
1839 |
+
$tempTest = RZP_PATH . 'templates/rzp-mini-checkout-btn.php';
|
1840 |
+
load_template( $tempTest, false, array() );
|
1841 |
+
}
|
1842 |
+
|
1843 |
+
}
|
1844 |
+
|
1845 |
+
//To add 1CC button on product page.
|
1846 |
+
if(isRazorpayPluginEnabled() && is1ccEnabled() && isPdpCheckoutEnabled())
|
1847 |
+
{
|
1848 |
+
add_action( 'woocommerce_after_add_to_cart_button', 'addPdpCheckoutButton');
|
1849 |
+
}
|
1850 |
+
|
1851 |
+
function addPdpCheckoutButton()
|
1852 |
+
{
|
1853 |
+
add_action('wp_enqueue_scripts', 'enqueueScriptsFor1cc', 0);
|
1854 |
+
|
1855 |
+
if (isTestModeEnabled()) {
|
1856 |
+
$current_user = wp_get_current_user();
|
1857 |
+
if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
|
1858 |
+
$tempTest = RZP_PATH . 'templates/rzp-pdp-checkout-btn.php';
|
1859 |
+
load_template( $tempTest, false, array() );
|
1860 |
+
}
|
1861 |
+
} else {
|
1862 |
+
$tempTest = RZP_PATH . 'templates/rzp-pdp-checkout-btn.php';
|
1863 |
+
load_template( $tempTest, false, array() );
|
1864 |
+
}
|
1865 |
+
}
|
1866 |
+
|
1867 |
+
// for admin panel custom alerts
|
1868 |
+
function addAdminSettingsAlertScript()
|
1869 |
+
{
|
1870 |
+
if (isRazorpayPluginEnabled()) {
|
1871 |
+
wp_enqueue_script('rzpAdminSettingsScript', plugin_dir_url(__FILE__) .'public/js/admin-rzp-settings.js');
|
1872 |
+
}
|
1873 |
+
}
|
1874 |
+
|
1875 |
+
add_action('admin_enqueue_scripts', 'addAdminSettingsAlertScript');
|
1876 |
+
|
1877 |
+
function disable_coupon_field_on_cart($enabled)
|
1878 |
+
{
|
1879 |
+
if (isTestModeEnabled()) {
|
1880 |
+
$current_user = wp_get_current_user();
|
1881 |
+
if ($current_user->has_cap( 'administrator' ) || preg_match( '/@razorpay.com$/i', $current_user->user_email )) {
|
1882 |
+
if (is_cart() || is_checkout()) {
|
1883 |
+
$enabled = false;
|
1884 |
+
}
|
1885 |
+
}
|
1886 |
+
} else {
|
1887 |
+
if (is_cart() || is_checkout()) {
|
1888 |
+
$enabled = false;
|
1889 |
+
}
|
1890 |
+
}
|
1891 |
+
return $enabled;
|
1892 |
+
}
|
1893 |
+
|
1894 |
+
if(is1ccEnabled())
|
1895 |
+
{
|
1896 |
+
add_filter( 'woocommerce_coupons_enabled', 'disable_coupon_field_on_cart' );
|
1897 |
+
}
|
1898 |
+
|
1899 |
+
add_filter('woocommerce_order_needs_shipping_address', '__return_true');
|