- public/index.html — landing page at root - public/pages/ — all feature pages (regulations, loadboard, etc.) - public/js/ — api.js, nav.js, mock data files - All links updated to absolute paths (/pages/, /js/) - Express static path updated to serve from public/ - Seed script path updated for new mock data location - README updated with new project structure and setup guide - Added .env.example template Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
445 lines
21 KiB
HTML
445 lines
21 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>State Regulations Map | PilotEdge</title>
|
|
<script src="https://cdn.tailwindcss.com"></script>
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
|
|
<style>
|
|
#map { height: 550px; width: 100%; border-radius: 0.75rem; }
|
|
.state-detail-row { display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; }
|
|
.leaflet-popup-content { margin: 8px 12px; }
|
|
.leaflet-popup-content-wrapper { border-radius: 12px; }
|
|
</style>
|
|
</head>
|
|
<body class="bg-slate-50 min-h-screen flex flex-col">
|
|
|
|
<div id="main-nav"></div>
|
|
<div id="poc-banner"></div>
|
|
|
|
<!-- Page Header -->
|
|
<section class="bg-slate-900 text-white pt-24 pb-12 px-4">
|
|
<div class="max-w-7xl mx-auto">
|
|
<h1 class="text-3xl md:text-4xl font-bold mb-3">State-by-State Regulations Map</h1>
|
|
<p class="text-lg text-gray-400 max-w-3xl">Click any state marker to view oversize load permit thresholds, escort requirements, and travel restrictions.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Map Section -->
|
|
<section class="max-w-7xl mx-auto px-4 py-8 w-full">
|
|
<div class="bg-white rounded-2xl shadow-lg p-4">
|
|
<div id="map"></div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Route Checker -->
|
|
<section class="max-w-7xl mx-auto px-4 pb-8">
|
|
<div class="bg-white rounded-2xl shadow-lg p-8">
|
|
<h2 class="text-2xl font-bold text-slate-900 mb-2">Quick Route Checker</h2>
|
|
<p class="text-slate-600 mb-6">Enter your load dimensions and route to see which states require permits and escorts.</p>
|
|
|
|
<div class="grid md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Load Width</label>
|
|
<div class="flex">
|
|
<input type="number" id="rc-width-ft" placeholder="ft" min="0" max="30" class="w-1/2 border border-slate-300 rounded-l-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<input type="number" id="rc-width-in" placeholder="in" min="0" max="11" class="w-1/2 border border-l-0 border-slate-300 rounded-r-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Load Height</label>
|
|
<div class="flex">
|
|
<input type="number" id="rc-height-ft" placeholder="ft" min="0" max="25" class="w-1/2 border border-slate-300 rounded-l-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<input type="number" id="rc-height-in" placeholder="in" min="0" max="11" class="w-1/2 border border-l-0 border-slate-300 rounded-r-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Overall Length</label>
|
|
<div class="flex">
|
|
<input type="number" id="rc-length-ft" placeholder="ft" min="0" max="200" class="w-1/2 border border-slate-300 rounded-l-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<input type="number" id="rc-length-in" placeholder="in" min="0" max="11" class="w-1/2 border border-l-0 border-slate-300 rounded-r-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Gross Weight</label>
|
|
<input type="text" id="rc-weight" placeholder="e.g. 120,000 lbs" class="w-full border border-slate-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="grid md:grid-cols-2 gap-4 mb-6">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Origin State</label>
|
|
<select id="rc-origin" class="w-full border border-slate-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<option value="">Select state...</option>
|
|
</select>
|
|
</div>
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Destination State</label>
|
|
<select id="rc-destination" class="w-full border border-slate-300 rounded-lg px-3 py-2 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<option value="">Select state...</option>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<button onclick="checkRoute()" class="bg-amber-500 hover:bg-amber-600 text-slate-900 font-bold px-6 py-3 rounded-lg transition-colors shadow-md">
|
|
Check Route Requirements
|
|
</button>
|
|
|
|
<div id="route-results" class="mt-6 hidden">
|
|
<!-- Results populated by JS -->
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- State Detail Panel (populated on click) -->
|
|
<section id="state-detail" class="max-w-7xl mx-auto px-4 pb-8 hidden">
|
|
<div class="bg-white rounded-2xl shadow-lg p-8">
|
|
<div class="flex items-center justify-between mb-6">
|
|
<h2 id="state-detail-name" class="text-2xl font-bold text-slate-900"></h2>
|
|
<button onclick="document.getElementById('state-detail').classList.add('hidden')" class="text-slate-400 hover:text-slate-600 text-2xl">×</button>
|
|
</div>
|
|
<div id="state-detail-content">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Equipment Requirements Section (Module 12) -->
|
|
<section id="equipment" class="max-w-7xl mx-auto px-4 pb-8">
|
|
<div class="bg-white rounded-2xl shadow-lg p-8">
|
|
<h2 class="text-2xl font-bold text-slate-900 mb-2">State Equipment Requirements</h2>
|
|
<p class="text-slate-600 mb-6">Equipment your escort vehicle and truck/trailer must carry — varies by state. Select a state to see requirements.</p>
|
|
|
|
<div class="grid md:grid-cols-2 gap-4 mb-6">
|
|
<div>
|
|
<label class="block text-sm font-semibold text-slate-700 mb-1">Select State</label>
|
|
<select id="equip-state" onchange="showEquipment()" class="w-full border border-slate-300 rounded-lg px-4 py-2.5 focus:ring-2 focus:ring-amber-400 focus:border-amber-400 outline-none">
|
|
<option value="">Choose a state...</option>
|
|
</select>
|
|
</div>
|
|
<div class="flex items-end">
|
|
<p class="text-sm text-slate-500">Detailed equipment data available for 12 major trucking states. More coming soon.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="equip-content" class="hidden">
|
|
<!-- Populated by JS -->
|
|
</div>
|
|
|
|
<div id="equip-no-data" class="hidden">
|
|
<div class="bg-slate-50 rounded-xl p-8 text-center">
|
|
<p class="text-slate-500 text-lg mb-2">Equipment data for this state is coming soon.</p>
|
|
<p class="text-slate-400 text-sm">We're actively adding detailed equipment requirements for all 50 states.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div id="main-footer"></div>
|
|
|
|
<script src="/js/api.js"></script>
|
|
<script src="/js/nav.js"></script>
|
|
<script>
|
|
renderNav('regulations');
|
|
renderBanner();
|
|
renderFooter();
|
|
|
|
(async () => {
|
|
const MOCK_STATE_REGULATIONS = await PilotEdge.getRegulations();
|
|
const MOCK_STATE_EQUIPMENT = await PilotEdge.getEquipment();
|
|
|
|
// Initialize map centered on continental US
|
|
const map = L.map('map').setView([39.5, -98.5], 4);
|
|
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
attribution: '© OpenStreetMap contributors',
|
|
maxZoom: 18
|
|
}).addTo(map);
|
|
|
|
// Custom marker icon
|
|
const stateIcon = L.divIcon({
|
|
className: 'custom-marker',
|
|
html: '<div style="background:#f59e0b; color:#0f172a; font-weight:800; font-size:11px; width:32px; height:32px; border-radius:50%; display:flex; align-items:center; justify-content:center; border:2px solid #0f172a; box-shadow:0 2px 6px rgba(0,0,0,0.3); cursor:pointer;" class="state-marker-dot"></div>',
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 16]
|
|
});
|
|
|
|
// Add markers for each state
|
|
MOCK_STATE_REGULATIONS.forEach(state => {
|
|
const marker = L.marker([state.lat, state.lng], {
|
|
icon: L.divIcon({
|
|
className: 'custom-marker',
|
|
html: `<div style="background:#f59e0b; color:#0f172a; font-weight:800; font-size:10px; width:32px; height:32px; border-radius:50%; display:flex; align-items:center; justify-content:center; border:2px solid #0f172a; box-shadow:0 2px 6px rgba(0,0,0,0.3); cursor:pointer;">${state.abbr}</div>`,
|
|
iconSize: [32, 32],
|
|
iconAnchor: [16, 16]
|
|
})
|
|
}).addTo(map);
|
|
|
|
marker.bindPopup(`
|
|
<div style="min-width:200px;">
|
|
<strong style="font-size:16px;">${state.name}</strong><br>
|
|
<span style="color:#666; font-size:12px;">Click below for full details</span><br><br>
|
|
<strong>Permit required over:</strong><br>
|
|
Width: ${state.permitWidth} | Height: ${state.permitHeight}<br>
|
|
<br>
|
|
<button onclick="showStateDetail('${state.abbr}')" style="background:#f59e0b; color:#0f172a; font-weight:700; padding:6px 16px; border-radius:6px; border:none; cursor:pointer; width:100%;">
|
|
View Full Details
|
|
</button>
|
|
</div>
|
|
`);
|
|
});
|
|
|
|
function showStateDetail(abbr) {
|
|
const state = MOCK_STATE_REGULATIONS.find(s => s.abbr === abbr);
|
|
if (!state) return;
|
|
|
|
map.closePopup();
|
|
|
|
document.getElementById('state-detail-name').textContent = `${state.name} (${state.abbr})`;
|
|
document.getElementById('state-detail-content').innerHTML = `
|
|
<div class="grid md:grid-cols-2 gap-8">
|
|
<!-- Permit Thresholds -->
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600 mr-2">📄</span>
|
|
Permit Required Over
|
|
</h3>
|
|
<div class="space-y-3">
|
|
<div class="flex justify-between items-center bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Width</span>
|
|
<span class="font-bold text-slate-900">${state.permitWidth}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Height</span>
|
|
<span class="font-bold text-slate-900">${state.permitHeight}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Length</span>
|
|
<span class="font-bold text-slate-900">${state.permitLength}</span>
|
|
</div>
|
|
<div class="flex justify-between items-center bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Weight</span>
|
|
<span class="font-bold text-slate-900">${state.permitWeight}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Escort Requirements -->
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-amber-100 rounded-lg flex items-center justify-center text-amber-600 mr-2">🚗</span>
|
|
Escort Required Over
|
|
</h3>
|
|
<div class="space-y-3">
|
|
<div class="bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Width:</span>
|
|
<span class="font-semibold text-slate-900 ml-2">${state.escortWidth}</span>
|
|
</div>
|
|
<div class="bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Height:</span>
|
|
<span class="font-semibold text-slate-900 ml-2">${state.escortHeight}</span>
|
|
</div>
|
|
<div class="bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Length:</span>
|
|
<span class="font-semibold text-slate-900 ml-2">${state.escortLength}</span>
|
|
</div>
|
|
<div class="bg-slate-50 px-4 py-2 rounded-lg">
|
|
<span class="text-slate-600 font-medium">Weight:</span>
|
|
<span class="font-semibold text-slate-900 ml-2">${state.escortWeight}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Travel Restrictions -->
|
|
<div class="mt-8 grid md:grid-cols-2 gap-8">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-green-100 rounded-lg flex items-center justify-center text-green-600 mr-2">🕐</span>
|
|
Travel Restrictions
|
|
</h3>
|
|
<div class="bg-slate-50 px-4 py-3 rounded-lg space-y-2">
|
|
<p><span class="font-medium text-slate-600">Hours:</span> <span class="text-slate-900">${state.travel}</span></p>
|
|
<p><span class="font-medium text-slate-600">Holidays:</span> <span class="text-slate-900">${state.holidays}</span></p>
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-purple-100 rounded-lg flex items-center justify-center text-purple-600 mr-2">🏛️</span>
|
|
Permit Agency
|
|
</h3>
|
|
<div class="bg-slate-50 px-4 py-3 rounded-lg space-y-2">
|
|
<p class="font-semibold text-slate-900">${state.agency}</p>
|
|
<a href="${state.url}" target="_blank" class="text-amber-600 hover:text-amber-700 text-sm font-medium">${state.url} ↗</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Notes -->
|
|
<div class="mt-6 bg-amber-50 border border-amber-200 rounded-xl px-6 py-4">
|
|
<p class="text-amber-900"><strong>Notes:</strong> ${state.notes}</p>
|
|
</div>
|
|
`;
|
|
|
|
const detailEl = document.getElementById('state-detail');
|
|
detailEl.classList.remove('hidden');
|
|
detailEl.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
}
|
|
|
|
// Populate route checker dropdowns
|
|
const originSelect = document.getElementById('rc-origin');
|
|
const destSelect = document.getElementById('rc-destination');
|
|
MOCK_STATE_REGULATIONS.forEach(state => {
|
|
originSelect.add(new Option(state.name, state.abbr));
|
|
destSelect.add(new Option(state.name, state.abbr));
|
|
});
|
|
|
|
function checkRoute() {
|
|
const origin = document.getElementById('rc-origin').value;
|
|
const dest = document.getElementById('rc-destination').value;
|
|
const widthFt = parseInt(document.getElementById('rc-width-ft').value) || 0;
|
|
const widthIn = parseInt(document.getElementById('rc-width-in').value) || 0;
|
|
const heightFt = parseInt(document.getElementById('rc-height-ft').value) || 0;
|
|
const heightIn = parseInt(document.getElementById('rc-height-in').value) || 0;
|
|
|
|
if (!origin || !dest) {
|
|
alert('Please select both origin and destination states.');
|
|
return;
|
|
}
|
|
|
|
const resultsDiv = document.getElementById('route-results');
|
|
resultsDiv.classList.remove('hidden');
|
|
|
|
const widthTotal = widthFt + widthIn / 12;
|
|
const heightTotal = heightFt + heightIn / 12;
|
|
|
|
const originState = MOCK_STATE_REGULATIONS.find(s => s.abbr === origin);
|
|
const destState = MOCK_STATE_REGULATIONS.find(s => s.abbr === dest);
|
|
|
|
// For POC, just show origin and destination state requirements
|
|
const states = [originState];
|
|
if (origin !== dest) states.push(destState);
|
|
|
|
let html = `
|
|
<div class="bg-blue-50 border border-blue-200 rounded-xl p-4 mb-4">
|
|
<p class="text-blue-900 font-medium">📍 Route: ${originState.name} → ${destState.name}</p>
|
|
<p class="text-blue-700 text-sm mt-1">Showing requirements for origin and destination states. In production, all transit states would be included.</p>
|
|
</div>
|
|
<div class="space-y-4">
|
|
`;
|
|
|
|
states.forEach(state => {
|
|
const needsPermitW = widthTotal > 8.5;
|
|
const needsPermitH = heightTotal > 13.5;
|
|
const needsEscortW = widthTotal > 14;
|
|
const needsEscortH = heightTotal > 15;
|
|
|
|
html += `
|
|
<div class="border border-slate-200 rounded-xl p-5">
|
|
<div class="flex items-center justify-between mb-3">
|
|
<h4 class="font-bold text-lg text-slate-900">${state.name} (${state.abbr})</h4>
|
|
<div class="flex gap-2">
|
|
${needsPermitW || needsPermitH ? '<span class="bg-blue-100 text-blue-800 text-xs font-bold px-3 py-1 rounded-full">PERMIT NEEDED</span>' : '<span class="bg-green-100 text-green-800 text-xs font-bold px-3 py-1 rounded-full">NO PERMIT</span>'}
|
|
${needsEscortW || needsEscortH ? '<span class="bg-amber-100 text-amber-800 text-xs font-bold px-3 py-1 rounded-full">ESCORT NEEDED</span>' : ''}
|
|
</div>
|
|
</div>
|
|
<div class="grid grid-cols-2 gap-2 text-sm">
|
|
<p><span class="text-slate-500">Permit over:</span> W ${state.permitWidth} / H ${state.permitHeight}</p>
|
|
<p><span class="text-slate-500">Escort over:</span> W ${state.escortWidth.split(';')[0]}</p>
|
|
<p><span class="text-slate-500">Travel:</span> ${state.travel}</p>
|
|
<p><span class="text-slate-500">Agency:</span> ${state.agency}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
});
|
|
|
|
html += '</div>';
|
|
resultsDiv.innerHTML = html;
|
|
}
|
|
|
|
// Equipment Requirements (Module 12)
|
|
const equipSelect = document.getElementById('equip-state');
|
|
MOCK_STATE_REGULATIONS.forEach(state => {
|
|
equipSelect.add(new Option(state.name + ' (' + state.abbr + ')', state.abbr));
|
|
});
|
|
|
|
// Auto-scroll to equipment section if URL has #equipment
|
|
if (window.location.hash === '#equipment') {
|
|
document.getElementById('equipment').scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
|
|
function renderEquipRow(label, value) {
|
|
return `<div class="flex justify-between items-start bg-slate-50 px-4 py-2.5 rounded-lg">
|
|
<span class="text-slate-600 font-medium text-sm flex-shrink-0 mr-4">${label}</span>
|
|
<span class="font-semibold text-slate-900 text-sm text-right">${value}</span>
|
|
</div>`;
|
|
}
|
|
|
|
function showEquipment() {
|
|
const abbr = document.getElementById('equip-state').value;
|
|
const contentDiv = document.getElementById('equip-content');
|
|
const noDataDiv = document.getElementById('equip-no-data');
|
|
|
|
if (!abbr) {
|
|
contentDiv.classList.add('hidden');
|
|
noDataDiv.classList.add('hidden');
|
|
return;
|
|
}
|
|
|
|
const equip = typeof MOCK_STATE_EQUIPMENT !== 'undefined' ? MOCK_STATE_EQUIPMENT[abbr] : null;
|
|
|
|
if (!equip) {
|
|
contentDiv.classList.add('hidden');
|
|
noDataDiv.classList.remove('hidden');
|
|
return;
|
|
}
|
|
|
|
noDataDiv.classList.add('hidden');
|
|
contentDiv.classList.remove('hidden');
|
|
|
|
const e = equip.escort;
|
|
const c = equip.carrier;
|
|
|
|
contentDiv.innerHTML = `
|
|
<div class="grid md:grid-cols-2 gap-8">
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-amber-100 rounded-lg flex items-center justify-center text-amber-600 mr-2">🚗</span>
|
|
Escort Vehicle Requirements
|
|
</h3>
|
|
<div class="space-y-2">
|
|
${renderEquipRow('Certification', e.certification)}
|
|
${renderEquipRow('Vehicle', e.vehicle)}
|
|
${renderEquipRow('Signs', e.signs)}
|
|
${renderEquipRow('Lights', e.lights)}
|
|
${renderEquipRow('Height Pole', e.heightPole)}
|
|
${renderEquipRow('Flags', e.flags)}
|
|
${renderEquipRow('Communication', e.communication)}
|
|
${renderEquipRow('Safety Gear', e.safety)}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<h3 class="text-lg font-bold text-slate-900 mb-4 flex items-center">
|
|
<span class="w-8 h-8 bg-blue-100 rounded-lg flex items-center justify-center text-blue-600 mr-2">🚛</span>
|
|
Truck & Trailer Requirements
|
|
</h3>
|
|
<div class="space-y-2">
|
|
${renderEquipRow('OVERSIZE LOAD Signs', c.signs)}
|
|
${renderEquipRow('Flags', c.flags)}
|
|
${renderEquipRow('Warning Lights', c.lights)}
|
|
${renderEquipRow('Traffic Cones', c.cones)}
|
|
${renderEquipRow('Fire Extinguisher', c.fireExtinguisher)}
|
|
${renderEquipRow('Reflective Triangles', c.triangles)}
|
|
${renderEquipRow('Road Flares', c.flares)}
|
|
${renderEquipRow('First Aid Kit', c.firstAid)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
})();
|
|
</script>
|
|
</body>
|
|
</html>
|