Compare commits

...

10 Commits

Author SHA1 Message Date
Elmar Kresse
0f1b0b6fd4 feat: Add script to generate AWS CCP practice exam Anki deck and initial deck file. 2025-12-29 23:34:16 +01:00
Kanani Nirav
aa36e26a12 [Modify] Answer correction and remove scripts tags 2025-09-24 21:35:08 +09:00
Kanani Nirav
80479c276e [Modify] Typo fix 2025-09-17 12:01:35 +09:00
Kanani Nirav
024406c289 [Modify] Update footer link text from "Terms & Conditions" to "Terms of Service" 2025-09-10 18:17:48 +09:00
Kanani Nirav
ef04d52898 [Add] Introduce About Us page and link in footer 2025-09-10 17:53:45 +09:00
Kanani Nirav
42034211b8 [Add] Create About, Contact Us, Privacy Policy, and Terms & Conditions pages 2025-09-10 17:46:56 +09:00
Kanani Nirav
401cd8f26e [Modify] Update ads with ezoic network entries 2025-06-22 21:17:05 +09:00
Kanani Nirav
67628d834b [Modify] Comment out Google Ads script 2025-06-22 08:16:49 +09:00
Kanani Nirav
ec54884308 [Modify] Remove Google Ads entry from ads.txt and add ezoic scripts 2025-06-22 08:14:32 +09:00
Kanani Nirav
c21f9562a3 [Modify] Update Ko-fi Support Button in README 2025-03-07 22:29:20 +09:00
13 changed files with 1477 additions and 287 deletions

View File

@@ -73,7 +73,7 @@ Each Section contains a number of units. **Below Table Link** containing informa
### If you find the content of this website interesting and helpful, use the “Buy me a Coffee” link below to buy me a coffee
<script type='text/javascript' src='https://storage.ko-fi.com/cdn/widget/Widget_2.js'></script><script type='text/javascript'>kofiwidget2.init('Support me on Ko-fi', '#26B0A1', 'I2I51B7WW2');kofiwidget2.draw();</script>
<a href='https://ko-fi.com/I2I51B7WW2' target='_blank'><img height='36' style='border:0px;height:36px;' src='https://storage.ko-fi.com/cdn/kofi6.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /></a>
![gif](https://media.giphy.com/media/gTURHJs4e2Ies/giphy.gif)

View File

@@ -10,6 +10,4 @@
gtag('config', 'G-JMDDTT0Y7C');
</script>
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7252354354222007"
crossorigin="anonymous"></script>

View File

@@ -63,9 +63,12 @@
<footer class="site-footer">
{% if site.github.is_project_page %}
<!-- <span class="site-footer-owner"><a href="{{ site.github.repository_url }}">{{ site.github.repository_name }}</a> is maintained by <a href="{{ site.github.owner_url }}">{{ site.github.owner_name }}</a>.</span> -->
<span class="site-footer-owner">Made with ❤️ by <a href="{{ site.github.owner_url }}" target="_blank">Nirav Kanani</a></span>
<span class="site-footer-owner">Made with ❤️ by <a href="{{ site.github.owner_url }}" target="_blank">Nirav Kanani</a> &nbsp; | &nbsp;
<a href="/privacy-policy/">Privacy Policy</a> &nbsp; | &nbsp;
<a href="/terms-and-conditions/">Terms of Service</a> &nbsp; | &nbsp;
<a href="/contact-us/">Contact Us</a> &nbsp; | &nbsp;
<a href="/about-us/">About Us</a></span>
{% endif %}
<!-- <span class="site-footer-credits">This page was generated by <a href="https://pages.github.com">GitHub Pages</a>.</span> -->
</footer>
<script type="text/javascript">
window.addEventListener('load', function () {

20
about-us.md Normal file
View File

@@ -0,0 +1,20 @@
---
layout: default
permalink: /about-us/
---
# About Us
Welcome to **{{ site.title }}** 👋
We are passionate about providing **developer resources, certification revision short notes, cheat sheets, blogs, and useful guides** to help learners, engineers, and tech professionals grow in their careers.
## Our Mission
- 📘 Deliver clear, concise, and practical knowledge
- 🚀 Support developers with quick reference guides and real-world solutions
- 🌍 Build a community of continuous learners
Whether youre preparing for a certification, brushing up on concepts, or exploring new technologies, **{{ site.title }}** is here to make learning easier and faster.
If you have suggestions, questions, or collaboration ideas, feel free to reach out via our **[Contact page](/contact-us/)**.

126
ads.txt
View File

@@ -1 +1,125 @@
google.com, pub-7252354354222007, DIRECT, f08c47fec0942fa0
ezoic.ai, 307c6a725eef832fab75d1ce22222f66, DIRECT
# 35
themediagrid.com, 4M5PGT, DIRECT, 35d5010d7789b49d
themediagrid.com, Q19AKF, DIRECT, 35d5010d7789b49d
sonobi.com, 192ecdea01, RESELLER, d1a215d9eb5aee9e
google.com, pub-6644558441501035, DIRECT, f08c47fec0942fa0
google.com, pub-1175987143200523, RESELLER, f08c47fec0942fa0
# 36
sharethrough.com, PmzCMtAd, DIRECT, d53b998a7bd4ecd2
google.com, pub-9508156287817487, RESELLER, f08c47fec0942fa0
improvedigital.com, 2483, RESELLER
inmobi.com, 6b1465d6abe84397bf7baad04aaee1f1, DIRECT, 83e75a7ae333ca9d
sonobi.com, c2988be809, RESELLER, d1a215d9eb5aee9e
# 10015
openx.com, 540310748, DIRECT, 6a698e2ec38604c6
appnexus.com, 1019, RESELLER, f5ab79cb980f11d1
openx.com, 537121708, DIRECT, 6a698e2ec38604c6
openx.com, 558427428, DIRECT, 6a698e2ec38604c6
openx.com, 559783383, DIRECT, 6a698e2ec38604c6
# 10017
lijit.com, 62299-eb, DIRECT, fafdf38b16bf6b2b
lijit.com, 62299, DIRECT, fafdf38b16bf6b2b
video.unrulymedia.com, 2444764291, RESELLER
contextweb.com, 558511, RESELLER, 89ff185a4c4e857c
# 10033
yahoo.com, 55771, RESELLER, e1a5b5b6e3255540
conversantmedia.com, 29686, DIRECT, 03113cd04947736d
# 10048
sonobi.com, f4e5b5299c, DIRECT, d1a215d9eb5aee9e
# 10050
criteo.com, B-062427, DIRECT, 9fac4a4a87c2a44f
themediagrid.com, 2RT75Y, DIRECT, 35d5010d7789b49d
# 10061
pubmatic.com, 156983, DIRECT, 5d62403b186f2ace
pubmatic.com, 160020, DIRECT, 5d62403b186f2ace
pubmatic.com, 162833, DIRECT, 5d62403b186f2ace
# 10063
rubiconproject.com, 21152, DIRECT, 0bfd66d529a55807
rubiconproject.com, 21150, DIRECT, 0bfd66d529a55807
# 10079
gumgum.com, 13457, DIRECT, ffdef49475d318a9
# 10082
indexexchange.com, 187973, DIRECT, 50b1c356f2c5c8fc
indexexchange.com, 188161, DIRECT, 50b1c356f2c5c8fc
# 10087
appnexus.com, 7620, DIRECT
# 10097
video.unrulymedia.com, 3149050999, DIRECT
video.unrulymedia.com, 1346664749, DIRECT
video.unrulymedia.com, 469403698, DIRECT
# 11290
amxrtb.com, 105199335, DIRECT
appnexus.com, 12290, RESELLER
lijit.com, 260380, RESELLER
pubmatic.com, 158355, RESELLER
openx.com, 559680764, RESELLER
sharethrough.com, a6a34444, RESELLER, d53b998a7bd4ecd2
# 11291
appnexus.com, 13099, RESELLER
onetag.com, 62499636face9dc, DIRECT
onetag.com, 62499636face9dc-OB, DIRECT
pubmatic.com, 161593, RESELLER, 5d62403b186f2ace
rubiconproject.com, 11006, RESELLER, 0bfd66d529a55807
smartadserver.com, 4111, RESELLER
# 11294
onlinemediasolutions.com, 20305, DIRECT
# 11296
triplelift.com, 9733, DIRECT, 6c33edb13117fd86
# 11297
teads.tv, 13877, DIRECT, 15a9c44f6d26cbe1
# 11301
contextweb.com, 562406, DIRECT, 89ff185a4c4e857c
# 11307
media.net, 8CUBCB617, DIRECT
openx.com, 537100188, RESELLER, 6a698e2ec38604c6
pubmatic.com, 159463, RESELLER, 5d62403b186f2ace
rubiconproject.com, 19396, Reseller, 0bfd66d529a55807
onetag.com, 5d49f482552c9b6, Reseller
pubmatic.com, 164187, RESELLER, 5d62403b186f2ace
rubiconproject.com, 26144, RESELLER, 0bfd66d529a55807
amxrtb.com, 105199734, RESELLER
openx.com, 559911747, RESELLER, 6a698e2ec38604c6
yieldmo.com, 3377199372461613093, RESELLER
onetag.com, 87f58fe90234d0e, RESELLER
# 11309
pubmatic.com, 156557, RESELLER
rubiconproject.com, 18694, RESELLER, 0bfd66d529a55807
openx.com, 540274407, RESELLER, 6a698e2ec38604c6
33across.com, 0013300001kQj2HAAS, RESELLER, bbea06d9c4d2853c
smaato.com, 1100047713, RESELLER, 07bcf65f187117b4
smartadserver.com, 4342, RESELLER
sharethrough.com, b18911a2, DIRECT, d53b998a7bd4ecd2
sharethrough.com, zhQZ2Tfv, DIRECT, d53b998a7bd4ecd2
# 11314
adyoulike.com, ad8c19559e1f2d3424eb0be801d8e184, DIRECT
# 11315
rubiconproject.com, 17070, RESELLER, 0bfd66d529a55807
pubmatic.com, 160648, RESELLER, 5d62403b186f2ace
contextweb.com, 561118, RESELLER, 89ff185a4c4e857c
appnexus.com, 7911, RESELLER
video.unrulymedia.com, 3463482822, RESELLER
yieldmo.com, 2723393041019642186, DIRECT
yieldmo.com, 2834292204858450860, DIRECT
yieldmo.com, 2676856567361380607, DIRECT
# 11321
33across.com, 0010b00002MpnPqAAJ, DIRECT, bbea06d9c4d2853c
appnexus.com, 10239, RESELLER, f5ab79cb980f11d1
contextweb.com, 561516, RESELLER, 89ff185a4c4e857c
conversantmedia.com, 100141, RESELLER
openx.com, 537120563, RESELLER, 6a698e2ec38604c6
pubmatic.com, 156423, RESELLER, 5d62403b186f2ace
rubiconproject.com, 16414, RESELLER, 0bfd66d529a55807
rubiconproject.com, 21642, RESELLER, 0bfd66d529a55807
triplelift.com, 12503, RESELLER, 6c33edb13117fd86
video.unrulymedia.com, 2439829435, RESELLER
adyoulike.com, 1f301d3bcd723f5c372070bdfd142940, RESELLER
# 11325
risecodes.com, 608fee2f84a3a300011acd3f, DIRECT
pubmatic.com, 160295, RESELLER, 5d62403b186f2ace
appnexus.com, 14082, RESELLER
rubiconproject.com, 23876, RESELLER, 0bfd66d529a55807
sharethrough.com, 5926d422, RESELLER, d53b998a7bd4ecd2
# 11335
smartadserver.com, 4503-OB, DIRECT, 060d053dcf45cbf3
smartadserver.com, 4503, DIRECT, 060d053dcf45cbf3

161
contact-us.html Normal file
View File

@@ -0,0 +1,161 @@
---
layout: default
title: Contact Us
permalink: /contact-us/
---
<h5>For all questions and suggestions Contact Us using below form. Form submission may take time, so please be patient 😄⏳</h5>
<div class="formbold-main-wrapper">
<div class="formbold-form-wrapper">
<form name="submit-to-google-sheet">
<div class="formbold-mb-5">
<label for="name"> Full Name </label>
<input
type="text"
name="Name"
id="name"
placeholder="Full Name"
class="formbold-form-input"
required=true
/>
</div>
<div class="formbold-mb-5">
<label for="email"> Email Address </label>
<input
type="email"
name="Email"
id="email"
placeholder="Enter your email"
class="formbold-form-input"
required=true
/>
</div>
<div class="formbold-mb-5">
<label for="subject"> Subject </label>
<input
type="text"
name="Subject"
id="subject"
placeholder="Enter your subject"
class="formbold-form-input"
required=true
/>
</div>
<div class="formbold-mb-5">
<label for="message"> Message </label>
<textarea
rows="6"
name="Message"
id="message"
placeholder="Type your message"
class="formbold-form-input"
required=true
></textarea>
</div>
<div>
<input type="hidden" id="site" name="Site" value="https://kananinirav.com">
<button class="formbold-btn">Submit</button>
</div>
</form>
<span id="msg"></span>
</div>
</div>
<script>
const scriptURL = 'https://script.google.com/macros/s/AKfycbxQFTlTZ3w-uvQPhq4-_Thbtl6JHYlt0J4BwfIZ1LeWT9bkcAMt0kMNT51soz5UWuHS/exec'
const form = document.forms['submit-to-google-sheet']
const msg = document.getElementById("msg")
form.addEventListener('submit', e => {
e.preventDefault()
fetch(scriptURL, { method: 'POST', body: new FormData(form)})
.then(response => {
msg.innerHTML = "Thank you for contacting us! We have received your message and will respond as soon as possible. In the meantime, feel free to explore our website. Have a great day!"
setTimeout(() => {
msg.innerHTML = ""
}, 15000);
form.reset();
})
.catch(error => console.error('Error!', error.message))
})
</script>
<style>
.formbold-mb-5 {
margin-bottom: 20px;
}
.formbold-pt-3 {
padding-top: 12px;
}
.formbold-main-wrapper {
display: flex;
align-items: center;
justify-content: center;
padding: 1rem;
}
.formbold-form-wrapper {
margin: 0 auto;
/* max-width: 550px; */
width: 100%;
background: white;
}
.formbold-form-input {
width: 100%;
padding: 12px 24px;
border-radius: 6px;
border: 1px solid #e0e0e0;
background: white;
font-weight: 500;
font-size: 16px;
color: #6b7280;
outline: none;
resize: none;
}
.formbold-form-input:focus {
border-color: #159957;
box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.05);
}
.formbold-btn {
text-align: center;
color: white;
font-size: 16px;
border-radius: 6px;
padding: 14px 32px;
border: none;
font-weight: 600;
background-color: #159957;
cursor: pointer;
}
.formbold--mx-3 {
margin-left: -12px;
margin-right: -12px;
}
.formbold-px-3 {
padding-left: 12px;
padding-right: 12px;
}
.flex {
display: flex;
}
.flex-wrap {
flex-wrap: wrap;
}
.w-full {
width: 100%;
}
@media (min-width: 540px) {
.sm\:w-half {
width: 50%;
}
}
#msg{
margin-top: 10px;
display: block;
}
</style>

Binary file not shown.

View File

@@ -0,0 +1,781 @@
"""
AWS Certified Cloud Practitioner Practice Exam to Anki Deck Converter
This script parses practice exam markdown files and generates Anki decks.
"""
import re
import os
import glob
import random
import genanki
def generate_unique_id():
"""Generate a unique ID for Anki models and decks."""
return random.randrange(1 << 30, 1 << 31)
# Define the Anki card model with interactive quiz functionality
AWS_MODEL = genanki.Model(
generate_unique_id(),
'AWS Practice Exam Interactive Model',
fields=[
{'name': 'Question'},
{'name': 'OptionsHTML'},
{'name': 'Answer'},
{'name': 'Source'},
{'name': 'IsMultiple'}, # "true" or "false" - whether multiple answers are expected
],
templates=[
{
'name': 'Interactive Quiz Card',
'qfmt': '''
<div class="question">{{Question}}</div>
<hr>
<div class="hint-text" id="hintText"></div>
<div class="options-container" id="options">{{OptionsHTML}}</div>
<div class="button-container">
<button id="checkBtn" onclick="checkAnswer()">Antwort prüfen ✓</button>
</div>
<script>
var correctAnswer = "{{Answer}}";
var isMultiple = "{{IsMultiple}}" === "true";
// Toggle option when clicking on the entire box
function toggleOption(event, element) {
var input = element.querySelector('input');
if (input.type === 'checkbox') {
input.checked = !input.checked;
} else {
input.checked = true;
}
}
// Set hint text based on number of answers
(function() {
var hintDiv = document.getElementById('hintText');
if (isMultiple) {
var numAnswers = correctAnswer.split(',').length;
hintDiv.innerHTML = '💡 Wähle ' + numAnswers + ' Antworten aus';
hintDiv.style.display = 'block';
}
})();
function getSelectedAnswers() {
var selected = [];
var inputs = document.querySelectorAll('input[name="answer"]:checked');
inputs.forEach(function(input) {
selected.push(input.value);
});
return selected.sort().join(", ");
}
function checkAnswer() {
var selected = getSelectedAnswers();
if (selected === "") {
alert("Bitte wähle mindestens eine Antwort aus!");
return;
}
// Store the result for the back side
var normalizedCorrect = correctAnswer.replace(/\\s/g, "").toUpperCase().split(",").sort().join(",");
var normalizedSelected = selected.replace(/\\s/g, "").toUpperCase().split(",").sort().join(",");
var isCorrect = normalizedSelected === normalizedCorrect;
// Store result in sessionStorage for back side
sessionStorage.setItem('lastAnswer', selected);
sessionStorage.setItem('wasCorrect', isCorrect ? 'true' : 'false');
// Trigger Anki to show the answer
if (typeof pycmd !== 'undefined') {
pycmd('ans');
} else if (typeof AnkiDroidJS !== 'undefined') {
showAnswer();
}
}
</script>
''',
'afmt': '''
<div class="question">{{Question}}</div>
<hr>
<div class="options-container answered" id="options">{{OptionsHTML}}</div>
<div id="result" class="result"></div>
<div class="correct-answer">
<strong>Richtige Antwort:</strong> {{Answer}}
</div>
<hr>
<div class="source">
<em>Quelle: {{Source}}</em>
</div>
<div class="rating-container">
<p class="rating-hint" id="ratingHint">Bewerte deine Antwort:</p>
<div class="rating-buttons">
<button class="rating-btn again" onclick="answerCard(1)">Nochmal<br><span class="rating-sub">&lt;1min</span></button>
<button class="rating-btn hard" onclick="answerCard(2)">Schwer<br><span class="rating-sub">&lt;6min</span></button>
<button class="rating-btn good" onclick="answerCard(3)">Gut<br><span class="rating-sub">&lt;10min</span></button>
<button class="rating-btn easy" onclick="answerCard(4)">Einfach<br><span class="rating-sub">4 Tage</span></button>
</div>
</div>
<script>
var correctAnswer = "{{Answer}}";
// Cross-platform answer function for desktop Anki and AnkiDroid
function answerCard(ease) {
// AnkiDroid uses direct functions
if (typeof buttonAnswerEase1 !== 'undefined') {
switch(ease) {
case 1: buttonAnswerEase1(); break;
case 2: buttonAnswerEase2(); break;
case 3: buttonAnswerEase3(); break;
case 4: buttonAnswerEase4(); break;
}
} else if (typeof AnkiDroidJS !== 'undefined') {
// Fallback for older AnkiDroid versions
AnkiDroidJS.ankiAnswerCard(ease);
} else if (typeof pycmd !== 'undefined') {
// Desktop Anki
pycmd('ease' + ease);
}
}
(function() {
var selected = sessionStorage.getItem('lastAnswer') || '';
var wasCorrect = sessionStorage.getItem('wasCorrect') === 'true';
var resultDiv = document.getElementById('result');
var ratingHint = document.getElementById('ratingHint');
// Highlight options
var options = document.querySelectorAll('.option-item');
var correctLetters = correctAnswer.replace(/\\s/g, "").toUpperCase().split(",");
var selectedLetters = selected.replace(/\\s/g, "").toUpperCase().split(",");
options.forEach(function(opt) {
var input = opt.querySelector('input');
if (input) {
var letter = input.value.toUpperCase();
input.disabled = true;
if (correctLetters.includes(letter)) {
opt.classList.add('correct-option');
input.checked = true;
}
if (selectedLetters.includes(letter) && !correctLetters.includes(letter)) {
opt.classList.add('incorrect-option');
input.checked = true;
}
}
});
// Show result
if (selected) {
if (wasCorrect) {
resultDiv.innerHTML = "✅ Richtig!";
resultDiv.className = "result correct";
ratingHint.innerHTML = "🎉 Super! Wie gut hast du es gewusst?";
} else {
resultDiv.innerHTML = "❌ Falsch! Deine Antwort: " + selected;
resultDiv.className = "result incorrect";
ratingHint.innerHTML = "📚 Für nächstes Mal merken:";
}
}
// Clear storage
sessionStorage.removeItem('lastAnswer');
sessionStorage.removeItem('wasCorrect');
})();
</script>
''',
},
],
css='''
.card {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
font-size: 16px;
text-align: left;
color: #333;
background-color: #f8f9fa;
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.question {
font-weight: 600;
margin-bottom: 20px;
font-size: 18px;
color: #232f3e;
line-height: 1.5;
}
.options-container {
margin: 15px 0;
}
.option-item {
display: flex;
align-items: flex-start;
margin: 10px 0;
padding: 12px 15px;
background-color: #fff;
border-radius: 8px;
border: 2px solid #e0e0e0;
cursor: pointer;
transition: all 0.2s ease;
}
.option-item:hover {
border-color: #ff9900;
background-color: #fff8f0;
}
.options-container.answered .option-item:hover {
border-color: inherit;
background-color: inherit;
}
.option-item input {
margin-right: 12px;
margin-top: 3px;
width: 18px;
height: 18px;
cursor: pointer;
accent-color: #ff9900;
}
.option-item label {
cursor: pointer;
flex: 1;
line-height: 1.4;
}
.option-item.correct-option {
border-color: #28a745;
background-color: #d4edda;
}
.option-item.incorrect-option {
border-color: #dc3545;
background-color: #f8d7da;
}
.hint-text {
display: none;
background-color: #e3f2fd;
color: #1565c0;
padding: 10px 15px;
border-radius: 8px;
margin-bottom: 15px;
font-weight: 500;
}
.button-container {
margin: 20px 0;
text-align: center;
}
button {
padding: 12px 30px;
font-size: 16px;
font-weight: 600;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
margin: 5px;
}
#checkBtn {
background: linear-gradient(135deg, #ff9900, #ffad33);
color: #232f3e;
}
#checkBtn:hover {
background: linear-gradient(135deg, #ec8b00, #ff9900);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(255, 153, 0, 0.4);
}
.result {
padding: 15px 20px;
border-radius: 8px;
margin: 15px 0;
font-size: 18px;
font-weight: 600;
text-align: center;
}
.result.correct {
background-color: #d4edda;
color: #155724;
border: 2px solid #28a745;
}
.result.incorrect {
background-color: #f8d7da;
color: #721c24;
border: 2px solid #dc3545;
}
.correct-answer {
padding: 15px 20px;
background-color: #e8f5e9;
border-radius: 8px;
border-left: 4px solid #28a745;
margin: 15px 0;
font-size: 16px;
}
.source {
color: #666;
font-size: 12px;
margin-top: 10px;
text-align: right;
}
.rating-container {
margin-top: 20px;
padding: 20px;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.rating-hint {
text-align: center;
font-size: 16px;
margin-bottom: 15px;
color: #333;
}
.rating-buttons {
display: flex;
justify-content: center;
gap: 10px;
flex-wrap: wrap;
}
.rating-btn {
padding: 15px 20px;
min-width: 80px;
font-size: 14px;
border: none;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
line-height: 1.3;
}
.rating-btn .rating-sub {
font-size: 11px;
opacity: 0.8;
}
.rating-btn.again {
background: #dc3545;
color: white;
}
.rating-btn.again:hover {
background: #c82333;
transform: translateY(-2px);
}
.rating-btn.hard {
background: #fd7e14;
color: white;
}
.rating-btn.hard:hover {
background: #e96b02;
transform: translateY(-2px);
}
.rating-btn.good {
background: #28a745;
color: white;
}
.rating-btn.good:hover {
background: #218838;
transform: translateY(-2px);
}
.rating-btn.easy {
background: #17a2b8;
color: white;
}
.rating-btn.easy:hover {
background: #138496;
transform: translateY(-2px);
}
hr {
border: none;
border-top: 1px solid #dee2e6;
margin: 20px 0;
}
/* Hide custom rating buttons on AnkiDroid/mobile (uses built-in buttons) */
.mobile .rating-container,
.android .rating-container {
display: none !important;
}
/* Dark Mode Styles */
.night_mode .card {
background-color: #1e1e2e;
color: #cdd6f4;
}
.night_mode .question {
color: #cdd6f4;
}
.night_mode .option-item {
background-color: #313244;
border-color: #45475a;
color: #cdd6f4;
}
.night_mode .option-item:hover {
border-color: #fab387;
background-color: #45475a;
}
.night_mode .option-item label {
color: #cdd6f4;
}
.night_mode .option-item.correct-option {
border-color: #a6e3a1;
background-color: rgba(166, 227, 161, 0.2);
}
.night_mode .option-item.incorrect-option {
border-color: #f38ba8;
background-color: rgba(243, 139, 168, 0.2);
}
.night_mode .hint-text {
background-color: rgba(137, 180, 250, 0.2);
color: #89b4fa;
}
.night_mode #checkBtn {
background: linear-gradient(135deg, #fab387, #f9e2af);
color: #1e1e2e;
}
.night_mode #checkBtn:hover {
background: linear-gradient(135deg, #f9e2af, #fab387);
box-shadow: 0 4px 12px rgba(250, 179, 135, 0.4);
}
.night_mode .result.correct {
background-color: rgba(166, 227, 161, 0.2);
color: #a6e3a1;
border-color: #a6e3a1;
}
.night_mode .result.incorrect {
background-color: rgba(243, 139, 168, 0.2);
color: #f38ba8;
border-color: #f38ba8;
}
.night_mode .correct-answer {
background-color: rgba(166, 227, 161, 0.15);
border-left-color: #a6e3a1;
color: #cdd6f4;
}
.night_mode .source {
color: #a6adc8;
}
.night_mode .rating-container {
background-color: #313244;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}
.night_mode .rating-hint {
color: #cdd6f4;
}
.night_mode hr {
border-top-color: #45475a;
}
'''
)
def parse_markdown_file(filepath: str) -> list[dict]:
"""
Parse a practice exam markdown file and extract questions.
Args:
filepath: Path to the markdown file
Returns:
List of dictionaries containing question data
"""
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
questions = []
# Pattern to match each question block
# Questions start with a number followed by a period
question_pattern = r'(\d+)\.\s+(.+?)(?=\n\s*-\s+A\.)'
# Split content by question numbers at the start of lines
question_blocks = re.split(r'\n(?=\d+\.\s)', content)
for block in question_blocks:
if not block.strip():
continue
# Match question number and text
q_match = re.match(r'(\d+)\.\s+(.+?)(?=\n\s*-\s+A\.)', block, re.DOTALL)
if not q_match:
continue
question_num = q_match.group(1)
question_text = q_match.group(2).strip()
# Extract options (A, B, C, D, E)
options = []
option_pattern = r'-\s+([A-E])\.(.+?)(?=(?:\n\s*-\s+[A-E]\.)|\n\s*<details|\Z)'
option_matches = re.findall(option_pattern, block, re.DOTALL)
for letter, text in option_matches:
options.append(f"{letter}. {text.strip()}")
# Extract answer from <details> block
answer_pattern = r'Correct answer:\s*([A-E](?:,\s*[A-E])*)'
answer_match = re.search(answer_pattern, block)
if answer_match and options:
answer = answer_match.group(1).strip()
# Check if multiple answers are expected
is_multiple = ',' in answer
questions.append({
'number': question_num,
'question': question_text,
'options': options,
'answer': answer,
'is_multiple': is_multiple
})
return questions
def create_anki_deck(questions: list[dict], deck_name: str, source_file: str) -> genanki.Deck:
"""
Create an Anki deck from parsed questions.
Args:
questions: List of question dictionaries
deck_name: Name for the Anki deck
source_file: Source file name for reference
Returns:
genanki.Deck object
"""
deck = genanki.Deck(generate_unique_id(), deck_name)
for q in questions:
# Format options as interactive HTML with checkboxes or radio buttons
is_multiple = q.get('is_multiple', False)
input_type = 'checkbox' if is_multiple else 'radio'
options_html_parts = []
for opt in q['options']:
letter = opt[0] # First character is the option letter
text = opt[3:] # Skip "X. " prefix
option_html = f'''<div class="option-item" onclick="toggleOption(event, this)">
<input type="{input_type}" name="answer" value="{letter}" id="opt_{letter}" onclick="event.stopPropagation()">
<label for="opt_{letter}"><strong>{letter}.</strong> {text}</label>
</div>'''
options_html_parts.append(option_html)
options_html = '\n'.join(options_html_parts)
note = genanki.Note(
model=AWS_MODEL,
fields=[
q['question'],
options_html,
q['answer'],
f"{source_file} - Q{q['number']}",
"true" if is_multiple else "false"
]
)
deck.add_note(note)
return deck
def process_single_file(filepath: str, output_dir: str = None):
"""
Process a single practice exam file and create an Anki deck.
Args:
filepath: Path to the markdown file
output_dir: Output directory for the .apkg file (defaults to same as input)
"""
if output_dir is None:
output_dir = os.path.dirname(filepath)
filename = os.path.basename(filepath)
deck_name = f"AWS CCP - {filename.replace('.md', '').replace('-', ' ').title()}"
print(f"Processing: {filename}")
questions = parse_markdown_file(filepath)
print(f" Found {len(questions)} questions")
if questions:
deck = create_anki_deck(questions, deck_name, filename)
output_path = os.path.join(output_dir, filename.replace('.md', '.apkg'))
genanki.Package(deck).write_to_file(output_path)
print(f" Created: {output_path}")
return deck
else:
print(f" No questions found in {filename}")
return None
def process_all_files(directory: str, output_dir: str = None, combined: bool = True):
"""
Process all practice exam files in a directory.
Args:
directory: Directory containing practice exam markdown files
output_dir: Output directory for .apkg files
combined: If True, create a single combined deck; if False, create separate decks
"""
if output_dir is None:
output_dir = directory
pattern = os.path.join(directory, 'practice-exam-*.md')
files = sorted(glob.glob(pattern))
if not files:
print(f"No practice exam files found matching: {pattern}")
return
print(f"Found {len(files)} practice exam files")
if combined:
# Create a combined deck
all_questions = []
for filepath in files:
filename = os.path.basename(filepath)
print(f"Processing: {filename}")
questions = parse_markdown_file(filepath)
# Add source file info to each question
for q in questions:
q['source_file'] = filename
all_questions.extend(questions)
print(f" Found {len(questions)} questions")
print(f"\nTotal questions: {len(all_questions)}")
if all_questions:
deck = genanki.Deck(
generate_unique_id(),
'AWS Certified Cloud Practitioner - All Practice Exams'
)
for q in all_questions:
# Format options as interactive HTML with checkboxes or radio buttons
is_multiple = q.get('is_multiple', False)
input_type = 'checkbox' if is_multiple else 'radio'
options_html_parts = []
for opt in q['options']:
letter = opt[0] # First character is the option letter
text = opt[3:] # Skip "X. " prefix
option_html = f'''<div class="option-item" onclick="toggleOption(event, this)">
<input type="{input_type}" name="answer" value="{letter}" id="opt_{letter}" onclick="event.stopPropagation()">
<label for="opt_{letter}"><strong>{letter}.</strong> {text}</label>
</div>'''
options_html_parts.append(option_html)
options_html = '\n'.join(options_html_parts)
note = genanki.Note(
model=AWS_MODEL,
fields=[
q['question'],
options_html,
q['answer'],
f"{q['source_file']} - Q{q['number']}",
"true" if is_multiple else "false"
]
)
deck.add_note(note)
output_path = os.path.join(output_dir, 'aws-ccp-all-practice-exams.apkg')
genanki.Package(deck).write_to_file(output_path)
print(f"\nCreated combined deck: {output_path}")
else:
# Create separate decks for each file
for filepath in files:
process_single_file(filepath, output_dir)
def main():
"""Main entry point."""
import argparse
parser = argparse.ArgumentParser(
description='Convert AWS Practice Exam markdown files to Anki decks'
)
parser.add_argument(
'input',
nargs='?',
default='.',
help='Input file or directory (default: current directory)'
)
parser.add_argument(
'-o', '--output',
help='Output directory for .apkg files (default: same as input)'
)
parser.add_argument(
'-s', '--separate',
action='store_true',
help='Create separate decks for each file instead of a combined deck'
)
parser.add_argument(
'-f', '--file',
help='Process a single specific file'
)
args = parser.parse_args()
if args.file:
# Process single file
process_single_file(args.file, args.output)
elif os.path.isfile(args.input):
# Input is a file
process_single_file(args.input, args.output)
else:
# Input is a directory
process_all_files(args.input, args.output, combined=not args.separate)
if __name__ == '__main__':
main()

View File

@@ -352,7 +352,7 @@ layout: exam
Correct answer: D
</details>
35. Much AWS services provide a way to extend an on-premises architecture to the AWS Cloud? (Select TWO)
35. Which AWS services provide a way to extend an on-premises architecture to the AWS Cloud? (Select TWO)
- A. Amazon EBS.
- B. AWS Direct Connect.
- C. Amazon CloudFront.

View File

@@ -92,7 +92,7 @@ layout: exam
<details markdown=1><summary markdown="span">Answer</summary>
Correct Answer: B
Correct Answer: A
Explanation: <https://aws.amazon.com/premiumsupport/plans/>

45
privacy-policy.md Normal file
View File

@@ -0,0 +1,45 @@
---
layout: default
permalink: /privacy-policy/
---
# Privacy Policy
**Last Updated:** January 1, 2025
Your privacy is important to us at **{{ site.title }}**. This Privacy Policy explains how we collect, use, and protect your information.
## 1. Information We Collect
- **Personal Information**: Only when you voluntarily provide it (e.g., contact form, email).
- **Non-Personal Information**: Browser type, device information, pages visited, and traffic data.
## 2. Use of Information
We may use collected data to:
- Improve website content and user experience
- Respond to inquiries or feedback
- Display personalized ads through **Google AdSense**
## 3. Google AdSense & Cookies
- Third-party vendors, including Google, use cookies to serve ads based on your previous visits.
- Googles use of advertising cookies enables it and its partners to serve ads based on your browsing activity.
- You can opt out of personalized advertising by visiting [Google Ads Settings](https://www.google.com/settings/ads/).
## 4. Third-Party Links
Our website may include external links. We are not responsible for the privacy practices or content of third-party sites.
## 5. Data Protection
We take reasonable security measures to protect your data. However, no online system is 100% secure, so we cannot guarantee complete protection.
## 6. Updates to This Policy
We may update this Privacy Policy as needed. Any changes will be posted on this page with an updated revision date.
## 7. Contact Us
If you have questions about this Privacy Policy, please contact us via our **[Contact page](/contact-us/)**.

View File

@@ -2,281 +2,304 @@
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<url>
<loc>https://kananinirav.com/</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>1.00</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/cloud_computing.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/iam.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/ec2.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/ec2_storage.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/elb_asg.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/s3.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/databases.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/other_compute.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/deploying.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/global_infrastructure.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/cloud_integration.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/cloud_monitoring.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/vpc.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/security_compliance.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/machine_learning.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/account_management_billing_support.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/advanced_identity.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/other_aws_services.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/sections/architecting_and_ecosystem.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/study-guide.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/exams.html</loc>
<lastmod>2023-10-09T09:00:00+00:00</lastmod>
<priority>1.00</priority>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-1.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-2.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-3.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-4.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-5.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-6.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-7.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-8.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-9.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-10.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-11.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-12.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-13.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-14.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-15.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-16.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-17.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-18.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-19.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-20.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-21.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-22.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/practice-exam/practice-exam-23.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
</url>
<url>
<loc>https://kananinirav.com/mind-map-aws-ccp.html</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
</url>
<url>
<loc>https://kananinirav.com/contact-us/</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://kananinirav.com/privacy-policy/</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://kananinirav.com/terms-and-conditions/</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
<url>
<loc>https://kananinirav.com/about-us/</loc>
<lastmod>2023-12-01T09:00:00+00:00</lastmod>
<priority>0.80</priority>
<changefreq>daily</changefreq>
</url>
</urlset>

35
terms-and-conditions.md Normal file
View File

@@ -0,0 +1,35 @@
---
layout: default
permalink: /terms-and-conditions/
---
# Terms & Conditions
**Last Updated:** January 1, 2025
Welcome to **{{ site.title }}**. By accessing and using this website, you agree to comply with the following terms and conditions.
## 1. Use of the Website
- The content provided on this site is for informational purposes only.
- You agree not to misuse, copy, or redistribute content without prior written permission.
- You are responsible for ensuring your use of this site complies with applicable laws.
## 2. Intellectual Property
- All articles, designs, and resources published here are the intellectual property of {{ site.title }} unless otherwise noted.
- Unauthorized reproduction or distribution of content may result in legal action.
## 3. Third-Party Links & Ads
- Our website may display advertisements (including Google AdSense) and links to third-party sites.
- We are not responsible for the accuracy, reliability, or content of external websites.
## 4. Disclaimer of Liability
- We do not guarantee the accuracy, completeness, or timeliness of the information provided.
- Use of any information is at your own risk.
## 5. Changes to Terms
We reserve the right to update these terms at any time. Continued use of the site means you accept any modifications.