|
|
<!DOCTYPE html> |
|
|
<html lang="en"> |
|
|
<head> |
|
|
<meta charset="UTF-8"> |
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
|
<title>Digital Preservation Glossary - Card Match Game</title> |
|
|
<style> |
|
|
* { |
|
|
box-sizing: border-box; |
|
|
margin: 0; |
|
|
padding: 0; |
|
|
} |
|
|
body { |
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif; |
|
|
background: #ffffff; |
|
|
min-height: 100vh; |
|
|
padding: 20px; |
|
|
color: #333; |
|
|
} |
|
|
.container { |
|
|
max-width: 1200px; |
|
|
margin: 0 auto; |
|
|
} |
|
|
header { |
|
|
text-align: center; |
|
|
margin-bottom: 15px; |
|
|
} |
|
|
h1 { |
|
|
font-size: 2rem; |
|
|
margin-bottom: 8px; |
|
|
color: #002147; |
|
|
} |
|
|
.subtitle { |
|
|
color: #666; |
|
|
font-size: 1rem; |
|
|
} |
|
|
|
|
|
|
|
|
.level-progress { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
align-items: center; |
|
|
margin: 20px 0 14px; |
|
|
} |
|
|
.level-label { |
|
|
padding: 7px 22px; |
|
|
border-radius: 20px; |
|
|
font-size: 0.85rem; |
|
|
font-weight: 600; |
|
|
background: #e8e8e8; |
|
|
color: #888; |
|
|
transition: background 0.4s ease, color 0.4s ease; |
|
|
white-space: nowrap; |
|
|
position: relative; |
|
|
z-index: 1; |
|
|
} |
|
|
.level-label.completed { |
|
|
background: #28a745; |
|
|
color: #fff; |
|
|
} |
|
|
.level-label.active { |
|
|
background: #002147; |
|
|
color: #fff; |
|
|
} |
|
|
.level-connector { |
|
|
width: 36px; |
|
|
height: 4px; |
|
|
background: #e0e0e0; |
|
|
margin: 0 -2px; |
|
|
transition: background 0.4s ease; |
|
|
} |
|
|
.level-connector.completed { |
|
|
background: #28a745; |
|
|
} |
|
|
|
|
|
|
|
|
.stats { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
gap: 30px; |
|
|
margin: 12px 0 18px; |
|
|
flex-wrap: wrap; |
|
|
} |
|
|
.stat { |
|
|
background: #f5f5f5; |
|
|
padding: 15px 25px; |
|
|
border-radius: 10px; |
|
|
text-align: center; |
|
|
border: 1px solid #e0e0e0; |
|
|
} |
|
|
.stat-value { |
|
|
font-size: 1.8rem; |
|
|
font-weight: bold; |
|
|
color: #002147; |
|
|
} |
|
|
.stat-value.warning { |
|
|
color: #dc3545; |
|
|
} |
|
|
.stat-label { |
|
|
font-size: 0.85rem; |
|
|
color: #666; |
|
|
text-transform: uppercase; |
|
|
letter-spacing: 1px; |
|
|
} |
|
|
|
|
|
|
|
|
.controls { |
|
|
display: flex; |
|
|
justify-content: center; |
|
|
gap: 15px; |
|
|
margin-bottom: 25px; |
|
|
flex-wrap: wrap; |
|
|
} |
|
|
button { |
|
|
background: #002147; |
|
|
color: white; |
|
|
border: none; |
|
|
padding: 12px 25px; |
|
|
border-radius: 8px; |
|
|
cursor: pointer; |
|
|
font-size: 1rem; |
|
|
font-weight: 600; |
|
|
transition: all 0.3s ease; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 8px; |
|
|
} |
|
|
button:hover { |
|
|
background: #003366; |
|
|
transform: translateY(-2px); |
|
|
} |
|
|
button.secondary { |
|
|
background: #f5f5f5; |
|
|
color: #002147; |
|
|
border: 2px solid #002147; |
|
|
} |
|
|
button.secondary:hover { |
|
|
background: #e8e8e8; |
|
|
} |
|
|
.btn-icon { |
|
|
font-size: 1.2rem; |
|
|
} |
|
|
|
|
|
|
|
|
.instructions { |
|
|
background: #f8f9fa; |
|
|
padding: 20px; |
|
|
border-radius: 10px; |
|
|
margin-bottom: 25px; |
|
|
text-align: center; |
|
|
border: 1px solid #e0e0e0; |
|
|
} |
|
|
.instructions h2 { |
|
|
color: #002147; |
|
|
margin-bottom: 10px; |
|
|
font-size: 1.2rem; |
|
|
} |
|
|
.instructions p { |
|
|
color: #555; |
|
|
line-height: 1.6; |
|
|
} |
|
|
.term-count { |
|
|
background: #e8f4f8; |
|
|
color: #002147; |
|
|
padding: 8px 16px; |
|
|
border-radius: 20px; |
|
|
font-size: 0.9rem; |
|
|
display: inline-block; |
|
|
margin-top: 10px; |
|
|
} |
|
|
|
|
|
|
|
|
.message { |
|
|
text-align: center; |
|
|
padding: 25px 20px; |
|
|
margin: 15px 0; |
|
|
border-radius: 10px; |
|
|
font-size: 1.3rem; |
|
|
display: none; |
|
|
} |
|
|
.message.show { |
|
|
display: block; |
|
|
} |
|
|
.message.success { |
|
|
background: rgba(40, 167, 69, 0.1); |
|
|
border: 2px solid #28a745; |
|
|
color: #28a745; |
|
|
} |
|
|
.message.failure { |
|
|
background: rgba(220, 53, 69, 0.1); |
|
|
border: 2px solid #dc3545; |
|
|
color: #dc3545; |
|
|
} |
|
|
.message .msg-subtitle { |
|
|
font-size: 0.95rem; |
|
|
margin-top: 8px; |
|
|
color: #555; |
|
|
} |
|
|
|
|
|
.message.success button, |
|
|
.message.failure button { |
|
|
color: white; |
|
|
background: #002147; |
|
|
margin-top: 15px; |
|
|
font-size: 1rem; |
|
|
} |
|
|
.message.success button:hover, |
|
|
.message.failure button:hover { |
|
|
background: #003366; |
|
|
} |
|
|
|
|
|
|
|
|
.game-area { |
|
|
display: flex; |
|
|
flex-direction: column; |
|
|
gap: 30px; |
|
|
margin-bottom: 40px; |
|
|
overflow: visible; |
|
|
} |
|
|
.section { |
|
|
width: 100%; |
|
|
overflow: visible; |
|
|
} |
|
|
.terms-board { |
|
|
padding: 10px 0; |
|
|
} |
|
|
.section-header { |
|
|
color: #002147; |
|
|
font-size: 1.3rem; |
|
|
font-weight: 600; |
|
|
margin-bottom: 15px; |
|
|
padding-bottom: 10px; |
|
|
border-bottom: 2px solid #002147; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
gap: 10px; |
|
|
} |
|
|
.section-header .icon { |
|
|
font-size: 1.4rem; |
|
|
} |
|
|
.game-board { |
|
|
display: grid; |
|
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); |
|
|
gap: 12px; |
|
|
overflow: visible; |
|
|
} |
|
|
.definitions-board { |
|
|
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); |
|
|
padding: 20px 0 150px 0; |
|
|
} |
|
|
|
|
|
|
|
|
.card { |
|
|
height: 80px; |
|
|
perspective: 1000px; |
|
|
cursor: pointer; |
|
|
} |
|
|
.definitions-board .card { |
|
|
height: 110px; |
|
|
} |
|
|
.card-inner { |
|
|
position: relative; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
transition: transform 0.6s; |
|
|
transform-style: preserve-3d; |
|
|
} |
|
|
.card.flipped .card-inner { |
|
|
transform: rotateY(180deg); |
|
|
} |
|
|
.card-front, .card-back { |
|
|
position: absolute; |
|
|
width: 100%; |
|
|
height: 100%; |
|
|
backface-visibility: hidden; |
|
|
border-radius: 10px; |
|
|
display: flex; |
|
|
align-items: center; |
|
|
justify-content: center; |
|
|
padding: 15px; |
|
|
text-align: center; |
|
|
} |
|
|
.card-front { |
|
|
background: #002147; |
|
|
border: 2px solid #001a38; |
|
|
} |
|
|
.card-front::before { |
|
|
content: "?"; |
|
|
font-size: 2rem; |
|
|
color: white; |
|
|
opacity: 0.4; |
|
|
} |
|
|
.card-back { |
|
|
background: #002147; |
|
|
transform: rotateY(180deg); |
|
|
border: 2px solid #001a38; |
|
|
color: white; |
|
|
overflow: hidden; |
|
|
} |
|
|
.card-back .content { |
|
|
color: white; |
|
|
} |
|
|
.card-back.term .content { |
|
|
font-size: 1.2rem; |
|
|
font-weight: bold; |
|
|
} |
|
|
.card-back.definition { |
|
|
font-size: 0.8rem; |
|
|
line-height: 1.4; |
|
|
} |
|
|
.card.matched .card-inner { |
|
|
transform: rotateY(180deg); |
|
|
} |
|
|
.card.matched .card-back { |
|
|
background: #28a745; |
|
|
border-color: #1e7e34; |
|
|
} |
|
|
.card.selected .card-back { |
|
|
border-color: #ffc107; |
|
|
border-width: 3px; |
|
|
box-shadow: 0 0 15px rgba(255, 193, 7, 0.5); |
|
|
} |
|
|
|
|
|
.definitions-board .card.selected { |
|
|
z-index: 100; |
|
|
position: relative; |
|
|
} |
|
|
.definitions-board .card.selected .card-inner { |
|
|
transform: rotateY(180deg); |
|
|
transition: transform 0.3s ease; |
|
|
} |
|
|
.definitions-board .card.selected .card-back { |
|
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3), 0 0 20px rgba(255, 193, 7, 0.6); |
|
|
font-size: 1.05rem; |
|
|
width: 340px; |
|
|
height: auto; |
|
|
min-height: 110px; |
|
|
position: absolute; |
|
|
top: 0; |
|
|
left: 0; |
|
|
transform: rotateY(180deg); |
|
|
overflow: visible; |
|
|
padding: 20px; |
|
|
line-height: 1.5; |
|
|
} |
|
|
|
|
|
.terms-board .card.selected { |
|
|
z-index: 100; |
|
|
position: relative; |
|
|
} |
|
|
.terms-board .card.selected .card-inner { |
|
|
transform: rotateY(180deg) scale(1.2); |
|
|
transition: transform 0.3s ease; |
|
|
} |
|
|
.terms-board .card.selected .card-back { |
|
|
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25), 0 0 15px rgba(255, 193, 7, 0.5); |
|
|
} |
|
|
.card.wrong .card-back { |
|
|
border-color: #dc3545; |
|
|
background: #dc3545; |
|
|
} |
|
|
.card.removing { |
|
|
animation: fadeOut 0.5s ease forwards; |
|
|
} |
|
|
@keyframes fadeOut { |
|
|
0% { opacity: 1; transform: scale(1); } |
|
|
100% { opacity: 0; transform: scale(0.8); } |
|
|
} |
|
|
.card.removed { |
|
|
visibility: hidden; |
|
|
pointer-events: none; |
|
|
} |
|
|
|
|
|
|
|
|
.attribution { |
|
|
background: #f8f9fa; |
|
|
padding: 20px; |
|
|
border-radius: 10px; |
|
|
margin-top: 40px; |
|
|
font-size: 0.85rem; |
|
|
line-height: 1.6; |
|
|
color: #666; |
|
|
border: 1px solid #e0e0e0; |
|
|
} |
|
|
.attribution a { |
|
|
color: #002147; |
|
|
text-decoration: none; |
|
|
font-weight: 500; |
|
|
} |
|
|
.attribution a:hover { |
|
|
text-decoration: underline; |
|
|
} |
|
|
|
|
|
|
|
|
@media (max-width: 600px) { |
|
|
h1 { font-size: 1.5rem; } |
|
|
.game-board { |
|
|
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); |
|
|
} |
|
|
.definitions-board { |
|
|
grid-template-columns: 1fr; |
|
|
} |
|
|
.card-back.definition { font-size: 0.75rem; } |
|
|
.definitions-board .card.selected .card-back { |
|
|
width: 100%; |
|
|
min-width: unset; |
|
|
font-size: 0.95rem; |
|
|
} |
|
|
.level-label { |
|
|
padding: 6px 14px; |
|
|
font-size: 0.78rem; |
|
|
} |
|
|
.level-connector { width: 20px; } |
|
|
} |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div class="container"> |
|
|
|
|
|
<header> |
|
|
<h1>🗃️ Digital Preservation Glossary</h1> |
|
|
<p class="subtitle">Match the terms with their definitions</p> |
|
|
</header> |
|
|
|
|
|
|
|
|
<div class="level-progress"> |
|
|
<div class="level-label active" id="level-label-0">Level 1</div> |
|
|
<div class="level-connector" id="level-conn-0"></div> |
|
|
<div class="level-label" id="level-label-1">Level 2</div> |
|
|
<div class="level-connector" id="level-conn-1"></div> |
|
|
<div class="level-label" id="level-label-2">Level 3</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="stats"> |
|
|
<div class="stat"> |
|
|
<div class="stat-value" id="matches">0 / 10</div> |
|
|
<div class="stat-label">✓ Matches</div> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<div class="stat-value" id="attempts">0</div> |
|
|
<div class="stat-label">Attempts</div> |
|
|
</div> |
|
|
<div class="stat"> |
|
|
<div class="stat-value" id="timer">2:30</div> |
|
|
<div class="stat-label">⏱ Time Left</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="controls"> |
|
|
<button onclick="startNewGame()"> |
|
|
<span class="btn-icon">🔄</span> New Game |
|
|
</button> |
|
|
<button class="secondary" onclick="shuffleCards()"> |
|
|
<span class="btn-icon">🔀</span> Shuffle |
|
|
</button> |
|
|
<button class="secondary" onclick="showHint()"> |
|
|
<span class="btn-icon">💡</span> Hint |
|
|
</button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="instructions"> |
|
|
<h2>How to Play</h2> |
|
|
<p>Complete all <strong>3 levels</strong> to win! Click a <strong>term card</strong>, then its matching <strong>definition</strong> below. |
|
|
Matched pairs turn <span style="color:#28a745;font-weight:bold">green</span>, then disappear on your next match. |
|
|
Each level has a tighter time limit — stay sharp!</p> |
|
|
<div class="term-count">📚 10 terms per level · 3 levels · From 108 terms in the DPC Glossary</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="message success" id="levelCompleteMessage"> |
|
|
<div id="levelCompleteTitle">🎉 Level 1 Complete!</div> |
|
|
<div class="msg-subtitle" id="levelCompleteSubtitle"></div> |
|
|
<button onclick="nextLevel()" id="nextLevelBtn">Next Level →</button> |
|
|
</div> |
|
|
|
|
|
<div class="message success" id="winMessage"> |
|
|
🎉 Congratulations! You completed all 3 levels! |
|
|
<div class="msg-subtitle">You've mastered the Digital Preservation Glossary!</div> |
|
|
<button onclick="startNewGame()">🔄 Play Again</button> |
|
|
</div> |
|
|
|
|
|
<div class="message failure" id="loseMessage"> |
|
|
⏰ Time's up! |
|
|
<div class="msg-subtitle">Don't give up — try this level again!</div> |
|
|
<button onclick="retryLevel()">🔄 Retry Level</button> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="game-area"> |
|
|
<div class="section terms-section"> |
|
|
<h2 class="section-header"> |
|
|
<span class="icon">📝</span> Terms & Acronyms |
|
|
</h2> |
|
|
<div class="game-board terms-board" id="termsBoard"></div> |
|
|
</div> |
|
|
<div class="section definitions-section"> |
|
|
<h2 class="section-header"> |
|
|
<span class="icon">📖</span> Definitions |
|
|
</h2> |
|
|
<div class="game-board definitions-board" id="definitionsBoard"></div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
<div class="attribution"> |
|
|
<strong>Source:</strong> Digital Preservation Handbook, 2nd Edition, |
|
|
<a href="https://www.dpconline.org/handbook" target="_blank">https://www.dpconline.org/handbook</a><br> |
|
|
Digital Preservation Coalition © 2015 licensed under the |
|
|
<a href="http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3/" target="_blank">Open Government Licence v3.0</a>.<br><br> |
|
|
This interactive learning tool was created for educational purposes. |
|
|
For the most up-to-date glossary, please visit the |
|
|
<a href="https://www.dpconline.org/handbook/glossary" target="_blank">DPC Handbook Glossary</a>. |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<script> |
|
|
|
|
|
|
|
|
|
|
|
const allGlossaryData = [ |
|
|
{ term:"Access", definition:"As defined in the Handbook, access is assumed to mean continued, ongoing usability of a digital resource, retaining all qualities of authenticity, accuracy and functionality deemed to be essential for the purposes the digital material was created and/or acquired for." }, |
|
|
{ term:"ADS", definition:"Archaeology Data Service. A UK based service active in digital preservation." }, |
|
|
{ term:"AIP", definition:"Archival Information Package. An Information Package, consisting of the Content Information and the associated Preservation Description Information (PDI), which is preserved within an OAIS (OAIS term)." }, |
|
|
{ term:"AMIA", definition:"Association of Moving Image Archives, an organisation active in the field of moving image archiving." }, |
|
|
{ term:"ARC", definition:"Container format for websites devised by the Internet Archive, superseded by WARC." }, |
|
|
{ term:"ASCII", definition:"American Standard Code for Information Interchange, standard for electronic text." }, |
|
|
{ term:"Authentication", definition:"A mechanism which attempts to establish the authenticity of digital materials at a particular point in time. For example, digital signatures." }, |
|
|
{ term:"Authenticity", definition:"The digital material is what it purports to be. In the case of electronic records, it refers to the trustworthiness of the electronic record as a record. In the case of \"born digital\" and digitised materials, it refers to the fact that whatever is being cited is the same as it was when it was first created unless the accompanying metadata indicates any changes." }, |
|
|
{ term:"Bit", definition:"A bit is the basic unit of information in computing. It can have only one of two values commonly represented as either a 0 or 1." }, |
|
|
{ term:"Bit Preservation", definition:"A term used to denote a very basic level of preservation of digital resource as it was submitted (literally preservation of the bits forming a digital resource). It may include maintaining onsite and offsite backup copies, virus checking, fixity-checking, and periodic refreshment to new storage media." }, |
|
|
{ term:"Born-Digital", definition:"Digital materials which are not intended to have an analogue equivalent, either as the originating source or as a result of conversion to analogue form." }, |
|
|
{ term:"BWF", definition:"Broadcast WAV format, the European Broadcasting Union standard for a WAV file, with extra metadata." }, |
|
|
{ term:"Byte (B)", definition:"A unit of digital information that most commonly consists of eight bits. Historically, the byte was the number of bits used to encode a single character of text in a computer." }, |
|
|
{ term:"CCSDS", definition:"Consultative Committee for Space Data Systems, the body responsible for the OAIS Reference Model." }, |
|
|
{ term:"Chain of Custody", definition:"A key concept in forensics whereby the custody and provenance of digital hardware, media and files are safeguarded through, for example, the appointment of evidence custodians." }, |
|
|
{ term:"Checksum", definition:"A unique numerical signature derived from a file. Used to compare copies." }, |
|
|
{ term:"CLIR", definition:"Council on Library and Information Resources. US based organisation active in digital preservation." }, |
|
|
{ term:"CNI", definition:"Coalition for Networked Information. US based organisation active in digital preservation." }, |
|
|
{ term:"Continuing Access", definition:"Refers to the right of a subscriber to an electronic publication and their users to have on-going permanent access to electronic materials which have already been leased and paid for by the subscriber from a publisher." }, |
|
|
{ term:"COPTR", definition:"Community Owned digital Preservation Tool Registry hosted by The Open Preservation Foundation." }, |
|
|
{ term:"Crawl", definition:"The act of browsing the web automatically and methodically to index or download content and other data from the web. The software to do this is often called a web crawler." }, |
|
|
{ term:"Dark Archive", definition:"An archive that cannot be accessed by any current users but may be accessible at future dates subject to the occurrence of specific pre-defined events ('trigger event')." }, |
|
|
{ term:"DCC", definition:"Digital Curation Centre. A UK based organisation active in digital preservation." }, |
|
|
{ term:"DDI", definition:"Data Documentation Initiative. A de facto international metadata standard for describing data from the social, behavioral, and economic sciences." }, |
|
|
{ term:"Designated Community", definition:"An identified group of potential consumers who should be able to understand a particular set of information from an archive. These consumers may consist of multiple communities, are designated by the archive, and may change over time (OAIS term)." }, |
|
|
{ term:"Digital Archiving", definition:"This term is used very differently within sectors. The library and archiving communities often use it interchangeably with digital preservation. Computing professionals tend to use it to mean the process of backup and ongoing maintenance." }, |
|
|
{ term:"Digital Forensics", definition:"The application of scientific technical methods and tools toward the preservation, collection, validation, identification, analysis, interpretation, documentation and presentation of digital information derived after-the-fact from digital sources." }, |
|
|
{ term:"Dim Archive", definition:"Provides bit preservation for the content plus digital preservation planning and actions for long-term perpetual access, and also limited current access." }, |
|
|
{ term:"DigCurV", definition:"Digital Curator Vocational Education Europe. A project funded by the European Commission to establish a curriculum framework for vocational training in digital curation." }, |
|
|
{ term:"Digital Materials", definition:"A broad term encompassing digital surrogates created as a result of converting analogue materials to digital form (digitisation), and \"born digital\" for which there has never been and is never intended to be an analogue equivalent, and digital records." }, |
|
|
{ term:"Digital Preservation", definition:"Refers to the series of managed activities necessary to ensure continued access to digital materials for as long as necessary. It includes all actions required to maintain access beyond the limits of media failure or technological and organisational change." }, |
|
|
{ term:"Short-term preservation", definition:"Access to digital materials either for a defined period of time while use is predicted but which does not extend beyond the foreseeable future and/or until it becomes inaccessible because of changes in technology." }, |
|
|
{ term:"Medium-term preservation", definition:"Continued access to digital materials beyond changes in technology for a defined period of time but not indefinitely." }, |
|
|
{ term:"Long-term preservation", definition:"Continued access to digital materials, or at least to the information contained in them, indefinitely." }, |
|
|
{ term:"Digital Preservation Management Workshop", definition:"An intensive training workshop and online tutorial developed and maintained by Cornell University Library, extended by ICPSR, and now maintained by MIT Libraries." }, |
|
|
{ term:"Digital Publications", definition:"\"Born digital\" objects which have been released for public access and either made available or distributed free of charge or for a fee. They may be networked publications or physical format publications distributed on formats such as optical disks." }, |
|
|
{ term:"Digitisation", definition:"The process of creating digital files by scanning or otherwise converting analogue materials. The resulting digital copy, or digital surrogate, would then be classed as digital material." }, |
|
|
{ term:"DIP", definition:"Dissemination Information Package. An Information Package, derived from one or more Archival Information Packages (AIPs), and sent by Archives to the Consumer in response to a request to the OAIS (OAIS term)." }, |
|
|
{ term:"DLF", definition:"Digital Library Federation. A US based organisation active in digital preservation." }, |
|
|
{ term:"Documentation", definition:"The information provided by a creator and the repository which provides enough information to establish provenance, history and context and to enable its use by others." }, |
|
|
{ term:"DOI", definition:"Digital Object Identifier. A technical and organisational infrastructure for the registration and use of persistent identifiers widely used in digital publications and for research data." }, |
|
|
{ term:"DPC", definition:"Digital Preservation Coalition. A UK and Ireland based organisation active in digital preservation and responsible for the Digital Preservation Handbook." }, |
|
|
{ term:"DPTP", definition:"Digital Preservation Training Programme, an intensive training course run by the University of London Computer Centre." }, |
|
|
{ term:"DRAMBORA", definition:"Digital Repository Audit Methodology Based on Risk Assessment. A set of risk assessment tools developed by the Digital Curation Centre." }, |
|
|
{ term:"DROID", definition:"A file profiling tool developed and distributed by TNA to identify file formats. Based on PRONOM." }, |
|
|
{ term:"Electronic Records", definition:"Records created digitally in the day-to-day business of the organisation and assigned formal status by the organisation. They may include word processing documents, emails, databases, or intranet web pages." }, |
|
|
{ term:"Emulation", definition:"A means of overcoming technological obsolescence of hardware and software by developing techniques for imitating obsolete systems on future generations of computers." }, |
|
|
{ term:"Escrow", definition:"A widespread legal practice of the deposit of content or software source code with a third party. Escrow takes place in a contractual relationship, formalized in an escrow agreement." }, |
|
|
{ term:"FIAF", definition:"International Federation of Film Archives, an association of the world's leading film archives." }, |
|
|
{ term:"FIAT", definition:"International Federation of Television Archives, a professional association for those engaged in the preservation and exploitation of broadcast archives." }, |
|
|
{ term:"File Format", definition:"A standard way that information is encoded for storage in a computer file. It tells the computer how to display, print, process, and save the information. A particular file format is often indicated by a file name extension." }, |
|
|
{ term:"Fixity Check", definition:"A method for ensuring the integrity of a file and verifying it has not been altered or corrupted. It is most often accomplished by computing checksums such as MD5, SHA1 or SHA256 for a file and comparing them to a stored value." }, |
|
|
{ term:"GIF", definition:"Graphic Interchange Format, an image which typically uses lossy compression." }, |
|
|
{ term:"Gigabyte (GB)", definition:"A unit of digital information often used to describe data or data storage size, equates to approximately 1,000 Megabytes (MB)." }, |
|
|
{ term:"GIS", definition:"Geographical Information System, a system that processes mapping and data together." }, |
|
|
{ term:"HTML", definition:"Hypertext Markup Language, a format used to present text and other information on the World Wide Web. Since 1996, versions have been maintained by the World Wide Web Consortium (W3C)." }, |
|
|
{ term:"IASA", definition:"International Association of Sound and Audiovisual Archives, an association for archives that preserve recorded sound and audiovisual documents." }, |
|
|
{ term:"IIPC", definition:"The International Internet Preservation Consortium." }, |
|
|
{ term:"Information Assurance", definition:"An aspect of digital security, specifically directed at ensuring that the quality of the information is demonstrably safeguarded, that it has not been tampered with or accessed inappropriately." }, |
|
|
{ term:"Ingest", definition:"The process of turning a Submission Information Package (SIP) into an Archival Information Package (AIP), i.e. putting data into a digital archive (OAIS term)." }, |
|
|
{ term:"InterPARES project", definition:"International Research on Permanent Authentic Records in Electronic Systems." }, |
|
|
{ term:"ISO", definition:"International Organization for Standardization." }, |
|
|
{ term:"JHove2", definition:"A characterization tool for digital objects. Characterisation is comprised of four elements: identifying the object's format; validating that the object conforms to its format's technical norms; extracting technical metadata; and assessing whether the object should be accepted into a repository." }, |
|
|
{ term:"JPEG", definition:"Joint Photographic Experts Group, a committee that oversees international standards for compression and processing of digital photographs. The majority of JPEG formats are lossy." }, |
|
|
{ term:"JPEG 2000", definition:"A revision of the JPEG format which can use lossless compression." }, |
|
|
{ term:"Kilobyte (KB)", definition:"A unit of digital information often used to describe data or data storage size, equates to approximately 1,000 Bytes." }, |
|
|
{ term:"Life-cycle Management", definition:"The need actively to manage digital resources at each stage of their life-cycle and to recognise the inter-dependencies between each stage, commencing preservation activities as early as practicable." }, |
|
|
{ term:"Lossless Compression", definition:"A mechanism for reducing file sizes that retains all original data." }, |
|
|
{ term:"Lossy Compression", definition:"A mechanism for reducing file sizes that typically discards data." }, |
|
|
{ term:"LOTAR", definition:"LOng Term Archiving and Retrieval - a digital preservation standard for 3D CAD models and product data management information developed by LOTAR International." }, |
|
|
{ term:"Megabyte (MB)", definition:"A unit of digital information often used to describe data or data storage size, equates to approximately 1,000 Kilobytes (KB)." }, |
|
|
{ term:"Metadata", definition:"Information which describes significant aspects of a resource. The emphasis in this Handbook is on what metadata are required to manage and preserve digital materials over time and ensure essential contextual, historical, and technical information are preserved." }, |
|
|
{ term:"METS", definition:"Metadata Encoding and Transmission Standard, a standard for presenting metadata using XML." }, |
|
|
{ term:"Migration", definition:"A means of overcoming technological obsolescence by transferring digital resources from one hardware/software generation to the next. The purpose is to preserve the intellectual content and retain the ability to retrieve, display, and use digital objects." }, |
|
|
{ term:"MIME", definition:"Multipurpose Internet Mail Extensions. A protocol for including non-ASCII information in email messages." }, |
|
|
{ term:"MPEG", definition:"Moving Picture Experts Group. A committee responsible for the development of international standards for compression, decompression, processing, and coded representation of moving pictures and audio." }, |
|
|
{ term:"NCDD", definition:"The Netherlands Coalition for Digital Preservation." }, |
|
|
{ term:"NDSA", definition:"National Digital Stewardship Alliance, a US based organisation active in digital preservation." }, |
|
|
{ term:"NESTOR", definition:"The German competence network for digital preservation." }, |
|
|
{ term:"OAIS", definition:"Open Archival Information System. An Archive consisting of an organization of people and systems that has accepted the responsibility to preserve information and make it available for a Designated Community. Also refers to the reference model standard (ISO 14721)." }, |
|
|
{ term:"OPF", definition:"Open Preservation Foundation, formerly the Open Planets Foundation." }, |
|
|
{ term:"PAIMAS", definition:"Space Data and Information Transfer Systems - Producer-Archive Interface - Methodology Abstract Standard. This ISO 20652:2006 standard covers the first stages of the ingest process defined by OAIS reference model." }, |
|
|
{ term:"PDF", definition:"Portable Document Format, a set of formats and open standards maintained by the International Organization for Standardization for producing and sharing electronic documents, originally developed by Adobe Systems." }, |
|
|
{ term:"PDF/A", definition:"Versions of the PDF standard intended for archival use." }, |
|
|
{ term:"PDI", definition:"Preservation Description Information. The information which is necessary for adequate preservation of the Content Information and which can be categorized as Provenance, Reference, Fixity, Context, and Access Rights Information (OAIS term)." }, |
|
|
{ term:"Petabyte (PB)", definition:"A unit of digital information often used to describe data or data storage size, equates to approximately 1,000 Terabytes (TB)." }, |
|
|
{ term:"PIN", definition:"Pérennisation des Informations Numériques, the French national interest group for digital preservation." }, |
|
|
{ term:"PREMIS", definition:"Preservation Metadata: Implementation Strategies. A de facto standard for digital preservation metadata." }, |
|
|
{ term:"PRONOM", definition:"A database of file formats, software products and other technical components required to support long-term access to electronic records and other digital objects. Used with DROID." }, |
|
|
{ term:"PST", definition:"Personal Storage Table is a file extension for local 'personal stores' written by Microsoft Outlook. PST files contain email messages and calendar entries." }, |
|
|
{ term:"Reformatting", definition:"Copying information content from one storage medium to a different storage medium (media reformatting) or converting from one file format to a different file format (file reformatting)." }, |
|
|
{ term:"Refreshing", definition:"Copying information content from one storage media to the same storage media." }, |
|
|
{ term:"Sandbox Containment", definition:"A secure computing environment for running novel, unattested or experimental code or changes in code, including potentially malicious code. The environment is self-contained with tightly controlled resources." }, |
|
|
{ term:"SGML", definition:"Standard Generalized Markup Language, an ISO standard for how to specify a document markup language or tag set." }, |
|
|
{ term:"Significant properties", definition:"Characteristics of digital and intellectual objects that must be preserved over time in order to ensure the continued accessibility, usability and meaning of the objects." }, |
|
|
{ term:"SIP", definition:"Submission Information Package. An Information Package that is delivered by the Producer to the OAIS for use in the construction or update of one or more Archival Information Packages (AIPs) (OAIS term)." }, |
|
|
{ term:"SMPTE", definition:"Society of Motion Picture and Television Engineers, a professional organisation and technical standards body for television and motion picture." }, |
|
|
{ term:"TDR", definition:"Trusted Digital Repository. A repository with a mission to provide reliable, long-term access to managed digital resources to its designated community, now and into the future." }, |
|
|
{ term:"Terabyte (TB)", definition:"A unit of digital information often used to describe data or data storage size, equates to approximately 1,000 Gigabytes (GB)." }, |
|
|
{ term:"Three-Legged Stool", definition:"A conceptual approach to digital preservation that suggests a fully implemented programme addresses organisational issues, technological concerns, and funding questions, balancing them like a three-legged stool." }, |
|
|
{ term:"TIFF", definition:"Tagged Image File Format, a common format for images typically lossless." }, |
|
|
{ term:"TRAC", definition:"Trusted Repository Audit and Certification, toolkit for auditing a digital repository." }, |
|
|
{ term:"Trigger Event", definition:"Terminology used when specific conditions relating to an electronic publication and its continued delivery are met. If the publication is no longer available from the publisher, a trigger event has occurred, which can set in motion access via an archive." }, |
|
|
{ term:"UKWA", definition:"UK Web Archive." }, |
|
|
{ term:"WARC", definition:"The WARC (Web ARChive) format is a container format for archived websites (ISO 28500:2009). It is a revision of the Internet Archive's ARC File Format." }, |
|
|
{ term:"WAV", definition:"The standard file wrapper for audio; see BWF (Broadcast WAV Format) for the professional variant." }, |
|
|
{ term:"Writeblockers", definition:"Tools that prevent an examination computer system from writing or altering a collection or subject hard drive or other digital media object." }, |
|
|
{ term:"XML", definition:"Extensible Markup Language, a widely used standard (derived from SGML), for representing structured information. It is maintained by the World Wide Web Consortium (W3C)." } |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const TERMS_PER_LEVEL = 10; |
|
|
const LEVELS = [ |
|
|
{ time: 150 }, |
|
|
{ time: 120 }, |
|
|
{ time: 90 } |
|
|
]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let glossaryData = []; |
|
|
let termCards = []; |
|
|
let definitionCards = []; |
|
|
let selectedTerm = null; |
|
|
let selectedDefinition = null; |
|
|
let lastMatchedTerm = null; |
|
|
let lastMatchedDefinition = null; |
|
|
let matchedPairs = 0; |
|
|
let attempts = 0; |
|
|
let canSelect = true; |
|
|
let timerInterval = null; |
|
|
let secondsRemaining = LEVELS[0].time; |
|
|
let gameOver = false; |
|
|
let currentLevel = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function shuffle(array) { |
|
|
const a = [...array]; |
|
|
for (let i = a.length - 1; i > 0; i--) { |
|
|
const j = Math.floor(Math.random() * (i + 1)); |
|
|
[a[i], a[j]] = [a[j], a[i]]; |
|
|
} |
|
|
return a; |
|
|
} |
|
|
|
|
|
function selectRandomTerms() { |
|
|
return shuffle(allGlossaryData).slice(0, TERMS_PER_LEVEL); |
|
|
} |
|
|
|
|
|
function formatTime(totalSeconds) { |
|
|
const m = Math.floor(totalSeconds / 60); |
|
|
const s = totalSeconds % 60; |
|
|
return `${m}:${s.toString().padStart(2, '0')}`; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateLevelDisplay() { |
|
|
for (let i = 0; i < LEVELS.length; i++) { |
|
|
const label = document.getElementById(`level-label-${i}`); |
|
|
label.className = 'level-label'; |
|
|
if (i < currentLevel) label.classList.add('completed'); |
|
|
else if (i === currentLevel) label.classList.add('active'); |
|
|
|
|
|
|
|
|
if (i < LEVELS.length - 1) { |
|
|
const conn = document.getElementById(`level-conn-${i}`); |
|
|
conn.className = 'level-connector'; |
|
|
if (i < currentLevel) conn.classList.add('completed'); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
function hideAllMessages() { |
|
|
['levelCompleteMessage', 'winMessage', 'loseMessage'].forEach(id => |
|
|
document.getElementById(id).classList.remove('show') |
|
|
); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createCards() { |
|
|
termCards = glossaryData.map((item, i) => ({ |
|
|
id: `term-${i}`, type: 'term', content: item.term, pairId: i |
|
|
})); |
|
|
definitionCards = glossaryData.map((item, i) => ({ |
|
|
id: `def-${i}`, type: 'definition', content: item.definition, pairId: i |
|
|
})); |
|
|
termCards = shuffle(termCards); |
|
|
definitionCards = shuffle(definitionCards); |
|
|
} |
|
|
|
|
|
function renderBoard() { |
|
|
const tb = document.getElementById('termsBoard'); |
|
|
const db = document.getElementById('definitionsBoard'); |
|
|
tb.innerHTML = ''; |
|
|
db.innerHTML = ''; |
|
|
termCards.forEach(c => tb.appendChild(createCardElement(c))); |
|
|
definitionCards.forEach(c => db.appendChild(createCardElement(c))); |
|
|
} |
|
|
|
|
|
function createCardElement(card) { |
|
|
const el = document.createElement('div'); |
|
|
el.className = 'card'; |
|
|
el.dataset.id = card.id; |
|
|
el.dataset.pairId = card.pairId; |
|
|
el.dataset.type = card.type; |
|
|
el.innerHTML = ` |
|
|
<div class="card-inner"> |
|
|
<div class="card-front"></div> |
|
|
<div class="card-back ${card.type}"> |
|
|
<div class="content">${card.content}</div> |
|
|
</div> |
|
|
</div>`; |
|
|
el.addEventListener('click', () => handleCardClick(el, card)); |
|
|
return el; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleCardClick(cardEl, card) { |
|
|
if (!canSelect || gameOver) return; |
|
|
if (cardEl.classList.contains('matched') || cardEl.classList.contains('removed')) return; |
|
|
|
|
|
cardEl.classList.add('flipped'); |
|
|
|
|
|
if (card.type === 'term') { |
|
|
if (selectedTerm && selectedTerm !== cardEl) { |
|
|
selectedTerm.classList.remove('selected'); |
|
|
if (!selectedDefinition) selectedTerm.classList.remove('flipped'); |
|
|
} |
|
|
cardEl.classList.add('selected'); |
|
|
selectedTerm = cardEl; |
|
|
} else { |
|
|
if (selectedDefinition && selectedDefinition !== cardEl) { |
|
|
selectedDefinition.classList.remove('selected'); |
|
|
if (!selectedTerm) selectedDefinition.classList.remove('flipped'); |
|
|
} |
|
|
cardEl.classList.add('selected'); |
|
|
selectedDefinition = cardEl; |
|
|
} |
|
|
|
|
|
if (selectedTerm && selectedDefinition) { |
|
|
attempts++; |
|
|
document.getElementById('attempts').textContent = attempts; |
|
|
checkMatch(); |
|
|
} |
|
|
} |
|
|
|
|
|
function checkMatch() { |
|
|
canSelect = false; |
|
|
|
|
|
if (selectedTerm.dataset.pairId === selectedDefinition.dataset.pairId) { |
|
|
|
|
|
|
|
|
if (lastMatchedTerm && lastMatchedDefinition) { |
|
|
lastMatchedTerm.classList.add('removing'); |
|
|
lastMatchedDefinition.classList.add('removing'); |
|
|
setTimeout(() => { |
|
|
lastMatchedTerm.classList.add('removed'); |
|
|
lastMatchedTerm.classList.remove('removing'); |
|
|
lastMatchedDefinition.classList.add('removed'); |
|
|
lastMatchedDefinition.classList.remove('removing'); |
|
|
}, 500); |
|
|
} |
|
|
|
|
|
setTimeout(() => { |
|
|
selectedTerm.classList.add('matched'); |
|
|
selectedTerm.classList.remove('selected'); |
|
|
selectedDefinition.classList.add('matched'); |
|
|
selectedDefinition.classList.remove('selected'); |
|
|
|
|
|
lastMatchedTerm = selectedTerm; |
|
|
lastMatchedDefinition = selectedDefinition; |
|
|
|
|
|
matchedPairs++; |
|
|
document.getElementById('matches').textContent = `${matchedPairs} / ${TERMS_PER_LEVEL}`; |
|
|
|
|
|
selectedTerm = null; |
|
|
selectedDefinition = null; |
|
|
canSelect = true; |
|
|
|
|
|
|
|
|
if (matchedPairs === TERMS_PER_LEVEL) { |
|
|
setTimeout(levelComplete, 700); |
|
|
} |
|
|
}, 500); |
|
|
|
|
|
} else { |
|
|
|
|
|
selectedTerm.classList.add('wrong'); |
|
|
selectedDefinition.classList.add('wrong'); |
|
|
setTimeout(() => { |
|
|
selectedTerm.classList.remove('wrong'); |
|
|
selectedDefinition.classList.remove('wrong'); |
|
|
setTimeout(() => { |
|
|
selectedTerm.classList.remove('flipped', 'selected'); |
|
|
selectedDefinition.classList.remove('flipped', 'selected'); |
|
|
selectedTerm = null; |
|
|
selectedDefinition = null; |
|
|
canSelect = true; |
|
|
}, 300); |
|
|
}, 800); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function levelComplete() { |
|
|
clearInterval(timerInterval); |
|
|
gameOver = true; |
|
|
|
|
|
if (currentLevel < LEVELS.length - 1) { |
|
|
|
|
|
const nextNum = currentLevel + 2; |
|
|
const nextTime = LEVELS[currentLevel + 1].time; |
|
|
|
|
|
document.getElementById('levelCompleteTitle').textContent = |
|
|
`🎉 Level ${currentLevel + 1} Complete!`; |
|
|
|
|
|
if (nextNum === LEVELS.length) { |
|
|
|
|
|
document.getElementById('levelCompleteSubtitle').textContent = |
|
|
`Ready for the final challenge? You'll have ${formatTime(nextTime)} this time.`; |
|
|
document.getElementById('nextLevelBtn').textContent = '⚡ Final Level →'; |
|
|
} else { |
|
|
document.getElementById('levelCompleteSubtitle').textContent = |
|
|
`Ready for Level ${nextNum}? You'll have ${formatTime(nextTime)} this time.`; |
|
|
document.getElementById('nextLevelBtn').textContent = `Go to Level ${nextNum} →`; |
|
|
} |
|
|
|
|
|
document.getElementById('levelCompleteMessage').classList.add('show'); |
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
|
currentLevel = LEVELS.length; |
|
|
updateLevelDisplay(); |
|
|
document.getElementById('winMessage').classList.add('show'); |
|
|
} |
|
|
} |
|
|
|
|
|
function gameLost() { |
|
|
clearInterval(timerInterval); |
|
|
gameOver = true; |
|
|
canSelect = false; |
|
|
document.getElementById('loseMessage').classList.add('show'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateTimer() { |
|
|
secondsRemaining--; |
|
|
if (secondsRemaining <= 0) { |
|
|
document.getElementById('timer').textContent = '0:00'; |
|
|
gameLost(); |
|
|
return; |
|
|
} |
|
|
const timerEl = document.getElementById('timer'); |
|
|
timerEl.textContent = formatTime(secondsRemaining); |
|
|
|
|
|
timerEl.classList.toggle('warning', secondsRemaining <= 30); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function startNewGame() { |
|
|
currentLevel = 0; |
|
|
initLevel(); |
|
|
} |
|
|
|
|
|
function nextLevel() { |
|
|
currentLevel++; |
|
|
initLevel(); |
|
|
} |
|
|
|
|
|
function retryLevel() { |
|
|
initLevel(); |
|
|
} |
|
|
|
|
|
function initLevel() { |
|
|
|
|
|
selectedTerm = null; |
|
|
selectedDefinition = null; |
|
|
lastMatchedTerm = null; |
|
|
lastMatchedDefinition = null; |
|
|
matchedPairs = 0; |
|
|
attempts = 0; |
|
|
canSelect = true; |
|
|
gameOver = false; |
|
|
secondsRemaining = LEVELS[currentLevel].time; |
|
|
|
|
|
|
|
|
glossaryData = selectRandomTerms(); |
|
|
|
|
|
|
|
|
hideAllMessages(); |
|
|
updateLevelDisplay(); |
|
|
document.getElementById('matches').textContent = `0 / ${TERMS_PER_LEVEL}`; |
|
|
document.getElementById('attempts').textContent = '0'; |
|
|
document.getElementById('timer').textContent = formatTime(secondsRemaining); |
|
|
document.getElementById('timer').classList.remove('warning'); |
|
|
|
|
|
|
|
|
clearInterval(timerInterval); |
|
|
timerInterval = setInterval(updateTimer, 1000); |
|
|
|
|
|
|
|
|
createCards(); |
|
|
renderBoard(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function shuffleCards() { |
|
|
if (matchedPairs === TERMS_PER_LEVEL || gameOver) return; |
|
|
|
|
|
|
|
|
if (selectedTerm) { |
|
|
selectedTerm.classList.remove('flipped', 'selected'); |
|
|
selectedTerm = null; |
|
|
} |
|
|
if (selectedDefinition) { |
|
|
selectedDefinition.classList.remove('flipped', 'selected'); |
|
|
selectedDefinition = null; |
|
|
} |
|
|
|
|
|
|
|
|
const unmatchedTerms = termCards.filter(c => { |
|
|
const el = document.querySelector(`[data-id="${c.id}"]`); |
|
|
return el && !el.classList.contains('matched') && !el.classList.contains('removed'); |
|
|
}); |
|
|
const unmatchedDefs = definitionCards.filter(c => { |
|
|
const el = document.querySelector(`[data-id="${c.id}"]`); |
|
|
return el && !el.classList.contains('matched') && !el.classList.contains('removed'); |
|
|
}); |
|
|
|
|
|
const shuffledTerms = shuffle(unmatchedTerms); |
|
|
const shuffledDefs = shuffle(unmatchedDefs); |
|
|
|
|
|
let ti = 0, di = 0; |
|
|
termCards = termCards.map(c => { |
|
|
const el = document.querySelector(`[data-id="${c.id}"]`); |
|
|
if (el && (el.classList.contains('matched') || el.classList.contains('removed'))) return c; |
|
|
return shuffledTerms[ti++] || c; |
|
|
}); |
|
|
definitionCards = definitionCards.map(c => { |
|
|
const el = document.querySelector(`[data-id="${c.id}"]`); |
|
|
if (el && (el.classList.contains('matched') || el.classList.contains('removed'))) return c; |
|
|
return shuffledDefs[di++] || c; |
|
|
}); |
|
|
|
|
|
renderBoard(); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showHint() { |
|
|
if (matchedPairs === TERMS_PER_LEVEL || !canSelect || gameOver) return; |
|
|
|
|
|
for (let i = 0; i < TERMS_PER_LEVEL; i++) { |
|
|
const termEl = document.querySelector(`[data-id="term-${i}"]`); |
|
|
const defEl = document.querySelector(`[data-id="def-${i}"]`); |
|
|
if (termEl && !termEl.classList.contains('matched') && !termEl.classList.contains('removed')) { |
|
|
termEl.classList.add('flipped'); |
|
|
defEl.classList.add('flipped'); |
|
|
setTimeout(() => { |
|
|
if (!termEl.classList.contains('matched')) termEl.classList.remove('flipped'); |
|
|
if (!defEl.classList.contains('matched')) defEl.classList.remove('flipped'); |
|
|
}, 1500); |
|
|
break; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
startNewGame(); |
|
|
</script> |
|
|
</body> |
|
|
</html> |