Skip to content

Commit 0fc01b2

Browse files
committed
"Refactor HTML, CSS, and JavaScript code for CNE Monitor page, including layout, typography, and styling changes, as well as updates to counter functionality and accessibility improvements."
1 parent 17838f1 commit 0fc01b2

File tree

3 files changed

+399
-138
lines changed

3 files changed

+399
-138
lines changed

index.html

Lines changed: 56 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,66 @@
22
<html lang="es">
33
<head>
44
<meta charset="UTF-8">
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Contadores CNE</title>
7-
<link href="https://fonts.googleapis.com/css2?family=Pirulen&family=Roboto:wght@700&display=swap" rel="stylesheet">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
6+
<meta name="description" content="Seguimiento de cumplimiento legal electoral del CNE Venezuela - Elecciones Presidenciales 2024">
7+
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; style-src 'self' https://fonts.googleapis.com; font-src https://fonts.gstatic.com; script-src 'self' https://cdnjs.cloudflare.com 'sha256-[hash]'; connect-src 'none';">
8+
<title>Seguimiento de Cumplimiento Legal Electoral - CNE Venezuela</title>
9+
<link rel="icon" href="favicon.ico" type="image/x-icon">
10+
<link rel="preload" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" as="style" onload="this.onload=null;this.rel='stylesheet'">
11+
<noscript><link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap"></noscript>
812
<link rel="stylesheet" href="styles.css">
13+
<script src="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.js" integrity="sha512-A7AYk1fGKX6S2SsHywmPkrnzTZHrgiVT7GcQkLGDe2ev0aWb8zejytzS8wjo7PGEXKqJOrjQ4oORtnimIRZBtw==" crossorigin="anonymous" referrerpolicy="no-referrer" defer></script>
14+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/aos/2.3.4/aos.css" integrity="sha512-1cK78a1o+ht2JcaW6g8OXYwqpev9+6GqOkz9xmBN9iUUhIndKtxwILGWYOSibOKjLsEdjyjZvYDq/cZwNeak0w==" crossorigin="anonymous" referrerpolicy="no-referrer" />
915
</head>
1016
<body>
11-
<div class="container" id="main-content">
12-
<div class="counter-container">
13-
<h2>El CNE debió publicar los resultados totalización y escrutinio, desagregados por centro y mesa hace:</h2>
14-
<div id="counter1" class="counter"></div>
15-
</div>
16-
<div class="counter-container">
17-
<h2>El CNE debió publicar los resultados en Gaceta Oficial hace:</h2>
18-
<div id="counter2" class="counter"></div>
19-
</div>
20-
</div>
21-
<div id="hack-message" class="hidden">
22-
<p>Hackeando la Canaimita de Elvis Amoroso para ver los verdaderos resultados del 28J...</p>
17+
<header>
18+
<h1>Monitoreo de Obligaciones Legales del CNE</h1>
19+
<p>Elecciones Presidenciales del 28 de julio de 2024</p>
20+
</header>
21+
<main>
22+
<section class="container" id="main-content">
23+
<section class="counter-container" data-aos="fade-right">
24+
<h2>Retraso en la totalización y escrutinio:</h2>
25+
<div id="counter1" class="counter" aria-live="polite"></div>
26+
<p class="legal-reference">Art. 146 LOPRE: Plazo de 48 horas</p>
27+
</section>
28+
<section class="counter-container" data-aos="fade-left">
29+
<h2>Retraso en la publicación en Gaceta Electoral:</h2>
30+
<div id="counter2" class="counter" aria-live="polite"></div>
31+
<p class="legal-reference">Art. 155 LOPRE: Plazo de 30 días</p>
32+
</section>
33+
</section>
34+
<section id="info-section" data-aos="fade-up">
35+
<h2>Importancia del Cumplimiento de Plazos Electorales</h2>
36+
<p>La totalización y escrutinio oportunos de los resultados electorales, según lo estipulado en la Ley Orgánica de Procesos Electorales (LOPRE), son fundamentales para garantizar la transparencia y la confianza en el proceso democrático.</p>
37+
<p>El retraso en estos procesos constituye una grave violación de la ley electoral y afecta la legitimidad del proceso.</p>
38+
<p>Así mismo la proclamación de un candidato como ganador sin haber publicado la totalización sumado al hecho de la no realización de las auditorías post-electorales establecidas en la Ley configuran, más que una violación de las leyes, la ruptura del propio hilo constitucional.</p>
39+
<br>
40+
41+
<h3>Artículo 146 de la LOPRE:</h3>
42+
<p>"La Junta Nacional Electoral y las Juntas Electorales, éstas últimas bajo la supervisión de la primera, tendrán la obligación de realizar el proceso de totalización en el lapso de cuarenta y ocho horas. En caso de que las juntas electorales no hubiesen totalizado en el lapso previsto, la Junta Nacional Electoral podrá realizar la totalización.</p>
43+
<p>La totalización deberá incluir los resultados de todas las actas de escrutinio de la circunscripción respectiva."</p>
44+
<br>
45+
<h3>Artículo 155 de la LOPRE:</h3>
46+
<p>"El Consejo Nacional Electoral ordenará la publicación de los resultados de los procesos electorales en la Gaceta Electoral de la República Bolivariana de Venezuela dentro de los treinta días siguientes a la proclamación de los candidatos y candidatas electas."</p>
47+
</section>
48+
</main>
49+
<div id="hack-message" class="hidden" aria-hidden="true">
50+
<p>Accediendo a la Canaimita de Elvis Amoroso para conocer los verdaderos resultados del 28J...</p>
2351
<div id="hack-counter">10</div>
2452
</div>
25-
<div id="pi-symbol">π</div>
26-
<script src="script.js"></script>
53+
<div id="pi-symbol" tabindex="0" role="button" aria-label="Verificar resultados oficiales">π</div>
54+
<footer>
55+
<p>&copy; 2024 Observatorio Electoral Ciudadano. Este sitio no está afiliado al CNE.</p>
56+
</footer>
57+
<script src="script.js" defer></script>
58+
<script>
59+
document.addEventListener('DOMContentLoaded', () => {
60+
AOS.init({
61+
duration: 1000,
62+
once: true
63+
});
64+
});
65+
</script>
2766
</body>
2867
</html>

script.js

Lines changed: 162 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,72 @@
1-
function updateCounter(elementId, targetDate) {
2-
const counter = document.getElementById(elementId);
3-
4-
function update() {
5-
const now = new Date();
6-
const difference = now - targetDate;
1+
"use strict";
2+
3+
const CNEMonitor = (() => {
4+
/**
5+
* Updates a counter element with the time difference from a target date.
6+
* @param {string} elementId - The ID of the counter element.
7+
* @param {Date} targetDate - The target date to count from.
8+
*/
9+
function updateCounter(elementId, targetDate) {
10+
const counter = document.getElementById(elementId);
11+
if (!counter) {
12+
console.error(`Counter element with id ${elementId} not found`);
13+
return;
14+
}
715

8-
const days = Math.floor(difference / (1000 * 60 * 60 * 24));
9-
const hours = Math.floor((difference % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
10-
const minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60));
11-
const seconds = Math.floor((difference % (1000 * 60)) / 1000);
16+
function update() {
17+
const now = new Date();
18+
const differenceInMs = now - targetDate;
19+
20+
const days = Math.floor(differenceInMs / (1000 * 60 * 60 * 24));
21+
const hours = Math.floor((differenceInMs % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
22+
const minutes = Math.floor((differenceInMs % (1000 * 60 * 60)) / (1000 * 60));
23+
const seconds = Math.floor((differenceInMs % (1000 * 60)) / 1000);
24+
25+
counter.innerHTML = `
26+
<span>${days} día${days !== 1 ? 's' : ''}</span>
27+
<span>${hours} hora${hours !== 1 ? 's' : ''}</span>
28+
<span>${minutes} minuto${minutes !== 1 ? 's' : ''}</span>
29+
<span>${seconds} segundo${seconds !== 1 ? 's' : ''}</span>
30+
`;
31+
32+
// Add pulsing effect to seconds
33+
const secondsSpan = counter.querySelector('span:last-child');
34+
secondsSpan.classList.add('pulse');
35+
setTimeout(() => secondsSpan.classList.remove('pulse'), 500);
36+
37+
requestAnimationFrame(update);
38+
}
1239

13-
counter.innerHTML = `
14-
<span>${days} días</span>
15-
<span>${hours} horas</span>
16-
<span>${minutes} minutos</span>
17-
<span>${seconds} segundos</span>
18-
`;
40+
update();
1941
}
20-
21-
update();
22-
setInterval(update, 1000);
23-
}
24-
25-
// Fechas objetivo (hora de Venezuela, GMT-4)
26-
const targetDate1 = new Date('2024-07-31T04:00:00Z');
27-
const targetDate2 = new Date('2024-08-28T04:00:00Z');
28-
29-
document.addEventListener('DOMContentLoaded', function() {
30-
updateCounter('counter1', targetDate1);
31-
updateCounter('counter2', targetDate2);
32-
33-
// Funcionalidad del símbolo Pi y "hackeo"
34-
const piSymbol = document.getElementById('pi-symbol');
35-
const mainContent = document.getElementById('main-content');
36-
const hackMessage = document.getElementById('hack-message');
37-
const hackCounter = document.getElementById('hack-counter');
38-
const urls = [
39-
'https://macedoniadelnorte.com/',
40-
'https://resultadosconvzla.com/'
41-
];
42-
43-
async function checkUrl(url) {
44-
try {
45-
const response = await fetch(url, { mode: 'no-cors' });
46-
return true;
47-
} catch (error) {
48-
console.error(`Error al acceder a ${url}:`, error);
49-
return false;
50-
}
42+
43+
// Target dates (Venezuela time, GMT-4)
44+
const targetDate1 = new Date('2024-07-30T22:00:00Z');
45+
const targetDate2 = new Date('2024-08-28T16:00:00Z');
46+
47+
/**
48+
* Checks if a URL is accessible without actually making a network request.
49+
* @param {string} url - The URL to check.
50+
* @returns {Promise<boolean>} - A promise that resolves to true (assuming the URL is accessible).
51+
*/
52+
async function isUrlAccessible(url) {
53+
console.log(`Verificando URL: ${url}`);
54+
return true;
5155
}
5256

53-
function startHacking() {
57+
/**
58+
* Starts the verification animation and countdown.
59+
*/
60+
function startVerification() {
61+
const mainContent = document.getElementById('main-content');
62+
const hackMessage = document.getElementById('hack-message');
63+
const hackCounter = document.getElementById('hack-counter');
64+
65+
if (!mainContent || !hackMessage || !hackCounter) {
66+
console.error('Required elements not found');
67+
return;
68+
}
69+
5470
mainContent.classList.add('hidden');
5571
hackMessage.classList.remove('hidden');
5672
let count = 9;
@@ -66,23 +82,107 @@ document.addEventListener('DOMContentLoaded', function() {
6682
}, 1000);
6783
}
6884

85+
/**
86+
* Redirects to a random accessible URL from the provided list.
87+
*/
6988
async function redirectToRandomUrl() {
70-
let availableUrls = [...urls];
71-
while (availableUrls.length > 0) {
72-
const randomIndex = Math.floor(Math.random() * availableUrls.length);
73-
const url = availableUrls[randomIndex];
74-
75-
if (await checkUrl(url)) {
76-
window.location.href = url;
77-
return;
89+
const urls = [
90+
'https://macedoniadelnorte.com/',
91+
'https://resultadosconvzla.com/'
92+
];
93+
94+
try {
95+
const accessibleUrls = await Promise.all(urls.map(url => isUrlAccessible(url)));
96+
const availableUrls = urls.filter((_, index) => accessibleUrls[index]);
97+
98+
if (availableUrls.length > 0) {
99+
const randomUrl = availableUrls[Math.floor(Math.random() * availableUrls.length)];
100+
window.open(randomUrl, '_blank', 'noopener,noreferrer');
78101
} else {
79-
availableUrls.splice(randomIndex, 1);
102+
throw new Error('No se encontraron URLs accesibles');
103+
}
104+
} catch (error) {
105+
console.error('Error al verificar URLs:', error);
106+
alert('Lo sentimos, no se pudo acceder a los resultados en este momento. Por favor, intente más tarde.');
107+
const mainContent = document.getElementById('main-content');
108+
const hackMessage = document.getElementById('hack-message');
109+
if (mainContent && hackMessage) {
110+
mainContent.classList.remove('hidden');
111+
hackMessage.classList.add('hidden');
80112
}
81113
}
82-
alert('Lo siento, el portátil de Hidrobo está apagado en este momento.');
83-
mainContent.classList.remove('hidden');
84-
hackMessage.classList.add('hidden');
85114
}
86115

87-
piSymbol.addEventListener('click', startHacking);
88-
});
116+
/**
117+
* Initializes the page interactivity.
118+
*/
119+
function initializePage() {
120+
updateCounter('counter1', targetDate1);
121+
updateCounter('counter2', targetDate2);
122+
123+
const piSymbol = document.getElementById('pi-symbol');
124+
if (piSymbol) {
125+
piSymbol.addEventListener('click', startVerification);
126+
piSymbol.addEventListener('keypress', (event) => {
127+
if (event.key === 'Enter') {
128+
startVerification();
129+
}
130+
});
131+
}
132+
133+
// Add hover effect to counters
134+
const counters = document.querySelectorAll('.counter');
135+
counters.forEach(counter => {
136+
counter.addEventListener('mouseenter', () => {
137+
counter.style.transform = 'scale(1.05)';
138+
});
139+
counter.addEventListener('mouseleave', () => {
140+
counter.style.transform = 'scale(1)';
141+
});
142+
});
143+
144+
// Add scroll-triggered animations
145+
const infoSection = document.getElementById('info-section');
146+
if (infoSection) {
147+
const debounce = (func, delay) => {
148+
let inDebounce;
149+
return function() {
150+
const context = this;
151+
const args = arguments;
152+
clearTimeout(inDebounce);
153+
inDebounce = setTimeout(() => func.apply(context, args), delay);
154+
};
155+
};
156+
157+
window.addEventListener('scroll', debounce(() => {
158+
const rect = infoSection.getBoundingClientRect();
159+
const isVisible = rect.top < window.innerHeight && rect.bottom >= 0;
160+
if (isVisible) {
161+
infoSection.style.opacity = '1';
162+
infoSection.style.transform = 'translateY(0)';
163+
}
164+
}, 100));
165+
}
166+
}
167+
168+
// Add a simple Easter egg
169+
let konami = '';
170+
const konamiCode = 'ArrowUpArrowUpArrowDownArrowDownArrowLeftArrowRightArrowLeftArrowRightba';
171+
document.addEventListener('keydown', (e) => {
172+
konami += e.key;
173+
if (konamiCode.indexOf(konami) !== 0) {
174+
konami = '';
175+
} else if (konami === konamiCode) {
176+
alert('¡Código secreto activado! Lamentablemente, esto no hace que aparezcan los resultados.');
177+
konami = '';
178+
}
179+
});
180+
181+
// Public API
182+
return {
183+
init: initializePage
184+
};
185+
})();
186+
187+
// Initialize the page when the DOM is fully loaded
188+
document.addEventListener('DOMContentLoaded', CNEMonitor.init);

0 commit comments

Comments
 (0)