updating session and pos
This commit is contained in:
parent
ad06129a7a
commit
9999efc72b
@ -1,8 +1,4 @@
|
||||
<?php
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Ensure functions are available
|
||||
if (file_exists(__DIR__ . '/../../db/config.php')) {
|
||||
require_once __DIR__ . '/../../db/config.php';
|
||||
@ -10,6 +6,13 @@ if (file_exists(__DIR__ . '/../../db/config.php')) {
|
||||
if (file_exists(__DIR__ . '/../../includes/functions.php')) {
|
||||
require_once __DIR__ . '/../../includes/functions.php';
|
||||
}
|
||||
|
||||
if (function_exists('init_session')) {
|
||||
init_session();
|
||||
} elseif (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
if (file_exists(__DIR__ . '/../../includes/lang.php')) {
|
||||
require_once __DIR__ . '/../../includes/lang.php';
|
||||
}
|
||||
@ -629,4 +632,4 @@ function can_view($module) {
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</header>
|
||||
@ -99,7 +99,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
function formatCurrency(amount) {
|
||||
const symbol = settings.currency_symbol || '$';
|
||||
const decimals = parseInt(settings.currency_decimals || 2);
|
||||
return symbol + parseFloat(amount).toFixed(decimals);
|
||||
return symbol + parseFloat(Math.abs(amount)).toFixed(decimals);
|
||||
}
|
||||
|
||||
function filterProducts() {
|
||||
@ -397,11 +397,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
if (data.success && data.tables.length > 0) {
|
||||
renderTables(data.tables);
|
||||
} else {
|
||||
grid.innerHTML = `<div class=\"p-4 text-center text-muted w-100">${_t("none")}</div>`;
|
||||
grid.innerHTML = `<div class=\"p-4 text-center text-muted w-100\">${_t("none")}</div>`;
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
grid.innerHTML = `<div class=\"alert alert-danger w-100">${_t("error")}</div>`;
|
||||
grid.innerHTML = `<div class=\"alert alert-danger w-100\">${_t("error")}</div>`;
|
||||
});
|
||||
}
|
||||
|
||||
@ -420,7 +420,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
for (const area in areas) {
|
||||
const areaHeader = document.createElement("div");
|
||||
areaHeader.className = "col-12 mt-3";
|
||||
areaHeader.innerHTML = `<h6 class=\"fw-bold text-muted text-uppercase small border-bottom pb-2">${area}</h6>`;
|
||||
areaHeader.innerHTML = `<h6 class=\"fw-bold text-muted text-uppercase small border-bottom pb-2\">${area}</h6>`;
|
||||
grid.appendChild(areaHeader);
|
||||
|
||||
areas[area].forEach(table => {
|
||||
@ -429,7 +429,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const statusClass = table.is_occupied ? "btn-outline-danger" : "btn-outline-success";
|
||||
col.innerHTML = `
|
||||
<button class=\"btn ${statusClass} w-100 py-3 rounded-3 position-relative\" onclick=\"selectTable(${table.id}, '${table.name}')\">
|
||||
<div class=\"fw-bold">${table.name}</div>
|
||||
<div class=\"fw-bold\">${table.name}</div>
|
||||
<div class=\"small\" style=\"font-size: 0.7rem;\">Cap: ${table.capacity}</div>
|
||||
${table.is_occupied ? '<span class="position-absolute top-0 start-100 translate-middle p-1 bg-danger border border-light rounded-circle" title="Occupied"></span>' : ''}
|
||||
</button>
|
||||
@ -634,10 +634,36 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
redeem_loyalty: isLoyaltyRedemption
|
||||
};
|
||||
|
||||
// Prepare receipt data before clearing cart
|
||||
const receiptData = {
|
||||
orderId: null,
|
||||
customer: currentCustomer ? { name: currentCustomer.name, phone: currentCustomer.phone, address: currentCustomer.address || '' } : null,
|
||||
items: cart.map(item => ({
|
||||
name: item.name,
|
||||
variant_name: item.variant_name,
|
||||
quantity: item.quantity,
|
||||
price: item.price
|
||||
})),
|
||||
total: subtotal + vat,
|
||||
vat: vat,
|
||||
orderType: orderType,
|
||||
tableNumber: (orderType === 'dine-in') ? currentTableName : null,
|
||||
date: new Date().toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }),
|
||||
paymentMethod: paymentTypeName || 'Unpaid',
|
||||
loyaltyRedeemed: isLoyaltyRedemption
|
||||
};
|
||||
|
||||
fetch('api/order.php', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(orderData) })
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
receiptData.orderId = data.order_id;
|
||||
|
||||
// Show receipt for Quick Pay (where paymentTypeId is provided)
|
||||
if (paymentTypeId !== null) {
|
||||
printThermalReceipt(receiptData);
|
||||
}
|
||||
|
||||
showToast(`${_t('order_placed')} #${data.order_id}`, 'success');
|
||||
clearCart();
|
||||
if (paymentSelectionModal) paymentSelectionModal.hide();
|
||||
@ -646,6 +672,136 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
});
|
||||
};
|
||||
|
||||
window.printThermalReceipt = function(data) {
|
||||
const width = 400;
|
||||
const height = 800;
|
||||
const left = (screen.width - width) / 2;
|
||||
const top = (screen.height - height) / 2;
|
||||
|
||||
const win = window.open('', '_blank', `width=${width},height=${height},top=${top},left=${left}`);
|
||||
|
||||
if (!win) {
|
||||
alert('Please allow popups for this website to print thermal receipts.');
|
||||
return;
|
||||
}
|
||||
|
||||
const tr = {
|
||||
'Order': 'الطلب', 'Type': 'النوع', 'Date': 'التاريخ', 'Staff': 'الموظف',
|
||||
'Table': 'طاولة', 'Payment': 'الدفع', 'ITEM': 'الصنف', 'TOTAL': 'المجموع',
|
||||
'Subtotal': 'المجموع الفرعي', 'VAT': 'ضريبة القيمة المضافة', 'Tax Included': 'شامل الضريبة',
|
||||
'THANK YOU FOR YOUR VISIT!': 'شكراً لزيارتكم!', 'Please come again.': 'يرجى زيارتنا مرة أخرى.',
|
||||
'Customer Details': 'تفاصيل العميل', 'Tel': 'هاتف', 'takeaway': 'سفري',
|
||||
'dine-in': 'محلي', 'delivery': 'توصيل', 'VAT No': 'الرقم الضريبي', 'CTR No': 'رقم السجل التجاري'
|
||||
};
|
||||
|
||||
const itemsHtml = data.items.map(item => `
|
||||
<tr>
|
||||
<td style="padding: 5px 0; border-bottom: 1px solid #eee;">
|
||||
<div style="font-weight: bold;">${item.name}</div>
|
||||
${item.variant_name ? `<div style="font-size: 10px; color: #555;">(${item.variant_name})</div>` : ''}
|
||||
<div style="font-size: 11px;">${item.quantity} x ${formatCurrency(item.price)}</div>
|
||||
</td>
|
||||
<td style="text-align: right; vertical-align: middle; font-weight: bold;">${formatCurrency(item.quantity * item.price)}</td>
|
||||
</tr>
|
||||
`).join('');
|
||||
|
||||
const customerHtml = data.customer ? `
|
||||
<div style="margin-bottom: 10px; border: 1px solid #eee; padding: 8px; border-radius: 4px;">
|
||||
<div style="font-weight: bold; text-transform: uppercase; font-size: 10px; color: #666; margin-bottom: 3px;">
|
||||
<span style="float: left;">Customer Details</span>
|
||||
<span style="float: right;">${tr['Customer Details']}</span>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<div style="font-weight: bold;">${data.customer.name}</div>
|
||||
${data.customer.phone ? `<div>Tel: ${data.customer.phone}</div>` : ''}
|
||||
${data.customer.address ? `<div style="font-size: 11px;">${data.customer.address}</div>` : ''}
|
||||
</div>
|
||||
` : '';
|
||||
|
||||
const tableHtml = data.tableNumber && data.orderType === 'dine-in' ? `
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<span><strong>Table:</strong> ${data.tableNumber}</span>
|
||||
<span><strong>${tr['Table']}:</strong> ${data.tableNumber}</span>
|
||||
</div>` : '';
|
||||
|
||||
const paymentHtml = data.paymentMethod ? `
|
||||
<div style="display: flex; justify-content: space-between;">
|
||||
<span><strong>Payment:</strong> ${data.paymentMethod}</span>
|
||||
<span><strong>${tr['Payment']}:</strong> ${data.paymentMethod}</span>
|
||||
</div>` : '';
|
||||
|
||||
const loyaltyHtml = data.loyaltyRedeemed ? `<div style="color: #d63384; font-weight: bold; margin: 5px 0; text-align: center;">* Loyalty Reward Applied *</div>` : '';
|
||||
|
||||
const subtotal = data.total - data.vat;
|
||||
const logoHtml = settings.logo_url ? `<img src="${BASE_URL}${settings.logo_url}" style="max-height: 80px; max-width: 150px; margin-bottom: 10px;">` : '';
|
||||
|
||||
const html = `
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<title>Receipt #${data.orderId}</title>
|
||||
<style>
|
||||
body { font-family: 'Courier New', Courier, monospace; font-size: 13px; margin: 0; padding: 15px; color: #000; line-height: 1.4; }
|
||||
.header { text-align: center; margin-bottom: 15px; }
|
||||
.header h2 { margin: 0 0 5px 0; font-size: 20px; font-weight: bold; }
|
||||
.header div { font-size: 12px; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
.divider { border-bottom: 2px dashed #000; margin: 10px 0; }
|
||||
.thick-divider { border-bottom: 2px solid #000; margin: 10px 0; }
|
||||
.totals td { padding: 3px 0; }
|
||||
.footer { text-align: center; margin-top: 25px; font-size: 12px; }
|
||||
.order-info { font-size: 11px; margin-bottom: 10px; }
|
||||
.order-info-row { display: flex; justify-content: space-between; margin-bottom: 2px; }
|
||||
.rtl { direction: rtl; unicode-bidi: embed; }
|
||||
@media print { body { width: 80mm; padding: 5mm; } @page { size: 80mm auto; margin: 0; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
${logoHtml}
|
||||
<h2>${settings.company_name}</h2>
|
||||
<div style="font-weight: bold;">${CURRENT_OUTLET.name}</div>
|
||||
<div>${settings.address || ''}</div>
|
||||
<div>Tel: ${settings.phone || ''}</div>
|
||||
${settings.vat_number ? `<div style="margin-top: 4px;">VAT No / الرقم الضريبي: ${settings.vat_number}</div>` : ''}
|
||||
${settings.ctr_number ? `<div>CTR No / رقم السجل: ${settings.ctr_number}</div>` : ''}
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="order-info">
|
||||
<div class="order-info-row"><span><strong>Order:</strong> #${data.orderId}</span><span><strong>${tr['Order']}:</strong> #${data.orderId}</span></div>
|
||||
<div class="order-info-row"><span><strong>Type:</strong> ${data.orderType.toUpperCase()}</span><span><strong>${tr['Type']}:</strong> ${tr[data.orderType] || data.orderType}</span></div>
|
||||
<div class="order-info-row"><span><strong>Date:</strong> ${data.date}</span><span><strong>${tr['Date']}:</strong> ${data.date}</span></div>
|
||||
<div class="order-info-row"><span><strong>Staff:</strong> ${CURRENT_USER.name}</span><span><strong>${tr['Staff']}:</strong> ${CURRENT_USER.name}</span></div>
|
||||
</div>
|
||||
${tableHtml}${paymentHtml}${loyaltyHtml}
|
||||
<div class="thick-divider"></div>
|
||||
${customerHtml}
|
||||
<table>
|
||||
<thead><tr><th style="text-align: left; padding-bottom: 5px;">ITEM / الصنف</th><th style="text-align: right; padding-bottom: 5px;">TOTAL / المجموع</th></tr></thead>
|
||||
<tbody>${itemsHtml}</tbody>
|
||||
</table>
|
||||
<div class="divider"></div>
|
||||
<div class="totals">
|
||||
<table style="width: 100%">
|
||||
<tr><td>Subtotal / ${tr['Subtotal']}</td><td style="text-align: right">${formatCurrency(subtotal)}</td></tr>
|
||||
${Math.abs(data.vat) > 0 ? `<tr><td>${data.vat < 0 ? 'Discount' : 'VAT'} / ${tr['VAT']}</td><td style="text-align: right">${data.vat < 0 ? '-' : '+'}${formatCurrency(Math.abs(data.vat))}</td></tr>` : ''}
|
||||
<tr style="font-weight: bold; font-size: 18px;"><td style="padding-top: 10px;">TOTAL / ${tr['TOTAL']}</td><td style="text-align: right; padding-top: 10px;">${formatCurrency(data.total)}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="thick-divider"></div>
|
||||
<div class="footer">
|
||||
<div style="font-weight: bold; font-size: 14px; margin-bottom: 2px;">THANK YOU FOR YOUR VISIT!</div>
|
||||
<div style="font-weight: bold; font-size: 14px; margin-bottom: 5px;" class="rtl">${tr['THANK YOU FOR YOUR VISIT!']}</div>
|
||||
<div>Please come again.</div><div class="rtl">${tr['Please come again.']}</div>
|
||||
${settings.email ? `<div style="margin-top: 5px; font-size: 10px;">${settings.email}</div>` : ''}
|
||||
<div style="margin-top: 15px; font-size: 10px; color: #888;">Powered by Abidarcafe</div>
|
||||
</div>
|
||||
<script>window.onload = function() { window.print(); setTimeout(function() { window.close(); }, 1500); }</script>
|
||||
</body></html>
|
||||
`;
|
||||
win.document.write(html);
|
||||
win.document.close();
|
||||
};
|
||||
|
||||
window.openRatingQRModal = function() {
|
||||
const qrContainer = document.getElementById('rating-qr-container');
|
||||
const ratingUrl = BASE_URL + '/rate.php';
|
||||
@ -656,4 +812,4 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
const modal = new bootstrap.Modal(document.getElementById('qrRatingModal'));
|
||||
modal.show();
|
||||
};
|
||||
});
|
||||
});
|
||||
@ -228,8 +228,31 @@ function render_pagination_controls($pagination, $extra_params = []) {
|
||||
|
||||
function init_session() {
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
// Set session lifetime to 1 week (604800 seconds)
|
||||
$lifetime = 604800;
|
||||
|
||||
// Ensure gc_maxlifetime is at least as long as cookie lifetime
|
||||
ini_set('session.gc_maxlifetime', (string)$lifetime);
|
||||
|
||||
// Set cookie parameters before session_start
|
||||
$isSecure = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || $_SERVER['SERVER_PORT'] == 443;
|
||||
|
||||
session_set_cookie_params([
|
||||
'lifetime' => $lifetime,
|
||||
'path' => '/',
|
||||
'domain' => '',
|
||||
'secure' => $isSecure,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Lax'
|
||||
]);
|
||||
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Refresh session expiration on each load if user is logged in
|
||||
if (isset($_SESSION['user'])) {
|
||||
// Optional: you could implement a last_activity check here
|
||||
}
|
||||
}
|
||||
|
||||
function login_user($username, $password) {
|
||||
|
||||
31
pos.php
31
pos.php
@ -4,9 +4,7 @@ require_once __DIR__ . '/db/config.php';
|
||||
require_once __DIR__ . '/includes/functions.php';
|
||||
require_once __DIR__ . '/includes/lang.php';
|
||||
|
||||
if (session_status() === PHP_SESSION_NONE) {
|
||||
session_start();
|
||||
}
|
||||
init_session();
|
||||
|
||||
// User requested no translations in all app except for QR order and rating.
|
||||
// Force English for POS.
|
||||
@ -102,7 +100,7 @@ if (!$loyalty_settings) {
|
||||
.pos-products { background: #f8fafc; height: 100%; display: flex; flex-direction: column; }
|
||||
.pos-cart { background: #fff; height: 100%; border-left: 1px solid #e0e0e0; display: flex; flex-direction: column; }
|
||||
|
||||
.product-card { transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; border: 1px solid transparent !important; background: #fff; }
|
||||
.product-card { transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); cursor: pointer; border: 1px solid transparent !important; background: #fff; aspect-ratio: 1/1; display: flex; flex-direction: column; }
|
||||
.product-card:active { transform: scale(0.95); }
|
||||
.product-card:hover { border-color: #0d6efd !important; box-shadow: 0 4px 12px rgba(0,0,0,0.08) !important; }
|
||||
|
||||
@ -112,19 +110,13 @@ if (!$loyalty_settings) {
|
||||
.search-dropdown { position: absolute; width: 100%; z-index: 1000; max-height: 200px; overflow-y: auto; display: none; }
|
||||
|
||||
/* Compact Card adjustments */
|
||||
.card-img-container { height: 75px; position: relative; background: #f1f5f9; }
|
||||
.card-img-container { flex: 1; position: relative; background: #f1f5f9; overflow: hidden; }
|
||||
.card-img-container img { height: 100%; width: 100%; object-fit: cover; transition: transform 0.3s; }
|
||||
.product-title { font-size: 0.75rem; line-height: 1.2; height: 1.8rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-weight: 700; color: #1e293b; }
|
||||
.product-price-tag { font-size: 0.85rem; color: #0d6efd; font-weight: 700; }
|
||||
.product-title { font-size: 0.75rem; line-height: 1.1; height: 2.2rem; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; font-weight: 700; color: #1e293b; }
|
||||
.product-price-tag { font-size: 0.8rem; color: #0d6efd; font-weight: 700; }
|
||||
.product-cat-name { font-size: 0.65rem; color: #94a3b8; }
|
||||
|
||||
/* Custom Grid for 7 columns */
|
||||
@media (min-width: 1200px) {
|
||||
.row-cols-xl-7 > *, .row-cols-xxl-7 > * { flex: 0 0 auto; width: 14.285714%; }
|
||||
}
|
||||
|
||||
@media (max-width: 576px) {
|
||||
.card-img-container { height: 65px; }
|
||||
.pos-categories { width: 65px !important; flex: 0 0 65px !important; }
|
||||
.category-btn span { display: none; }
|
||||
.category-btn i { font-size: 1.4rem !important; margin-bottom: 0 !important; }
|
||||
@ -169,7 +161,6 @@ if (!$loyalty_settings) {
|
||||
<img src="<?= get_base_url() . htmlspecialchars($settings['logo_url']) ?>?v=<?= time() ?>" alt="Logo" height="28" class="me-2">
|
||||
<?php endif; ?>
|
||||
<span class="d-none d-sm-inline" style="letter-spacing: -0.5px;"><?= htmlspecialchars($settings['company_name']) ?></span>
|
||||
<span class="badge bg-primary-subtle text-primary ms-2 fs-7 fw-semibold rounded-pill px-2 border border-primary-subtle"><?= htmlspecialchars($current_outlet_name) ?></span>
|
||||
</a>
|
||||
|
||||
<div class="ms-auto d-flex align-items-center gap-1 gap-sm-2">
|
||||
@ -200,7 +191,7 @@ if (!$loyalty_settings) {
|
||||
|
||||
<div class="row g-0 pos-layout">
|
||||
<!-- Left Sidebar: Categories -->
|
||||
<div class="col-md-2 col-auto pos-categories scrollable-y p-2" style="max-width: 170px;">
|
||||
<div class="col-md-2 col-auto pos-categories scrollable-y p-2" style="max-width: 220px;">
|
||||
<button class="category-btn active mb-2" data-category="all">
|
||||
<i class="bi bi-grid fs-5 text-inherit"></i>
|
||||
<span style="font-size: 0.85rem; font-weight: 700;">All</span>
|
||||
@ -222,7 +213,7 @@ if (!$loyalty_settings) {
|
||||
<!-- Search Bar -->
|
||||
<div class="px-3 py-2 border-bottom bg-white">
|
||||
<div class="row g-2 align-items-center">
|
||||
<div class="col">
|
||||
<div class="col-md-6 col-lg-5">
|
||||
<div class="position-relative">
|
||||
<span class="position-absolute top-50 start-0 translate-middle-y ms-3 text-muted">
|
||||
<i class="bi bi-search small"></i>
|
||||
@ -232,7 +223,7 @@ if (!$loyalty_settings) {
|
||||
</div>
|
||||
<?php if (count($outlets) > 1): ?>
|
||||
<div class="col-auto">
|
||||
<select class="form-select form-select-sm border-0 bg-light rounded-3 fw-bold text-primary" style="min-width: 120px;" onchange="location.href='?outlet_id=' + this.value + '&order_type=<?= $order_type ?>'">
|
||||
<select class="form-select form-select-sm border-0 bg-light rounded-3 fw-bold text-primary" style="min-width: 200px;" onchange="location.href='?outlet_id=' + this.value + '&order_type=<?= $order_type ?>'">
|
||||
<?php foreach ($outlets as $o): ?>
|
||||
<option value="<?= $o['id'] ?>" <?= $o['id'] == $outlet_id ? 'selected' : '' ?>><?= htmlspecialchars($o['name']) ?></option>
|
||||
<?php endforeach; ?>
|
||||
@ -244,7 +235,7 @@ if (!$loyalty_settings) {
|
||||
|
||||
<!-- Grid Container -->
|
||||
<div class="flex-grow-1 scrollable-y p-2">
|
||||
<div class="row g-2 row-cols-3 row-cols-sm-4 row-cols-md-5 row-cols-lg-6 row-cols-xl-7 row-cols-xxl-7" id="product-grid">
|
||||
<div class="row g-2 row-cols-3 row-cols-sm-4 row-cols-md-5 row-cols-lg-6 row-cols-xl-6 row-cols-xxl-6" id="product-grid">
|
||||
<?php foreach ($all_products as $product): ?>
|
||||
<?php $has_variants = !empty($variants_by_product[$product['id']]); ?>
|
||||
<div class="col product-item"
|
||||
@ -267,7 +258,7 @@ if (!$loyalty_settings) {
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="card-body p-1 text-center d-flex flex-column justify-content-between">
|
||||
<div class="card-body p-1 text-center d-flex flex-column justify-content-between flex-grow-0">
|
||||
<div>
|
||||
<h6 class="card-title product-title mb-0"><?= htmlspecialchars($product['name']) ?></h6>
|
||||
</div>
|
||||
@ -487,4 +478,4 @@ if (!$loyalty_settings) {
|
||||
</script>
|
||||
<script src="assets/js/main.js?v=<?= time() ?>"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
Loading…
x
Reference in New Issue
Block a user