Add PPE images, assets, and update game scenarios and avatar logic
|
After Width: | Height: | Size: 1.3 MiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 146 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 164 KiB |
|
After Width: | Height: | Size: 152 KiB |
|
After Width: | Height: | Size: 143 KiB |
|
After Width: | Height: | Size: 150 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 148 KiB |
|
After Width: | Height: | Size: 149 KiB |
|
After Width: | Height: | Size: 432 KiB |
@@ -16,7 +16,13 @@
|
||||
<!-- Top Navigation / Header Bar -->
|
||||
<header class="top-bar">
|
||||
<div class="brand-badge">
|
||||
<div class="safety-cross-icon">✚</div>
|
||||
<div class="safety-helmet-icon">
|
||||
<svg viewBox="0 0 36 36" class="helmet-svg">
|
||||
<path d="M 6 22 C 6 12 30 12 30 22 L 34 24 C 34 26 2 26 2 24 Z" fill="#facc15" stroke="#ca8a04" stroke-width="1.5"/>
|
||||
<path d="M 14 11 L 22 11 L 21 23 L 15 23 Z" fill="#eab308"/>
|
||||
<rect x="3" y="23" width="30" height="3" rx="1.5" fill="#ca8a04"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="brand-text">
|
||||
<span class="game-title">PPE SAFETY CHALLENGE</span>
|
||||
<span class="game-tagline">CHOOSE RIGHT. WORK SAFE.</span>
|
||||
@@ -29,7 +35,7 @@
|
||||
<span class="step-num">1</span>
|
||||
<span class="step-label">Grinding Ops</span>
|
||||
</div>
|
||||
<div class="step-connector"></div>
|
||||
<div class="step-dots">·······</div>
|
||||
<div class="step-pill" id="step-pill-2">
|
||||
<span class="step-num">2</span>
|
||||
<span class="step-label">Chemical Handling</span>
|
||||
@@ -41,15 +47,19 @@
|
||||
<div class="score-display">
|
||||
<span class="score-label">SAFETY SCORE</span>
|
||||
<span class="score-val" id="hud-score">0</span>
|
||||
<span class="score-stars" id="hud-stars">☆☆</span>
|
||||
<span class="score-star-icon">★</span>
|
||||
<span class="score-stars-sub" id="hud-stars">☆</span>
|
||||
</div>
|
||||
|
||||
<!-- Audio Controls Menu Trigger -->
|
||||
<button id="btn-audio-settings" class="btn-icon" title="Audio Settings (M)" aria-label="Audio Settings">
|
||||
<span id="audio-icon">🔊</span>
|
||||
<!-- Audio & Settings Controls -->
|
||||
<button id="btn-sound-toggle" class="btn-icon-hud" title="Sound Effects (S)" aria-label="Sound Toggle">
|
||||
<span>🔊</span>
|
||||
</button>
|
||||
<button id="btn-restart" class="btn-icon" title="Restart Game (R)" aria-label="Restart">
|
||||
<span>🔄</span>
|
||||
<button id="btn-music-toggle" class="btn-icon-hud" title="Music Toggle (M)" aria-label="Music Toggle">
|
||||
<span>🎵</span>
|
||||
</button>
|
||||
<button id="btn-audio-settings" class="btn-icon-hud" title="Audio Settings (O)" aria-label="Audio Settings">
|
||||
<span>⚙️</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
@@ -84,7 +94,7 @@
|
||||
<span class="flow-arrow">➔</span>
|
||||
<span class="flow-item">🦺 SELECT PPE</span>
|
||||
<span class="flow-arrow">➔</span>
|
||||
<span class="flow-item">⚙️ TEST SAFETY</span>
|
||||
<span class="flow-item">⚙️ START TASK</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -94,7 +104,7 @@
|
||||
<span class="btn-text">START CHALLENGE</span>
|
||||
</button>
|
||||
<div class="controls-hint">
|
||||
<span>⌨️ Mouse Click or Number Keys (1-8) to equip • Spacebar to Test Task</span>
|
||||
<span>⌨️ Mouse Click or Number Keys (1-9) to equip • Spacebar to Start Task</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,71 +114,90 @@
|
||||
<section id="screen-game" class="screen-view">
|
||||
<div class="gameplay-grid">
|
||||
|
||||
<!-- Left Column: Hazard Assessment & Task Briefing -->
|
||||
<!-- Left Column: Hazard Assessment & Worker Protection Status -->
|
||||
<aside class="sidebar-hazard-panel card-panel">
|
||||
<div class="panel-header">
|
||||
<div class="scenario-badge" id="scene-badge">SCENARIO 1 OF 2</div>
|
||||
<h2 class="scenario-title" id="scene-title">Metal Grinding Operation</h2>
|
||||
</div>
|
||||
|
||||
<div class="situation-card">
|
||||
<div class="card-subtitle">WORKPLACE ENVIRONMENT</div>
|
||||
<h2 class="scenario-title" id="scene-title">Chemical Handling & Dispensing</h2>
|
||||
<p class="situation-desc" id="scene-desc">
|
||||
An industrial worker is preparing to grind weld seams on structural steel with a high-speed angle grinder (11,000 RPM).
|
||||
An employee is transferring an industrial corrosive solvent between approved containers at a ventilated dispensing station.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Identify Hazards Box -->
|
||||
<div class="hazard-identification-card">
|
||||
<div class="card-subtitle">IDENTIFIED TASK HAZARDS</div>
|
||||
<div class="card-subtitle-small">IDENTIFY THE HAZARDS</div>
|
||||
<ul class="hazard-list" id="hazard-list">
|
||||
<!-- Dynamically populated -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="equipped-status-card">
|
||||
<div class="card-subtitle">PROTECTION COVERAGE</div>
|
||||
<div class="coverage-grid" id="coverage-grid">
|
||||
<div class="coverage-item" data-slot="head">
|
||||
<span class="cov-icon">🧢</span>
|
||||
<span class="cov-label">Head</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
<!-- Worker Protection Status with Wireframe Silhouette -->
|
||||
<div class="worker-protection-card">
|
||||
<div class="card-subtitle-small">WORKER PROTECTION STATUS</div>
|
||||
<div class="protection-status-content">
|
||||
<!-- Blue Wireframe Silhouette -->
|
||||
<div class="body-silhouette-box">
|
||||
<svg viewBox="0 0 100 200" class="wireframe-body-svg">
|
||||
<!-- Head -->
|
||||
<circle cx="50" cy="24" r="14" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Neck -->
|
||||
<line x1="50" y1="38" x2="50" y2="46" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Shoulders & Torso -->
|
||||
<path d="M 24 55 L 76 55 L 68 115 L 32 115 Z" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Left Arm -->
|
||||
<path d="M 24 55 L 12 105 L 10 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Right Arm -->
|
||||
<path d="M 76 55 L 88 105 L 90 140" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Left Leg -->
|
||||
<path d="M 38 115 L 34 165 L 32 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Right Leg -->
|
||||
<path d="M 62 115 L 66 165 L 68 195" fill="none" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="coverage-item" data-slot="eyes">
|
||||
<span class="cov-icon">👓</span>
|
||||
<span class="cov-label">Eyes/Face</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
</div>
|
||||
<div class="coverage-item" data-slot="ears">
|
||||
<span class="cov-icon">🎧</span>
|
||||
<span class="cov-label">Hearing</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
</div>
|
||||
<div class="coverage-item" data-slot="hands">
|
||||
<span class="cov-icon">🧤</span>
|
||||
<span class="cov-label">Hands</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
</div>
|
||||
<div class="coverage-item" data-slot="body">
|
||||
<span class="cov-icon">🦺</span>
|
||||
<span class="cov-label">Body</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
</div>
|
||||
<div class="coverage-item" data-slot="feet">
|
||||
<span class="cov-icon">🥾</span>
|
||||
<span class="cov-label">Feet</span>
|
||||
<span class="cov-status missing">Missing</span>
|
||||
|
||||
<!-- Status Rows -->
|
||||
<div class="protection-rows" id="coverage-grid">
|
||||
<div class="status-row-item" data-slot="head">
|
||||
<span class="row-icon">🧢</span>
|
||||
<span class="row-label">Head</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
<div class="status-row-item" data-slot="eyes">
|
||||
<span class="row-icon">👓</span>
|
||||
<span class="row-label">Eyes / Face</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
<div class="status-row-item" data-slot="ears">
|
||||
<span class="row-icon">🎧</span>
|
||||
<span class="row-label">Hearing</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
<div class="status-row-item" data-slot="hands">
|
||||
<span class="row-icon">🧤</span>
|
||||
<span class="row-label">Hands</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
<div class="status-row-item" data-slot="body">
|
||||
<span class="row-icon">🦺</span>
|
||||
<span class="row-label">Body</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
<div class="status-row-item" data-slot="feet">
|
||||
<span class="row-icon">🥾</span>
|
||||
<span class="row-label">Feet</span>
|
||||
<span class="row-badge status-q">?</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="action-dock">
|
||||
<button id="btn-test-safety" class="btn btn-action btn-full glow-ready">
|
||||
<span class="btn-icon">⚡</span>
|
||||
<span id="btn-test-safety-text">TEST WORKER SAFETY & START</span>
|
||||
</button>
|
||||
<button id="btn-clear-ppe" class="btn btn-ghost btn-small">
|
||||
<span>↺ Clear All Equipped Items</span>
|
||||
</button>
|
||||
<!-- Tip Box -->
|
||||
<div class="tip-card">
|
||||
<div class="tip-title">💡 TIP</div>
|
||||
<p class="tip-text" id="locker-guide-text">
|
||||
Observe the scene, identify the hazards and select the correct PPE before starting the task.
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
@@ -180,12 +209,7 @@
|
||||
|
||||
<!-- Dynamic Background Scenery Layer -->
|
||||
<div class="scene-backdrop" id="scene-backdrop">
|
||||
<div class="industrial-wall"></div>
|
||||
<div class="workbench">
|
||||
<div class="workpiece-element" id="workpiece-element"></div>
|
||||
<div class="equipment-element" id="equipment-element"></div>
|
||||
</div>
|
||||
<div class="warning-tape"></div>
|
||||
<!-- Dynamically populated based on scenario -->
|
||||
</div>
|
||||
|
||||
<!-- Worker Avatar Interactive SVG Layer -->
|
||||
@@ -239,35 +263,35 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Task Status Indicator -->
|
||||
<div class="stage-footer-bar">
|
||||
<div class="status-indicator-light" id="status-light">
|
||||
<span class="light-dot"></span>
|
||||
<span class="light-text" id="status-text">TASK IDLE - EQUIP PPE AND CLICK TEST</span>
|
||||
</div>
|
||||
<div class="audio-feedback-caption" id="audio-caption">
|
||||
[Audio: Workshop Ambience Active]
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Right Column: PPE Selection Locker / Tool Rack -->
|
||||
<!-- Right Column: PPE Selection Locker (3x3 Grid) & Action Buttons -->
|
||||
<aside class="sidebar-locker-panel card-panel">
|
||||
<div class="panel-header">
|
||||
<h3 class="locker-title">🦺 PPE SAFETY LOCKER</h3>
|
||||
<span class="locker-subtitle">Select correct gear for this task:</span>
|
||||
<div class="panel-header-locker">
|
||||
<div class="locker-title-row">
|
||||
<span class="locker-icon">🦺</span>
|
||||
<h3 class="locker-title">PPE SAFETY LOCKER</h3>
|
||||
</div>
|
||||
<p class="locker-subtitle">Select and equip the correct PPE for this task.</p>
|
||||
<p class="locker-instruction">Click an item to equip on the worker.</p>
|
||||
</div>
|
||||
|
||||
<!-- 3x3 Equipment Grid -->
|
||||
<div class="ppe-locker-grid" id="ppe-locker-grid">
|
||||
<!-- Dynamically populated based on scenario -->
|
||||
<!-- Dynamically populated based on scenario (9 items in 3 columns) -->
|
||||
</div>
|
||||
|
||||
<div class="locker-guide-card">
|
||||
<div class="guide-title">💡 Safety Selection Rule</div>
|
||||
<p class="guide-text" id="locker-guide-text">
|
||||
Some gear offers insufficient protection or introduces new hazards. Choose specifically rated items!
|
||||
</p>
|
||||
<!-- Locker Action Buttons -->
|
||||
<div class="locker-actions-dock">
|
||||
<button id="btn-check-ppe" class="btn btn-check-ppe">
|
||||
<span class="btn-check-icon">✓</span>
|
||||
<span>CHECK MY PPE</span>
|
||||
</button>
|
||||
|
||||
<button id="btn-test-safety" class="btn btn-start-task glow-ready">
|
||||
<span class="btn-play-icon">▶</span>
|
||||
<span id="btn-test-safety-text">START TASK</span>
|
||||
</button>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/**
|
||||
* PPE SAFETY CHALLENGE - DYNAMIC WORKER AVATAR SYSTEM
|
||||
* Generates an SVG industrial worker avatar with modular layered PPE gear.
|
||||
* PPE SAFETY CHALLENGE - DYNAMIC 2D WORKER AVATAR SYSTEM
|
||||
* Uses the step-by-step transparent character images from ppe_character_steps_transparent_png!
|
||||
* Dynamically switches character states as safety gear is equipped.
|
||||
*/
|
||||
|
||||
class WorkerAvatar {
|
||||
@@ -30,7 +31,7 @@ class WorkerAvatar {
|
||||
}
|
||||
|
||||
getAvatarCenterCoordinates() {
|
||||
if (!this.container) return { x: 150, y: 200, eyeX: 140, eyeY: 100, handX: 190, handY: 220 };
|
||||
if (!this.container) return { x: 170, y: 220, eyeX: 170, eyeY: 110, handX: 230, handY: 260 };
|
||||
const rect = this.container.getBoundingClientRect();
|
||||
const parentRect = this.container.parentElement.getBoundingClientRect();
|
||||
const relX = rect.left - parentRect.left + (rect.width * 0.5);
|
||||
@@ -38,260 +39,94 @@ class WorkerAvatar {
|
||||
return {
|
||||
x: relX,
|
||||
y: relY,
|
||||
eyeX: relX - 10,
|
||||
eyeY: relY - 110,
|
||||
handX: relX + 45,
|
||||
handY: relY + 15
|
||||
eyeX: relX,
|
||||
eyeY: relY - 130,
|
||||
handX: relX + 55,
|
||||
handY: relY + 30
|
||||
};
|
||||
}
|
||||
|
||||
getStepImagePath() {
|
||||
const hasHelmet = this.equippedItems.has('safety_helmet_grind') || this.equippedItems.has('safety_helmet_chem');
|
||||
const hasGoggles = this.equippedItems.has('chem_splash_goggles') || this.equippedItems.has('safety_goggles_grind');
|
||||
const hasFaceShield = this.equippedItems.has('face_shield_grind') || this.equippedItems.has('face_shield_chem');
|
||||
const hasHearing = this.equippedItems.has('hearing_protection_grind') || this.equippedItems.has('hearing_protection_chem');
|
||||
const hasLeatherGloves = this.equippedItems.has('leather_grinding_gloves');
|
||||
const hasWorkGloves = this.equippedItems.has('work_gloves_grind') || this.equippedItems.has('standard_work_gloves');
|
||||
const hasChemGloves = this.equippedItems.has('chem_resistant_gloves');
|
||||
const hasVest = this.equippedItems.has('reflective_vest_grind');
|
||||
const hasApron = this.equippedItems.has('chem_resistant_apron');
|
||||
const hasCottonCoat = this.equippedItems.has('cotton_coat_chem');
|
||||
const hasBoots = this.equippedItems.has('steel_toe_boots_grind') || this.equippedItems.has('chem_safety_shoes');
|
||||
const hasMask = this.equippedItems.has('dust_mask_grind');
|
||||
|
||||
// 10. Full PPE with Mask
|
||||
if (hasMask) {
|
||||
return 'images/steps/10_full_ppe_with_mask.png';
|
||||
}
|
||||
|
||||
// 9. Full Grinding Set with Boots
|
||||
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasBoots)) {
|
||||
return 'images/steps/09_helmet_goggles_hearing_leather_gloves_vest_boots.png';
|
||||
}
|
||||
|
||||
// 8. With Vest / Body Wear
|
||||
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves) && (hasVest || hasApron || hasCottonCoat)) {
|
||||
return 'images/steps/08_helmet_goggles_hearing_leather_gloves_vest.png';
|
||||
}
|
||||
|
||||
// 7. With Leather / Chem Gloves
|
||||
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && (hasLeatherGloves || hasChemGloves)) {
|
||||
return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png';
|
||||
}
|
||||
|
||||
// 6. With Work Gloves
|
||||
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing && hasWorkGloves) {
|
||||
return 'images/steps/06_helmet_goggles_hearing_work_gloves.png';
|
||||
}
|
||||
|
||||
// 5. With Earmuffs / Hearing Protection
|
||||
if (hasHelmet && (hasGoggles || hasFaceShield) && hasHearing) {
|
||||
return 'images/steps/05_helmet_goggles_hearing.png';
|
||||
}
|
||||
|
||||
// 4. With Face Shield
|
||||
if (hasFaceShield || (hasHelmet && hasFaceShield)) {
|
||||
return 'images/steps/04_helmet_goggles_face_shield.png';
|
||||
}
|
||||
|
||||
// 3. With Goggles & Helmet
|
||||
if (hasHelmet && hasGoggles) {
|
||||
return 'images/steps/03_helmet_goggles.png';
|
||||
}
|
||||
|
||||
// 2. Helmet Only
|
||||
if (hasHelmet) {
|
||||
return 'images/steps/02_helmet.png';
|
||||
}
|
||||
|
||||
// Individual items
|
||||
if (hasFaceShield) return 'images/steps/04_helmet_goggles_face_shield.png';
|
||||
if (hasGoggles) return 'images/steps/03_helmet_goggles.png';
|
||||
if (hasHearing) return 'images/steps/05_helmet_goggles_hearing.png';
|
||||
if (hasLeatherGloves) return 'images/steps/07_helmet_goggles_hearing_leather_gloves.png';
|
||||
if (hasWorkGloves) return 'images/steps/06_helmet_goggles_hearing_work_gloves.png';
|
||||
|
||||
// 1. Base Worker (No PPE)
|
||||
return 'images/steps/01_no_ppe.png';
|
||||
}
|
||||
|
||||
render() {
|
||||
if (!this.container) return;
|
||||
|
||||
this.container.innerHTML = `
|
||||
<svg viewBox="0 0 300 450" class="worker-svg" id="worker-avatar-svg" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<linearGradient id="skinGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#f6d5b8"/>
|
||||
<stop offset="100%" stop-color="#e2b792"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="hairGrad" x1="0%" y1="0%" x2="0%" y2="100%">
|
||||
<stop offset="0%" stop-color="#3b291d"/>
|
||||
<stop offset="100%" stop-color="#24180f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="baseSuitGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#2c3e50"/>
|
||||
<stop offset="100%" stop-color="#1a252f"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="leatherGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#a0522d"/>
|
||||
<stop offset="100%" stop-color="#723616"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="nitrileGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0284c7"/>
|
||||
<stop offset="100%" stop-color="#0369a1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="visorGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="rgba(14, 165, 233, 0.4)"/>
|
||||
<stop offset="100%" stop-color="rgba(2, 132, 199, 0.6)"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="chemicalApronGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#059669"/>
|
||||
<stop offset="100%" stop-color="#047857"/>
|
||||
</linearGradient>
|
||||
<filter id="gearGlow" x="-20%" y="-20%" width="140%" height="140%">
|
||||
<feDropShadow dx="0" dy="2" stdDeviation="3" flood-color="#facc15" flood-opacity="0.35"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<div class="avatar-step-container" id="avatar-step-container">
|
||||
<!-- Floor Contact Shadow -->
|
||||
<div class="avatar-floor-shadow"></div>
|
||||
|
||||
<!-- Shadow on floor -->
|
||||
<ellipse cx="150" cy="425" rx="75" ry="12" fill="rgba(0,0,0,0.4)"/>
|
||||
|
||||
<!-- LAYER: BASE WORKER BODY -->
|
||||
<g id="layer-base-body">
|
||||
<!-- Legs / Basic Work Trousers -->
|
||||
<path d="M 120 230 L 110 375 L 138 375 L 146 250 L 154 250 L 162 375 L 190 375 L 180 230 Z" fill="#1e293b"/>
|
||||
|
||||
<!-- Feet (Base work shoes) -->
|
||||
<g id="layer-feet-base">
|
||||
<path d="M 105 375 L 140 375 L 142 395 L 98 395 Z" fill="#334155"/>
|
||||
<path d="M 160 375 L 195 375 L 202 395 L 158 395 Z" fill="#334155"/>
|
||||
</g>
|
||||
|
||||
<!-- Torso (Base blue industrial shirt) -->
|
||||
<path d="M 110 140 C 110 130 190 130 190 140 L 196 235 C 196 240 104 240 104 235 Z" fill="url(#baseSuitGrad)"/>
|
||||
|
||||
<!-- Arms (Base) -->
|
||||
<path d="M 110 140 L 80 215 L 98 222 L 122 160 Z" fill="url(#baseSuitGrad)"/>
|
||||
<path d="M 190 140 L 220 215 L 202 222 L 178 160 Z" fill="url(#baseSuitGrad)"/>
|
||||
|
||||
<!-- Forearms (Skin) -->
|
||||
<path d="M 80 215 L 70 260 L 84 262 L 98 222 Z" fill="url(#skinGrad)"/>
|
||||
<path d="M 220 215 L 230 260 L 216 262 L 202 222 Z" fill="url(#skinGrad)"/>
|
||||
|
||||
<!-- Hands (Skin - Bare) -->
|
||||
<g id="layer-hands-bare">
|
||||
<ellipse cx="74" cy="272" rx="10" ry="14" fill="url(#skinGrad)"/>
|
||||
<ellipse cx="226" cy="272" rx="10" ry="14" fill="url(#skinGrad)"/>
|
||||
</g>
|
||||
|
||||
<!-- Neck -->
|
||||
<rect x="138" y="115" width="24" height="25" rx="4" fill="url(#skinGrad)"/>
|
||||
|
||||
<!-- Head -->
|
||||
<ellipse cx="150" cy="95" rx="28" ry="34" fill="url(#skinGrad)"/>
|
||||
|
||||
<!-- Hair Base -->
|
||||
<path d="M 122 90 C 122 65 178 65 178 90 C 178 72 165 62 150 62 C 135 62 122 72 122 90 Z" fill="url(#hairGrad)"/>
|
||||
|
||||
<!-- Eyes & Eyebrows -->
|
||||
<ellipse cx="140" cy="94" rx="3.5" ry="3" fill="#1e293b"/>
|
||||
<ellipse cx="160" cy="94" rx="3.5" ry="3" fill="#1e293b"/>
|
||||
<path d="M 134 88 Q 140 85 146 88" stroke="#3b291d" stroke-width="2" fill="none"/>
|
||||
<path d="M 154 88 Q 160 85 166 88" stroke="#3b291d" stroke-width="2" fill="none"/>
|
||||
|
||||
<!-- Nose & Mouth -->
|
||||
<path d="M 150 96 L 147 106 L 153 106" stroke="#c08c65" stroke-width="1.5" fill="none"/>
|
||||
<path d="M 143 116 Q 150 120 157 116" stroke="#b45309" stroke-width="2" fill="none"/>
|
||||
|
||||
<!-- Ears -->
|
||||
<ellipse cx="121" cy="96" rx="4" ry="7" fill="url(#skinGrad)"/>
|
||||
<ellipse cx="179" cy="96" rx="4" ry="7" fill="url(#skinGrad)"/>
|
||||
</g>
|
||||
|
||||
<!-- ====================================================
|
||||
EQUIPMENT LAYERS (Toggled by class or visibility)
|
||||
==================================================== -->
|
||||
|
||||
<!-- 1. HEAD GEAR -->
|
||||
<!-- Hard Hat (Grinding / General) -->
|
||||
<g id="layer-gear-hard_hat_cap" style="display: none;">
|
||||
<path d="M 115 82 C 115 48 185 48 185 82 L 195 86 C 195 90 105 90 105 86 Z" fill="#facc15" stroke="#ca8a04" stroke-width="2"/>
|
||||
<path d="M 144 48 L 156 48 L 154 85 L 146 85 Z" fill="#eab308"/>
|
||||
</g>
|
||||
|
||||
<!-- Hard Hat (Chemical) -->
|
||||
<g id="layer-gear-hard_hat_chemical" style="display: none;">
|
||||
<path d="M 115 82 C 115 48 185 48 185 82 L 195 86 C 195 90 105 90 105 86 Z" fill="#f8fafc" stroke="#94a3b8" stroke-width="2"/>
|
||||
<path d="M 144 48 L 156 48 L 154 85 L 146 85 Z" fill="#cbd5e1"/>
|
||||
</g>
|
||||
|
||||
<!-- 2. HEARING / RESPIRATORY GEAR -->
|
||||
<!-- Heavy Ear Muffs -->
|
||||
<g id="layer-gear-earmuffs_heavy" style="display: none;">
|
||||
<path d="M 116 80 C 116 45 184 45 184 80" stroke="#dc2626" stroke-width="5" fill="none"/>
|
||||
<rect x="114" y="86" width="10" height="22" rx="4" fill="#ef4444" stroke="#991b1b" stroke-width="1.5"/>
|
||||
<rect x="176" y="86" width="10" height="22" rx="4" fill="#ef4444" stroke="#991b1b" stroke-width="1.5"/>
|
||||
</g>
|
||||
|
||||
<!-- Consumer Earbuds (Distractor) -->
|
||||
<g id="layer-gear-wireless_earbuds" style="display: none;">
|
||||
<ellipse cx="122" cy="98" rx="2" ry="3" fill="#ffffff"/>
|
||||
<ellipse cx="178" cy="98" rx="2" ry="3" fill="#ffffff"/>
|
||||
<line x1="122" y1="98" x2="122" y2="108" stroke="#ffffff" stroke-width="1.5"/>
|
||||
<line x1="178" y1="98" x2="178" y2="108" stroke="#ffffff" stroke-width="1.5"/>
|
||||
</g>
|
||||
|
||||
<!-- Organic Vapor Half-Mask Respirator -->
|
||||
<g id="layer-gear-organic_vapor_respirator" style="display: none;">
|
||||
<path d="M 136 102 L 164 102 L 160 126 L 140 126 Z" fill="#475569" stroke="#1e293b" stroke-width="1.5"/>
|
||||
<!-- Cartridge canisters on sides -->
|
||||
<ellipse cx="132" cy="115" rx="7" ry="9" fill="#0284c7" stroke="#0369a1" stroke-width="1.5"/>
|
||||
<ellipse cx="168" cy="115" rx="7" ry="9" fill="#0284c7" stroke="#0369a1" stroke-width="1.5"/>
|
||||
<!-- Straps -->
|
||||
<line x1="136" y1="104" x2="122" y2="92" stroke="#334155" stroke-width="2"/>
|
||||
<line x1="164" y1="104" x2="178" y2="92" stroke="#334155" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<!-- Cloth Dust Mask (Distractor) -->
|
||||
<g id="layer-gear-cloth_dust_mask" style="display: none;">
|
||||
<path d="M 134 102 C 134 102 150 100 166 102 L 160 125 C 150 128 150 128 140 125 Z" fill="#93c5fd" stroke="#60a5fa" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- 3. EYE & FACE GEAR -->
|
||||
<!-- Face Shield + Safety Glasses (Grinding) -->
|
||||
<g id="layer-gear-faceshield_glasses" style="display: none;">
|
||||
<!-- Dual Glasses underneath -->
|
||||
<rect x="130" y="88" width="18" height="12" rx="3" fill="rgba(6, 182, 212, 0.3)" stroke="#0891b2" stroke-width="2"/>
|
||||
<rect x="152" y="88" width="18" height="12" rx="3" fill="rgba(6, 182, 212, 0.3)" stroke="#0891b2" stroke-width="2"/>
|
||||
<line x1="148" y1="92" x2="152" y2="92" stroke="#0891b2" stroke-width="2"/>
|
||||
<!-- Full Clear Curved Visor Overlay -->
|
||||
<path d="M 112 78 L 188 78 L 182 135 C 182 142 118 142 118 135 Z" fill="url(#visorGrad)" stroke="#38bdf8" stroke-width="2" opacity="0.85"/>
|
||||
<!-- Brow guard -->
|
||||
<path d="M 112 76 L 188 76 L 186 82 L 114 82 Z" fill="#0369a1"/>
|
||||
</g>
|
||||
|
||||
<!-- Chemical Splash Goggles -->
|
||||
<g id="layer-gear-chemical_splash_goggles" style="display: none;">
|
||||
<path d="M 124 86 C 124 86 150 84 176 86 L 174 104 C 150 106 150 106 126 104 Z" fill="rgba(16, 185, 129, 0.35)" stroke="#059669" stroke-width="2.5"/>
|
||||
<ellipse cx="138" cy="94" rx="10" ry="7" fill="none" stroke="#10b981" stroke-width="2"/>
|
||||
<ellipse cx="162" cy="94" rx="10" ry="7" fill="none" stroke="#10b981" stroke-width="2"/>
|
||||
<line x1="124" y1="94" x2="120" y2="94" stroke="#065f46" stroke-width="3"/>
|
||||
<line x1="176" y1="94" x2="180" y2="94" stroke="#065f46" stroke-width="3"/>
|
||||
</g>
|
||||
|
||||
<!-- Standard Sunglasses (Distractor) -->
|
||||
<g id="layer-gear-regular_sunglasses" style="display: none;">
|
||||
<rect x="130" y="90" width="18" height="10" rx="2" fill="#111827" stroke="#000" stroke-width="2"/>
|
||||
<rect x="152" y="90" width="18" height="10" rx="2" fill="#111827" stroke="#000" stroke-width="2"/>
|
||||
<line x1="148" y1="93" x2="152" y2="93" stroke="#000" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<!-- Open Safety Glasses (Distractor in Chemical) -->
|
||||
<g id="layer-gear-standard_safety_glasses" style="display: none;">
|
||||
<rect x="130" y="90" width="18" height="10" rx="2" fill="rgba(255,255,255,0.4)" stroke="#64748b" stroke-width="1.5"/>
|
||||
<rect x="152" y="90" width="18" height="10" rx="2" fill="rgba(255,255,255,0.4)" stroke="#64748b" stroke-width="1.5"/>
|
||||
</g>
|
||||
|
||||
<!-- 4. BODY PROTECTION -->
|
||||
<!-- Heavy Leather Grinding Jacket -->
|
||||
<g id="layer-gear-heavy_leather_jacket" style="display: none;">
|
||||
<path d="M 104 136 C 104 126 196 126 196 136 L 202 240 L 98 240 Z" fill="url(#leatherGrad)" stroke="#57260d" stroke-width="2"/>
|
||||
<!-- Leather Sleeves -->
|
||||
<path d="M 106 138 L 72 248 L 94 252 L 122 160 Z" fill="url(#leatherGrad)"/>
|
||||
<path d="M 194 138 L 228 248 L 206 252 L 178 160 Z" fill="url(#leatherGrad)"/>
|
||||
<line x1="150" y1="140" x2="150" y2="240" stroke="#451a03" stroke-width="3"/>
|
||||
</g>
|
||||
|
||||
<!-- Chemical-Resistant Apron -->
|
||||
<g id="layer-gear-chemical_resistant_apron" style="display: none;">
|
||||
<path d="M 126 135 L 174 135 L 188 175 L 192 315 L 108 315 L 112 175 Z" fill="url(#chemicalApronGrad)" stroke="#064e3b" stroke-width="2.5"/>
|
||||
<path d="M 130 135 L 138 115 M 170 135 L 162 115" stroke="#047857" stroke-width="3"/>
|
||||
</g>
|
||||
|
||||
<!-- Cotton Lab Coat (Distractor) -->
|
||||
<g id="layer-gear-cotton_lab_coat" style="display: none;">
|
||||
<path d="M 104 136 L 196 136 L 200 300 L 100 300 Z" fill="#f1f5f9" stroke="#cbd5e1" stroke-width="2"/>
|
||||
<line x1="150" y1="136" x2="150" y2="300" stroke="#94a3b8" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<!-- 5. HAND PROTECTION -->
|
||||
<!-- Heavy Leather Grinding Gloves -->
|
||||
<g id="layer-gear-leather_grinding_gloves" style="display: none;">
|
||||
<path d="M 64 250 L 86 252 L 86 288 L 62 284 Z" fill="url(#leatherGrad)" stroke="#57260d" stroke-width="1.5"/>
|
||||
<path d="M 236 250 L 214 252 L 214 288 L 238 284 Z" fill="url(#leatherGrad)" stroke="#57260d" stroke-width="1.5"/>
|
||||
</g>
|
||||
|
||||
<!-- Nitrile Gauntlet Chemical Gloves -->
|
||||
<g id="layer-gear-nitrile_gauntlet_gloves" style="display: none;">
|
||||
<path d="M 62 235 L 88 238 L 86 288 L 60 284 Z" fill="url(#nitrileGrad)" stroke="#0369a1" stroke-width="2"/>
|
||||
<path d="M 238 235 L 212 238 L 214 288 L 240 284 Z" fill="url(#nitrileGrad)" stroke="#0369a1" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
<!-- Thin Latex Gloves (Distractor) -->
|
||||
<g id="layer-gear-thin_latex_gloves" style="display: none;">
|
||||
<ellipse cx="74" cy="272" rx="11" ry="15" fill="#bae6fd" stroke="#38bdf8" stroke-width="1"/>
|
||||
<ellipse cx="226" cy="272" rx="11" ry="15" fill="#bae6fd" stroke="#38bdf8" stroke-width="1"/>
|
||||
</g>
|
||||
|
||||
<!-- Standard Leather Work Gloves (Distractor in Chemical) -->
|
||||
<g id="layer-gear-leather_work_gloves" style="display: none;">
|
||||
<path d="M 64 255 L 86 257 L 86 285 L 62 282 Z" fill="#d97706" stroke="#b45309" stroke-width="1.5"/>
|
||||
<path d="M 236 255 L 214 257 L 214 285 L 238 282 Z" fill="#d97706" stroke="#b45309" stroke-width="1.5"/>
|
||||
</g>
|
||||
|
||||
<!-- 6. FOOT PROTECTION -->
|
||||
<!-- Steel-Toe Safety Boots -->
|
||||
<g id="layer-gear-steel_toe_boots" style="display: none;">
|
||||
<path d="M 100 365 L 142 365 L 146 405 L 94 405 Z" fill="#1c1917" stroke="#44403c" stroke-width="2"/>
|
||||
<path d="M 94 395 L 115 395 L 115 405 L 94 405 Z" fill="#78716c"/> <!-- Steel Cap Plate -->
|
||||
<path d="M 158 365 L 200 365 L 206 405 L 154 405 Z" fill="#1c1917" stroke="#44403c" stroke-width="2"/>
|
||||
<path d="M 185 395 L 206 395 L 206 405 L 185 405 Z" fill="#78716c"/>
|
||||
</g>
|
||||
|
||||
<!-- Chemical Rubber Boots -->
|
||||
<g id="layer-gear-chemical_rubber_boots" style="display: none;">
|
||||
<path d="M 98 345 L 144 345 L 146 408 L 92 408 Z" fill="#047857" stroke="#064e3b" stroke-width="2.5"/>
|
||||
<path d="M 156 345 L 202 345 L 208 408 L 154 408 Z" fill="#047857" stroke="#064e3b" stroke-width="2.5"/>
|
||||
</g>
|
||||
|
||||
<!-- Canvas Running Sneakers (Distractor) -->
|
||||
<g id="layer-gear-regular_sneakers" style="display: none;">
|
||||
<path d="M 102 375 L 140 375 L 144 398 L 96 398 Z" fill="#ef4444" stroke="#ffffff" stroke-width="2"/>
|
||||
<path d="M 160 375 L 198 375 L 204 398 L 156 398 Z" fill="#ef4444" stroke="#ffffff" stroke-width="2"/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
<!-- Dynamic Character Step Image -->
|
||||
<img src="images/steps/01_no_ppe.png" alt="Worker Character" class="avatar-step-img" id="avatar-step-img" />
|
||||
</div>
|
||||
`;
|
||||
|
||||
this.updateLayers();
|
||||
@@ -300,37 +135,12 @@ class WorkerAvatar {
|
||||
updateLayers() {
|
||||
if (!this.container) return;
|
||||
|
||||
// All gear IDs configured across scenarios
|
||||
const allGearIds = [
|
||||
'hard_hat_cap', 'hard_hat_chemical',
|
||||
'faceshield_glasses', 'chemical_splash_goggles', 'regular_sunglasses', 'standard_safety_glasses',
|
||||
'earmuffs_heavy', 'wireless_earbuds', 'organic_vapor_respirator', 'cloth_dust_mask',
|
||||
'heavy_leather_jacket', 'chemical_resistant_apron', 'cotton_lab_coat',
|
||||
'leather_grinding_gloves', 'nitrile_gauntlet_gloves', 'thin_latex_gloves', 'leather_work_gloves',
|
||||
'steel_toe_boots', 'chemical_rubber_boots', 'regular_sneakers'
|
||||
];
|
||||
|
||||
allGearIds.forEach(gearId => {
|
||||
const el = document.getElementById(`layer-gear-${gearId}`);
|
||||
if (el) {
|
||||
el.style.display = this.equippedItems.has(gearId) ? 'block' : 'none';
|
||||
const imgEl = document.getElementById('avatar-step-img');
|
||||
if (imgEl) {
|
||||
const targetSrc = this.getStepImagePath();
|
||||
if (imgEl.getAttribute('src') !== targetSrc) {
|
||||
imgEl.src = targetSrc;
|
||||
}
|
||||
});
|
||||
|
||||
// Toggle bare hands layer if gloves equipped
|
||||
const bareHandsEl = document.getElementById('layer-hands-bare');
|
||||
const hasAnyGloves = ['leather_grinding_gloves', 'nitrile_gauntlet_gloves', 'thin_latex_gloves', 'leather_work_gloves']
|
||||
.some(g => this.equippedItems.has(g));
|
||||
if (bareHandsEl) {
|
||||
bareHandsEl.style.display = hasAnyGloves ? 'none' : 'block';
|
||||
}
|
||||
|
||||
// Toggle base feet layer if special boots equipped
|
||||
const baseFeetEl = document.getElementById('layer-feet-base');
|
||||
const hasAnyBoots = ['steel_toe_boots', 'chemical_rubber_boots', 'regular_sneakers']
|
||||
.some(b => this.equippedItems.has(b));
|
||||
if (baseFeetEl) {
|
||||
baseFeetEl.style.display = hasAnyBoots ? 'none' : 'block';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
/**
|
||||
* PPE SAFETY CHALLENGE - SCENARIO DEFINITIONS & SAFETY DATABASE
|
||||
* Implements: SEE THE SITUATION -> IDENTIFY HAZARDS -> SELECT PPE -> CONSEQUENCES -> CORRECT
|
||||
* PPE SAFETY CHALLENGE - SCENARIO DEFINITIONS & 3x3 SAFETY LOCKER DATABASE
|
||||
* "Choose Right. Work Safe."
|
||||
*
|
||||
* Scenario 1: Angle Grinding Operation (PNG Icons from grinding_ppe_icons_png)
|
||||
* Scenario 2: Chemical Handling & Dispensing (PNG Icons from ppe_icons_png)
|
||||
*/
|
||||
|
||||
const SCENARIO_DATA = [
|
||||
{
|
||||
id: "grinding",
|
||||
index: 1,
|
||||
title: "Metal Grinding Operation",
|
||||
title: "Angle Grinding Operation",
|
||||
taskName: "ANGLE GRINDER WELD SMOOTHING",
|
||||
sceneClass: "stage-grinding",
|
||||
environmentDesc: "An industrial worker is preparing to grind rough weld seams on heavy structural steel using a high-speed angle grinder (11,000 RPM).",
|
||||
@@ -15,176 +18,150 @@ const SCENARIO_DATA = [
|
||||
guideTip: "High-speed spinning discs eject fiery sparks and shrapnel at over 100 m/s with extreme noise (95+ dB).",
|
||||
|
||||
hazards: [
|
||||
{
|
||||
id: "flying_sparks",
|
||||
label: "Flying hot metal sparks & abrasive wheel particles (11,000 RPM)",
|
||||
criticalSlot: "eyes"
|
||||
},
|
||||
{
|
||||
id: "high_noise",
|
||||
label: "Continuous high decibel motor and grinding noise (95-105 dB)",
|
||||
criticalSlot: "ears"
|
||||
},
|
||||
{
|
||||
id: "sharp_burrs",
|
||||
label: "Sharp metal burrs, intense friction heat & wheel kickback hazard",
|
||||
criticalSlot: "hands"
|
||||
},
|
||||
{
|
||||
id: "falling_debris",
|
||||
label: "Heavy steel drop hazard & structural workshop overhead risks",
|
||||
criticalSlot: "feet"
|
||||
}
|
||||
{ id: "flying_sparks", label: "Flying Hot Sparks (1000°C+)" },
|
||||
{ id: "high_noise", label: "High Decibel Noise (95+ dB)" },
|
||||
{ id: "sharp_burrs", label: "Sharp Metal Burrs & Jagged Edges" },
|
||||
{ id: "falling_debris", label: "Heavy Structural Steel Drop Hazard" }
|
||||
],
|
||||
|
||||
// Required protective gear items
|
||||
requiredPpe: [
|
||||
"faceshield_glasses",
|
||||
"safety_helmet_grind",
|
||||
"face_shield_grind",
|
||||
"hearing_protection_grind",
|
||||
"leather_grinding_gloves",
|
||||
"earmuffs_heavy",
|
||||
"hard_hat_cap",
|
||||
"heavy_leather_jacket",
|
||||
"steel_toe_boots"
|
||||
"steel_toe_boots_grind"
|
||||
],
|
||||
|
||||
// Critical slots for safety check evaluation
|
||||
criticalChecks: [
|
||||
{
|
||||
slot: "eyes",
|
||||
requiredItem: "faceshield_glasses",
|
||||
consequenceTitle: "Flying Particle Hazard",
|
||||
consequenceDesc: "Without full face & eye impact protection, flying abrasive particles at 11,000 RPM can cause catastrophic corneal penetration or severe facial lacerations.",
|
||||
missingLabel: "Full Face Shield + Safety Glasses (ANSI Z87+)"
|
||||
requiredItem: "face_shield_grind",
|
||||
consequenceTitle: "High-Speed Flying Particle Hazard",
|
||||
consequenceDesc: "Without full face & eye impact protection, flying abrasive disc particles and 1000°C sparks cause instant severe corneal burns and permanent vision loss.",
|
||||
missingLabel: "Face Shield (ANSI Z87+ Full Impact)"
|
||||
},
|
||||
{
|
||||
slot: "ears",
|
||||
requiredItem: "earmuffs_heavy",
|
||||
consequenceTitle: "Noise-Induced Hearing Damage",
|
||||
consequenceDesc: "Angle grinding routinely generates 100+ dB. Operating without rated hearing protection causes irreversible inner-ear acoustic trauma.",
|
||||
missingLabel: "Heavy Duty Hearing Protection (Earmuffs / Plugs)"
|
||||
requiredItem: "hearing_protection_grind",
|
||||
consequenceTitle: "Noise-Induced Acoustic Trauma",
|
||||
consequenceDesc: "Angle grinding routinely exceeds 100 dB. Operating without acoustic earmuffs causes irreversible inner-ear cochlear damage and permanent tinnitus.",
|
||||
missingLabel: "Hearing Protection (NRR 30 Earmuffs)"
|
||||
},
|
||||
{
|
||||
slot: "hands",
|
||||
requiredItem: "leather_grinding_gloves",
|
||||
consequenceTitle: "Thermal Burn & Abrasion Danger",
|
||||
consequenceDesc: "Thin latex or bare hands offer zero protection against glowing 800°C sparks and jagged steel edges. Heavy-duty leather gloves are required.",
|
||||
missingLabel: "Heavy-Duty Split Cowhide Leather Grinding Gloves"
|
||||
consequenceTitle: "Severe Thermal Burn & Laceration Danger",
|
||||
consequenceDesc: "Standard cloth work gloves melt instantly from 800°C sparks and provide zero protection against razor-sharp steel burrs. Heavy split cowhide leather gloves are mandatory.",
|
||||
missingLabel: "Leather Gloves (Split Cowhide)"
|
||||
},
|
||||
{
|
||||
slot: "feet",
|
||||
requiredItem: "steel_toe_boots",
|
||||
consequenceTitle: "Crush & Penetration Hazard",
|
||||
consequenceDesc: "Standard footwear cannot protect against dropped structural steel sections or sharp discarded metal shards on workshop floors.",
|
||||
missingLabel: "Steel-Toe Safety Boots with Puncture Resistant Sole"
|
||||
requiredItem: "steel_toe_boots_grind",
|
||||
consequenceTitle: "Crush & Puncture Hazard",
|
||||
consequenceDesc: "Standard footwear offers zero impact protection against dropped structural steel sections or sharp discarded metal shards on workshop floors.",
|
||||
missingLabel: "Safety Shoes (Steel-Toe ASTM F2413)"
|
||||
},
|
||||
{
|
||||
slot: "head",
|
||||
requiredItem: "hard_hat_cap",
|
||||
requiredItem: "safety_helmet_grind",
|
||||
consequenceTitle: "Overhead Impact & Debris Risk",
|
||||
consequenceDesc: "In fabrication bays, overhead cranes and moving metal fixtures require impact-certified head protection.",
|
||||
missingLabel: "Industrial Hard Hat (Type 1, Class E)"
|
||||
},
|
||||
{
|
||||
slot: "body",
|
||||
requiredItem: "heavy_leather_jacket",
|
||||
consequenceTitle: "Clothing Ignition / Hot Spark Burn",
|
||||
consequenceDesc: "Synthetic regular clothing easily melts or ignites from dense grinder spark streams. Heavy flame-resistant leather/cotton protective wear is essential.",
|
||||
missingLabel: "Flame-Resistant Heavy Leather Welder/Grinder Jacket"
|
||||
consequenceDesc: "In fabrication bays, overhead cranes, suspended steel beams, and falling debris require impact-certified head protection.",
|
||||
missingLabel: "Safety Helmet (Industrial Hard Hat)"
|
||||
}
|
||||
],
|
||||
|
||||
// Locker items available for selection (including distractors)
|
||||
lockerItems: [
|
||||
{
|
||||
id: "faceshield_glasses",
|
||||
name: "Face Shield + Safety Glasses",
|
||||
slot: "eyes",
|
||||
icon: "🛡️",
|
||||
spec: "ANSI Z87+ Impact Dual Protection",
|
||||
isCorrect: true
|
||||
id: "safety_helmet_grind",
|
||||
name: "Safety Helmet",
|
||||
slot: "head",
|
||||
iconType: "helmet",
|
||||
iconImg: "grinding_ppe_icons_png/01_safety_helmet.png",
|
||||
isCorrect: true,
|
||||
spec: "ANSI Z89.1 Type 1 Class E Hard Hat"
|
||||
},
|
||||
{
|
||||
id: "regular_sunglasses",
|
||||
name: "Standard Tinted Sunglasses",
|
||||
id: "safety_goggles_grind",
|
||||
name: "Safety Goggles",
|
||||
slot: "eyes",
|
||||
icon: "🕶️",
|
||||
spec: "Non-impact rated tinted plastic",
|
||||
iconType: "sunglasses",
|
||||
iconImg: "grinding_ppe_icons_png/02_safety_goggles.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Standard sunglasses shatter upon impact and leave the face exposed to flying debris."
|
||||
rejectReason: "Standard safety glasses/goggles leave face and neck vulnerable to hot flying sparks and shattering grinding fragments. A full face shield is required.",
|
||||
spec: "Non-impact safety goggles"
|
||||
},
|
||||
{
|
||||
id: "face_shield_grind",
|
||||
name: "Face Shield",
|
||||
slot: "eyes",
|
||||
iconType: "face_shield",
|
||||
iconImg: "grinding_ppe_icons_png/03_face_shield.png",
|
||||
isCorrect: true,
|
||||
spec: "ANSI Z87+ Full Impact Face Visor"
|
||||
},
|
||||
{
|
||||
id: "hearing_protection_grind",
|
||||
name: "Hearing Protection",
|
||||
slot: "ears",
|
||||
iconType: "earmuffs",
|
||||
iconImg: "grinding_ppe_icons_png/04_hearing_protection.png",
|
||||
isCorrect: true,
|
||||
spec: "High noise reduction acoustic seal (NRR 30)"
|
||||
},
|
||||
{
|
||||
id: "work_gloves_grind",
|
||||
name: "Work Gloves",
|
||||
slot: "hands",
|
||||
iconType: "work_gloves",
|
||||
iconImg: "grinding_ppe_icons_png/05_work_gloves.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Thin work gloves offer zero thermal or cut protection against glowing 1000°C sparks and jagged burrs. Heavy split cowhide leather gloves are required.",
|
||||
spec: "Porous cloth work gloves"
|
||||
},
|
||||
{
|
||||
id: "leather_grinding_gloves",
|
||||
name: "Leather Grinding Gloves",
|
||||
name: "Leather Gloves",
|
||||
slot: "hands",
|
||||
icon: "🧤",
|
||||
spec: "Heavy split cowhide heat/spark resistant",
|
||||
isCorrect: true
|
||||
iconType: "leather_gloves",
|
||||
iconImg: "grinding_ppe_icons_png/06_leather_gloves.png",
|
||||
isCorrect: true,
|
||||
spec: "Heavy split cowhide heat/spark resistant"
|
||||
},
|
||||
{
|
||||
id: "thin_latex_gloves",
|
||||
name: "Thin Disposable Latex Gloves",
|
||||
slot: "hands",
|
||||
icon: "🧤",
|
||||
spec: "Medical grade 4mil rubber (Flaggable)",
|
||||
isCorrect: false,
|
||||
rejectReason: "Thin latex immediately melts onto skin when hit by 800°C grinder sparks."
|
||||
},
|
||||
{
|
||||
id: "earmuffs_heavy",
|
||||
name: "Industrial Ear Muffs (NRR 30)",
|
||||
slot: "ears",
|
||||
icon: "🎧",
|
||||
spec: "High noise reduction acoustic seal",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "wireless_earbuds",
|
||||
name: "Consumer Music Earbuds",
|
||||
slot: "ears",
|
||||
icon: "🎵",
|
||||
spec: "Audio playback (Non-certified)",
|
||||
isCorrect: false,
|
||||
rejectReason: "Music earphones are not certified PPE and distract the operator from machine warnings."
|
||||
},
|
||||
{
|
||||
id: "hard_hat_cap",
|
||||
name: "Industrial Hard Hat",
|
||||
slot: "head",
|
||||
icon: "⛑️",
|
||||
spec: "ANSI Z89.1 Type 1 Class E",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "heavy_leather_jacket",
|
||||
name: "Flame-Resistant Work Jacket",
|
||||
id: "reflective_vest_grind",
|
||||
name: "Reflective Vest",
|
||||
slot: "body",
|
||||
icon: "🦺",
|
||||
spec: "Heavy-duty spark-resistant leather/cotton",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "steel_toe_boots",
|
||||
name: "Steel-Toe Safety Boots",
|
||||
slot: "feet",
|
||||
icon: "🥾",
|
||||
spec: "ASTM F2413 Impact & Puncture Rated",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "regular_sneakers",
|
||||
name: "Canvas Running Sneakers",
|
||||
slot: "feet",
|
||||
icon: "👟",
|
||||
spec: "Fabric sports shoe (Zero drop rating)",
|
||||
iconType: "leather_jacket",
|
||||
iconImg: "grinding_ppe_icons_png/07_reflective_vest.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Fabric sneakers ignite from sparks and offer zero crush protection from dropped metal."
|
||||
rejectReason: "Synthetic high-visibility vests melt or ignite from dense grinder spark streams.",
|
||||
spec: "Synthetic mesh hi-vis vest"
|
||||
},
|
||||
{
|
||||
id: "steel_toe_boots_grind",
|
||||
name: "Safety Shoes",
|
||||
slot: "feet",
|
||||
iconType: "safety_boots",
|
||||
iconImg: "grinding_ppe_icons_png/08_safety_shoes.png",
|
||||
isCorrect: true,
|
||||
spec: "ASTM F2413 Impact & Puncture Rated"
|
||||
},
|
||||
{
|
||||
id: "dust_mask_grind",
|
||||
name: "Dust Mask",
|
||||
slot: "body",
|
||||
iconType: "cotton_coat",
|
||||
iconImg: "grinding_ppe_icons_png/09_dust_mask.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "A simple dust mask does not protect the face or body from high-speed thermal sparks.",
|
||||
spec: "N95 particulate filter mask"
|
||||
}
|
||||
],
|
||||
|
||||
successMessage: {
|
||||
title: "SAFE TO START",
|
||||
headline: "Correct PPE selected.",
|
||||
body: "Your eyes, face, hands, hearing and feet are protected from the main hazards of this task."
|
||||
headline: "Correct Grinding Protection Selected.",
|
||||
body: "Your eyes, face, hands, hearing and feet are fully protected from all hazards of this grinding task."
|
||||
}
|
||||
},
|
||||
|
||||
@@ -194,180 +171,162 @@ const SCENARIO_DATA = [
|
||||
title: "Chemical Handling & Dispensing",
|
||||
taskName: "CORROSIVE SOLVENT TRANSFER",
|
||||
sceneClass: "stage-chemical",
|
||||
environmentDesc: "An employee is preparing to transfer an industrial corrosive solvent between approved containment drums inside a ventilated chemical dispensing station.",
|
||||
environmentDesc: "An employee is transferring an industrial corrosive solvent between approved containers at a ventilated dispensing station.",
|
||||
audioCaption: "Ventilation Ambience: Fume extraction hood airflow & quiet laboratory background",
|
||||
guideTip: "Corrosive chemicals cause irreversible chemical burns upon skin contact and severe vapor irritation.",
|
||||
guideTip: "Observe the scene, identify the hazards and select the correct PPE before starting the task.",
|
||||
|
||||
hazards: [
|
||||
{
|
||||
id: "chemical_splash",
|
||||
label: "Corrosive liquid splash risk during pouring & transfer",
|
||||
criticalSlot: "eyes"
|
||||
},
|
||||
{
|
||||
id: "skin_absorption",
|
||||
label: "Acute dermal chemical burn and toxic absorption",
|
||||
criticalSlot: "hands"
|
||||
},
|
||||
{
|
||||
id: "body_soak",
|
||||
label: "Direct container overflow or accidental splash onto torso & legs",
|
||||
criticalSlot: "body"
|
||||
},
|
||||
{
|
||||
id: "foot_contact",
|
||||
label: "Chemical pooling on floor and footwear degradation",
|
||||
criticalSlot: "feet"
|
||||
}
|
||||
{ id: "chemical_splash", label: "Chemical Splash" },
|
||||
{ id: "skin_exposure", label: "Skin Exposure" },
|
||||
{ id: "vapour_exposure", label: "Vapour Exposure" },
|
||||
{ id: "floor_contamination", label: "Floor Contamination" }
|
||||
],
|
||||
|
||||
// Required protective gear items
|
||||
requiredPpe: [
|
||||
"chemical_splash_goggles",
|
||||
"nitrile_gauntlet_gloves",
|
||||
"chemical_resistant_apron",
|
||||
"chemical_rubber_boots",
|
||||
"hard_hat_chemical",
|
||||
"organic_vapor_respirator"
|
||||
"safety_helmet_chem",
|
||||
"chem_splash_goggles",
|
||||
"hearing_protection_chem",
|
||||
"chem_resistant_gloves",
|
||||
"chem_resistant_apron",
|
||||
"chem_safety_shoes"
|
||||
],
|
||||
|
||||
// Critical slots evaluation
|
||||
criticalChecks: [
|
||||
{
|
||||
slot: "eyes",
|
||||
requiredItem: "chemical_splash_goggles",
|
||||
requiredItem: "chem_splash_goggles",
|
||||
consequenceTitle: "Chemical Splash to Eyes",
|
||||
consequenceDesc: "Standard safety glasses with open side vents allow hazardous liquid droplets to roll directly into the eyes, causing permanent corneal scarring.",
|
||||
missingLabel: "Indirectly Vented Chemical Splash Goggles (ANSI Z87.1 D3)"
|
||||
consequenceDesc: "Without sealed indirectly-vented chemical splash goggles, corrosive solvent droplets roll directly into the eyes, causing permanent corneal scarring.",
|
||||
missingLabel: "Chemical Splash Goggles (ANSI Z87.1 D3)"
|
||||
},
|
||||
{
|
||||
slot: "hands",
|
||||
requiredItem: "nitrile_gauntlet_gloves",
|
||||
requiredItem: "chem_resistant_gloves",
|
||||
consequenceTitle: "Dermal Chemical Permeation",
|
||||
consequenceDesc: "Porous leather or basic household gloves rapidly absorb harsh solvents, causing chemical burns and systemic toxicity through the skin.",
|
||||
missingLabel: "Heavy-Duty Chemical-Resistant Nitrile/Neoprene Gauntlets"
|
||||
consequenceDesc: "Standard cloth/leather or bare hands rapidly absorb harsh corrosive solvents, causing severe chemical burns and toxic absorption.",
|
||||
missingLabel: "Chemical Resistant Gloves (Nitrile / Neoprene)"
|
||||
},
|
||||
{
|
||||
slot: "body",
|
||||
requiredItem: "chemical_resistant_apron",
|
||||
requiredItem: "chem_resistant_apron",
|
||||
consequenceTitle: "Body Splash & Acid Soak Hazard",
|
||||
consequenceDesc: "Standard porous fabric clothing absorbs chemical splashes immediately, holding corrosive liquids against the skin.",
|
||||
missingLabel: "Chemical-Resistant Impervious PVC/Neoprene Apron"
|
||||
consequenceDesc: "Standard cotton coats absorb corrosive chemicals immediately, holding toxic liquids against the skin. Impervious chemical apron is required.",
|
||||
missingLabel: "Chemical Resistant Apron (PVC / Neoprene)"
|
||||
},
|
||||
{
|
||||
slot: "feet",
|
||||
requiredItem: "chemical_rubber_boots",
|
||||
requiredItem: "chem_safety_shoes",
|
||||
consequenceTitle: "Corrosive Liquid Footwear Infiltration",
|
||||
consequenceDesc: "Standard leather safety boots dissolve and degrade when exposed to pooled industrial acids and solvents.",
|
||||
missingLabel: "Chemical-Resistant Neoprene/Rubber Boots"
|
||||
consequenceDesc: "Standard footwear degrades rapidly when exposed to pooled industrial acids. Chemical-resistant safety boots are required.",
|
||||
missingLabel: "Chemical Safety Shoes / Boots"
|
||||
},
|
||||
{
|
||||
slot: "ears",
|
||||
requiredItem: "organic_vapor_respirator", // Uses respiratory/head slot
|
||||
consequenceTitle: "Hazardous Vapor Inhalation",
|
||||
consequenceDesc: "Concentrated chemical vapors overcome unprotected workers quickly. Half-mask respirator with chemical cartridges is required.",
|
||||
missingLabel: "Half-Mask Respirator with Organic Vapor/Acid Gas Cartridges"
|
||||
requiredItem: "hearing_protection_chem",
|
||||
consequenceTitle: "High Ventilation & Pump Noise Hazard",
|
||||
consequenceDesc: "Continuous industrial ventilation extractors and dispensing pumps exceed safe acoustic thresholds.",
|
||||
missingLabel: "Hearing Protection (Earmuffs)"
|
||||
},
|
||||
{
|
||||
slot: "head",
|
||||
requiredItem: "hard_hat_chemical",
|
||||
requiredItem: "safety_helmet_chem",
|
||||
consequenceTitle: "Overhead Chemical Piping Hazard",
|
||||
consequenceDesc: "Chemical distribution zones require head protection against overhead pipe drips and valve maintenance risks.",
|
||||
missingLabel: "Chemical-Resistant Industrial Hard Hat"
|
||||
consequenceDesc: "Chemical distribution bays require certified head protection against overhead pipe drips and valve fixtures.",
|
||||
missingLabel: "Safety Helmet (Type 1 Class E)"
|
||||
}
|
||||
],
|
||||
|
||||
lockerItems: [
|
||||
{
|
||||
id: "chemical_splash_goggles",
|
||||
id: "safety_helmet_chem",
|
||||
name: "Safety Helmet",
|
||||
slot: "head",
|
||||
iconType: "helmet",
|
||||
iconImg: "ppe_icons_png/01_safety_helmet.png",
|
||||
isCorrect: true,
|
||||
spec: "ANSI Z89.1 Certified Industrial Hard Hat"
|
||||
},
|
||||
{
|
||||
id: "chem_splash_goggles",
|
||||
name: "Chemical Splash Goggles",
|
||||
slot: "eyes",
|
||||
icon: "🥽",
|
||||
spec: "ANSI Z87.1 D3 Sealed Splash Protection",
|
||||
isCorrect: true
|
||||
iconType: "splash_goggles",
|
||||
iconImg: "ppe_icons_png/02_chemical_splash_goggles.png",
|
||||
isCorrect: true,
|
||||
spec: "ANSI Z87.1 D3 Sealed Chemical Splash Goggles"
|
||||
},
|
||||
{
|
||||
id: "standard_safety_glasses",
|
||||
name: "Open Safety Glasses",
|
||||
id: "face_shield_chem",
|
||||
name: "Face Shield",
|
||||
slot: "eyes",
|
||||
icon: "👓",
|
||||
spec: "Impact rated with open side vents (Non-liquid)",
|
||||
iconType: "face_shield",
|
||||
iconImg: "ppe_icons_png/03_face_shield.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Open side vents allow liquid splashes and corrosive droplets to enter the eye."
|
||||
rejectReason: "A standalone face shield without sealed splash goggles underneath allows liquid splashes to roll up into eyes.",
|
||||
spec: "Full Face Visor (Secondary Protection)"
|
||||
},
|
||||
{
|
||||
id: "nitrile_gauntlet_gloves",
|
||||
name: "Nitrile Gauntlet Gloves",
|
||||
slot: "hands",
|
||||
icon: "🧤",
|
||||
spec: "15-mil Heavy Nitrile Chemical Gauntlets",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "leather_work_gloves",
|
||||
name: "Standard Leather Work Gloves",
|
||||
slot: "hands",
|
||||
icon: "🧤",
|
||||
spec: "Porous split cowhide (Absorbent)",
|
||||
isCorrect: false,
|
||||
rejectReason: "Leather absorbs corrosive chemicals like a sponge, causing deep chemical burns."
|
||||
},
|
||||
{
|
||||
id: "chemical_resistant_apron",
|
||||
name: "Chemical-Resistant Apron",
|
||||
slot: "body",
|
||||
icon: "🦺",
|
||||
spec: "Impermeable Heavy PVC / Neoprene Apron",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "cotton_lab_coat",
|
||||
name: "Standard Cotton Coat",
|
||||
slot: "body",
|
||||
icon: "🥼",
|
||||
spec: "Porous woven cotton (Non-impervious)",
|
||||
isCorrect: false,
|
||||
rejectReason: "Cotton absorbs acids and solvents directly into underclothes."
|
||||
},
|
||||
{
|
||||
id: "chemical_rubber_boots",
|
||||
name: "Chemical Rubber Boots",
|
||||
slot: "feet",
|
||||
icon: "🥾",
|
||||
spec: "Seamless Neoprene Acid-Resistant Boots",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "organic_vapor_respirator",
|
||||
name: "Organic Vapor Respirator",
|
||||
slot: "ears", // Grouped in face/respiratory slot
|
||||
icon: "😷",
|
||||
spec: "Half-Face Mask with Dual Acid/Vapor Cartridges",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "hard_hat_chemical",
|
||||
name: "Safety Hard Hat",
|
||||
slot: "head",
|
||||
icon: "⛑️",
|
||||
spec: "Chemical-Resistant High Density Polyethylene",
|
||||
isCorrect: true
|
||||
},
|
||||
{
|
||||
id: "cloth_dust_mask",
|
||||
name: "Simple Cloth Dust Mask",
|
||||
id: "hearing_protection_chem",
|
||||
name: "Hearing Protection",
|
||||
slot: "ears",
|
||||
icon: "😷",
|
||||
spec: "Particulate only (No gas/vapor barrier)",
|
||||
iconType: "earmuffs",
|
||||
iconImg: "ppe_icons_png/04_hearing_protection.png",
|
||||
isCorrect: true,
|
||||
spec: "NRR 30 Acoustic Earmuffs"
|
||||
},
|
||||
{
|
||||
id: "chem_resistant_gloves",
|
||||
name: "Chemical Resistant Gloves",
|
||||
slot: "hands",
|
||||
iconType: "chem_gloves",
|
||||
iconImg: "ppe_icons_png/05_chemical_resistant_gloves.png",
|
||||
isCorrect: true,
|
||||
spec: "15-mil Heavy Nitrile Chemical Gauntlets"
|
||||
},
|
||||
{
|
||||
id: "standard_work_gloves",
|
||||
name: "Standard Work Gloves",
|
||||
slot: "hands",
|
||||
iconType: "work_gloves",
|
||||
iconImg: "ppe_icons_png/06_standard_work_gloves.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Cloth dust masks offer ZERO filtration against toxic chemical fumes and organic solvent vapors."
|
||||
rejectReason: "Standard porous work gloves absorb corrosive liquids like a sponge, causing deep chemical burns.",
|
||||
spec: "Cloth/Leather Work Gloves (Porous)"
|
||||
},
|
||||
{
|
||||
id: "chem_resistant_apron",
|
||||
name: "Chemical Resistant Apron",
|
||||
slot: "body",
|
||||
iconType: "chem_apron",
|
||||
iconImg: "ppe_icons_png/07_chemical_resistant_apron.png",
|
||||
isCorrect: true,
|
||||
spec: "Impermeable Heavy PVC / Neoprene Apron"
|
||||
},
|
||||
{
|
||||
id: "chem_safety_shoes",
|
||||
name: "Safety Shoes",
|
||||
slot: "feet",
|
||||
iconType: "safety_boots",
|
||||
iconImg: "ppe_icons_png/08_safety_shoes.png",
|
||||
isCorrect: true,
|
||||
spec: "Chemical & Acid Resistant Safety Boots"
|
||||
},
|
||||
{
|
||||
id: "cotton_coat_chem",
|
||||
name: "Cotton Coat",
|
||||
slot: "body",
|
||||
iconType: "cotton_coat",
|
||||
iconImg: "ppe_icons_png/09_cotton_coat.png",
|
||||
isCorrect: false,
|
||||
rejectReason: "Cotton laboratory coats absorb acids and solvents directly into underclothing.",
|
||||
spec: "Standard Woven Cotton Lab Coat"
|
||||
}
|
||||
],
|
||||
|
||||
successMessage: {
|
||||
title: "SAFE TO PROCEED",
|
||||
headline: "Correct chemical protection selected.",
|
||||
body: "Your PPE helps protect the eyes, respiratory system and skin against accidental chemical splashes."
|
||||
headline: "Correct Chemical Protection Selected.",
|
||||
body: "Your PPE protects the eyes, skin, hearing, body and feet against hazardous chemical splashes and fumes."
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 128 KiB |
|
After Width: | Height: | Size: 124 KiB |
|
After Width: | Height: | Size: 127 KiB |
|
After Width: | Height: | Size: 134 KiB |
|
After Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 123 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 9.5 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 10 KiB |