2026-02-18 17:15:31 -07:00

2001 lines
54 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Explore Changemaker Lite's campaign, mapping, media, and communication features.">
<meta name="author" content="Bunker Operations">
<link rel="canonical" href="https://bnkserve.org/docs/features/">
<link rel="prev" href="../getting-started/environment-variables/">
<link rel="next" href="../admin/">
<link rel="icon" href="../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
<title>Feature Guides - Changemaker Lite</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.484c7ddc.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.ab4e12ef.min.css">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
<link rel="stylesheet" href="../../stylesheets/extra.css">
<link rel="stylesheet" href="../../stylesheets/home.css">
<link rel="stylesheet" href="../../assets/css/video-player.css">
<link rel="stylesheet" href="../../assets/css/payment-widgets.css">
<script>__md_scope=new URL("../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
<script>
(function () {
// API URL injected from MkDocs config.extra (set by env_config_hook.py)
var apiUrl = "http://localhost:4002";
if (!apiUrl) return;
var trackUrl = apiUrl + "/api/docs-analytics/track";
// Anonymous session UUID (sessionStorage — dies with tab close, no cookies)
function getSessionHash() {
var key = "__docs_sh";
var hash = sessionStorage.getItem(key);
if (!hash) {
hash = crypto.randomUUID
? crypto.randomUUID()
: "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
var r = (Math.random() * 16) | 0;
return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
});
sessionStorage.setItem(key, hash);
}
return hash;
}
function trackPageView(path) {
var payload = JSON.stringify({
path: path,
referrer: document.referrer || undefined,
sessionHash: getSessionHash(),
});
// Prefer sendBeacon for reliability (works during tab close)
if (navigator.sendBeacon) {
navigator.sendBeacon(trackUrl, new Blob([payload], { type: "application/json" }));
} else {
fetch(trackUrl, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: payload,
keepalive: true,
}).catch(function () {});
}
}
// Track initial page load
trackPageView(location.pathname);
// Subscribe to Material's SPA navigation observable (instant loading)
if (typeof document$ !== "undefined") {
document$.subscribe(function () {
trackPageView(location.pathname);
});
}
})();
</script>
<script>"undefined"!=typeof __md_analytics&&__md_analytics()</script>
<meta property="og:type" content="website" />
<meta property="og:title" content="Feature Guides - Changemaker Lite" />
<meta property="og:description" content="Explore Changemaker Lite's campaign, mapping, media, and communication features." />
<meta property="og:image" content="https://bnkserve.org/assets/images/social/docs/features/index.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta property="og:url" content="https://bnkserve.org/docs/features/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Feature Guides - Changemaker Lite" />
<meta property="twitter:description" content="Explore Changemaker Lite's campaign, mapping, media, and communication features." />
<meta property="twitter:image" content="https://bnkserve.org/assets/images/social/docs/features/index.png" />
</head>
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber">
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" for="__drawer"></label>
<div data-md-component="skip">
<a href="#feature-guides" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
<aside class="md-banner">
<div class="md-banner__inner md-grid md-typeset">
<button class="md-banner__button md-icon" aria-label="Don't show this again">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<nav class="cm-header-nav" role="navigation" aria-label="Application">
<div class="cm-header-nav__inner">
<a href="#" data-path="/campaigns" class="cm-header-nav__link">
<span class="material-icons">campaign</span>
<span class="cm-header-nav__label">Campaigns</span>
</a>
<a href="#" data-path="/map" class="cm-header-nav__link">
<span class="material-icons">map</span>
<span class="cm-header-nav__label">Map</span>
</a>
<a href="#" data-path="/shifts" class="cm-header-nav__link">
<span class="material-icons">groups</span>
<span class="cm-header-nav__label">Volunteer</span>
</a>
<a href="#" data-path="/gallery" class="cm-header-nav__link">
<span class="material-icons">play_circle</span>
<span class="cm-header-nav__label">Gallery</span>
</a>
<a href="#" data-path="/responses" class="cm-header-nav__link">
<span class="material-icons">forum</span>
<span class="cm-header-nav__label">Responses</span>
</a>
<a href="#" data-path="/donate" class="cm-header-nav__link">
<span class="material-icons">favorite</span>
<span class="cm-header-nav__label">Donate</span>
</a>
<a href="#" data-path="/login" class="cm-header-nav__link">
<span class="material-icons">login</span>
<span class="cm-header-nav__label">Sign In</span>
</a>
</div>
</nav>
<script>
// Resolve nav link hrefs based on the current browser hostname.
// localhost → http://localhost:{ADMIN_PORT}
// subdomain.example.org → {proto}://app.example.org
(function() {
var h = location.hostname;
var base;
if (h === 'localhost' || h === '127.0.0.1') {
base = location.protocol + '//localhost:' + (3002 || 3000);
} else {
var parts = h.split('.');
if (parts.length >= 3) { parts[0] = 'app'; }
else { parts.unshift('app'); }
base = location.protocol + '//' + parts.join('.');
}
var links = document.querySelectorAll('.cm-header-nav__link[data-path]');
for (var i = 0; i < links.length; i++) {
links[i].setAttribute('href', base + links[i].getAttribute('data-path'));
}
})();
</script>
<style>
/* Override MkDocs Material announce bar container */
.md-banner {
background: #6f42c1 !important;
color: #ffffff !important;
}
/* Hide the dismiss (X) button that Material adds for announce.dismiss */
.md-banner__button {
display: none !important;
}
.cm-header-nav {
background: #6f42c1;
min-height: 40px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 24px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
z-index: 10;
}
.cm-header-nav__inner {
display: flex;
align-items: center;
gap: 6px;
max-width: 1400px;
width: 100%;
justify-content: center;
flex-wrap: nowrap;
overflow-x: auto;
}
.cm-header-nav__link {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 16px;
color: #ffffff;
text-decoration: none;
font-size: 0.8rem;
font-weight: 600;
letter-spacing: 0.02em;
border-radius: 6px;
background: rgba(255, 255, 255, 0.12);
transition: background 0.15s, transform 0.1s;
white-space: nowrap;
line-height: 1;
}
.cm-header-nav__link:hover {
background: rgba(255,255,255,0.15);
color: #ffffff;
text-decoration: none;
transform: translateY(-1px);
}
.cm-header-nav__link:active {
transform: translateY(0);
}
.cm-header-nav__link .material-icons {
font-size: 16px;
opacity: 0.9;
}
@media (max-width: 768px) {
.cm-header-nav { padding: 0 8px; }
.cm-header-nav__label { display: none; }
.cm-header-nav__link { padding: 8px 10px; }
.cm-header-nav__inner { gap: 4px; }
}
</style>
</div>
<script>var el=document.querySelector("[data-md-component=announce]");if(el){var content=el.querySelector(".md-typeset");__md_hash(content.innerHTML)===__md_get("__announce")&&(el.hidden=!0)}</script>
</aside>
</div>
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
<nav class="md-header__inner md-grid" aria-label="Header">
<a href="../.." title="Changemaker Lite" class="md-header__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../assets/logo.png" alt="logo">
</a>
<label class="md-header__button md-icon" for="__drawer">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
</label>
<div class="md-header__title" data-md-component="header-title">
<div class="md-header__ellipsis">
<div class="md-header__topic">
<span class="md-ellipsis">
Changemaker Lite
</span>
</div>
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
Feature Guides
</span>
</div>
</div>
</div>
<form class="md-header__option" data-md-component="palette">
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
</label>
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
</label>
</form>
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
<label class="md-header__button md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
</label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
<label class="md-search__icon md-icon" for="__search">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</label>
<nav class="md-search__options" aria-label="Search">
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
</a>
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
</button>
</nav>
<div class="md-search__suggest" data-md-component="search-suggest"></div>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
<div class="md-search-result" data-md-component="search-result">
<div class="md-search-result__meta">
Initializing search
</div>
<ol class="md-search-result__list" role="presentation"></ol>
</div>
</div>
</div>
</div>
</div>
<div class="md-header__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
</nav>
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
<div class="md-grid">
<ul class="md-tabs__list">
<li class="md-tabs__item">
<a href="../.." class="md-tabs__link">
Home
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../" class="md-tabs__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.5c-1.35-.85-3.8-1.5-5.5-1.5-1.65 0-3.35.3-4.75 1.05-.1.05-.15.05-.25.05-.25 0-.5-.25-.5-.5V6c.6-.45 1.25-.75 2-1 1.11-.35 2.33-.5 3.5-.5 1.95 0 4.05.4 5.5 1.5 1.45-1.1 3.55-1.5 5.5-1.5 1.17 0 2.39.15 3.5.5.75.25 1.4.55 2 1v14.6c0 .25-.25.5-.5.5-.1 0-.15 0-.25-.05-1.4-.75-3.1-1.05-4.75-1.05-1.7 0-4.15.65-5.5 1.5M12 8v11.5c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5V7c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5m1 3.5c1.11-.68 2.6-1 4.5-1 .91 0 1.76.09 2.5.28V9.23c-.87-.15-1.71-.23-2.5-.23q-2.655 0-4.5.84zm4.5.17c-1.71 0-3.21.26-4.5.79v1.69c1.11-.65 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24v-1.5c-.87-.16-1.71-.23-2.5-.23m2.5 2.9c-.87-.16-1.71-.24-2.5-.24-1.83 0-3.33.27-4.5.8v1.69c1.11-.66 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24z"/></svg>
Docs
</a>
</li>
<li class="md-tabs__item">
<a href="../../blog/" class="md-tabs__link">
Blog
</a>
</li>
</ul>
</div>
</nav>
</header>
<div class="md-container" data-md-component="container">
<main class="md-main" data-md-component="main">
<div class="md-main__inner md-grid">
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
<label class="md-nav__title" for="__drawer">
<a href="../.." title="Changemaker Lite" class="md-nav__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
<img src="../../assets/logo.png" alt="logo">
</a>
Changemaker Lite
</label>
<div class="md-nav__source">
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
<div class="md-source__icon md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
</div>
<div class="md-source__repository">
changemaker.lite
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." class="md-nav__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21.5c-1.35-.85-3.8-1.5-5.5-1.5-1.65 0-3.35.3-4.75 1.05-.1.05-.15.05-.25.05-.25 0-.5-.25-.5-.5V6c.6-.45 1.25-.75 2-1 1.11-.35 2.33-.5 3.5-.5 1.95 0 4.05.4 5.5 1.5 1.45-1.1 3.55-1.5 5.5-1.5 1.17 0 2.39.15 3.5.5.75.25 1.4.55 2 1v14.6c0 .25-.25.5-.5.5-.1 0-.15 0-.25-.05-1.4-.75-3.1-1.05-4.75-1.05-1.7 0-4.15.65-5.5 1.5M12 8v11.5c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5V7c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5m1 3.5c1.11-.68 2.6-1 4.5-1 .91 0 1.76.09 2.5.28V9.23c-.87-.15-1.71-.23-2.5-.23q-2.655 0-4.5.84zm4.5.17c-1.71 0-3.21.26-4.5.79v1.69c1.11-.65 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24v-1.5c-.87-.16-1.71-.23-2.5-.23m2.5 2.9c-.87-.16-1.71-.24-2.5-.24-1.83 0-3.33.27-4.5.8v1.69c1.11-.66 2.6-.99 4.5-.99 1.04 0 1.88.08 2.5.24z"/></svg>
<span class="md-ellipsis">
Docs
</span>
</a>
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2">
<span class="md-nav__icon md-icon"></span>
Docs
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../getting-started/" class="md-nav__link">
<span class="md-ellipsis">
Getting Started
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_3" checked>
<div class="md-nav__link md-nav__container">
<a href="./" class="md-nav__link md-nav__link--active">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m18.09 11.77 1.47 6.33L14 14.74 8.44 18.1l1.46-6.33L5 7.5l6.47-.54L14 1l2.53 5.96L23 7.5zM2 12.43c.19 0 .38-.06.55-.17l3.2-2.11-1.57-1.36-2.73 1.8c-.461.3-.589.91-.29 1.41.2.27.52.43.84.43m-.84 9.12c.2.29.52.45.84.45.19 0 .38-.05.55-.16l4.11-2.71.34-1.37.31-1.45-5.86 3.85c-.461.31-.589.93-.29 1.39m.29-6.17a1 1 0 0 0-.29 1.38c.2.3.52.45.84.45.19 0 .38-.05.55-.16l5.42-3.55.27-1.19-.92-.81z"/></svg>
<span class="md-ellipsis">
Feature Guides
</span>
</a>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_2_3">
<span class="md-nav__icon md-icon"></span>
Feature Guides
</label>
<ul class="md-nav__list" data-md-scrollfix>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../admin/" class="md-nav__link">
<span class="md-ellipsis">
Administration
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../volunteer/" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Guide
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../deployment/" class="md-nav__link">
<span class="md-ellipsis">
Deployment
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../architecture/" class="md-nav__link">
<span class="md-ellipsis">
Architecture
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../services/" class="md-nav__link">
<span class="md-ellipsis">
Services
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../api/" class="md-nav__link">
<span class="md-ellipsis">
API Reference
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../troubleshooting/" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
<a href="../../blog/" class="md-nav__link">
<span class="md-ellipsis">
Blog
</span>
<span class="md-nav__icon md-icon"></span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary" aria-label="On this page">
<label class="md-nav__title" for="__toc">
<span class="md-nav__icon md-icon"></span>
On this page
</label>
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#advocacy-campaigns" class="md-nav__link">
<span class="md-ellipsis">
Advocacy Campaigns
</span>
</a>
<nav class="md-nav" aria-label="Advocacy Campaigns">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-it-works" class="md-nav__link">
<span class="md-ellipsis">
How It Works
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#key-features" class="md-nav__link">
<span class="md-ellipsis">
Key Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-routes" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#public-routes" class="md-nav__link">
<span class="md-ellipsis">
Public Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#map-canvassing" class="md-nav__link">
<span class="md-ellipsis">
Map &amp; Canvassing
</span>
</a>
<nav class="md-nav" aria-label="Map &amp; Canvassing">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#locations" class="md-nav__link">
<span class="md-ellipsis">
Locations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#areas-cuts" class="md-nav__link">
<span class="md-ellipsis">
Areas (Cuts)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#shifts" class="md-nav__link">
<span class="md-ellipsis">
Shifts
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#canvassing" class="md-nav__link">
<span class="md-ellipsis">
Canvassing
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-routes_1" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#public-routes_1" class="md-nav__link">
<span class="md-ellipsis">
Public Routes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#volunteer-routes" class="md-nav__link">
<span class="md-ellipsis">
Volunteer Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#media-manager" class="md-nav__link">
<span class="md-ellipsis">
Media Manager
</span>
</a>
<nav class="md-nav" aria-label="Media Manager">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#key-features_1" class="md-nav__link">
<span class="md-ellipsis">
Key Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-routes_2" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#public-routes_2" class="md-nav__link">
<span class="md-ellipsis">
Public Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#landing-pages" class="md-nav__link">
<span class="md-ellipsis">
Landing Pages
</span>
</a>
<nav class="md-nav" aria-label="Landing Pages">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#how-it-works_1" class="md-nav__link">
<span class="md-ellipsis">
How It Works
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-routes_3" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#public-routes_3" class="md-nav__link">
<span class="md-ellipsis">
Public Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#newsletter-listmonk" class="md-nav__link">
<span class="md-ellipsis">
Newsletter (Listmonk)
</span>
</a>
<nav class="md-nav" aria-label="Newsletter (Listmonk)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#sync" class="md-nav__link">
<span class="md-ellipsis">
Sync
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-routes_4" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#email-templates" class="md-nav__link">
<span class="md-ellipsis">
Email Templates
</span>
</a>
<nav class="md-nav" aria-label="Email Templates">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#admin-routes_5" class="md-nav__link">
<span class="md-ellipsis">
Admin Routes
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<nav class="md-path" aria-label="Navigation" >
<ol class="md-path__list">
<li class="md-path__item">
<a href="../.." class="md-path__link">
<span class="md-ellipsis">
Home
</span>
</a>
</li>
<li class="md-path__item">
<a href="../" class="md-path__link">
<span class="md-ellipsis">
Docs
</span>
</a>
</li>
<li class="md-path__item">
<a href="./" class="md-path__link">
<span class="md-ellipsis">
Feature Guides
</span>
</a>
</li>
</ol>
</nav>
<article class="md-content__inner md-typeset">
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/docs/features/index.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
</a>
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/docs/features/index.md" title="View source of this page" class="md-content__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
</a>
<h1 id="feature-guides">Feature Guides<a class="headerlink" href="#feature-guides" title="Permanent link">&para;</a></h1>
<p>Changemaker Lite bundles advocacy campaigns, geographic mapping, volunteer management, media hosting, and landing pages into a single self-hosted platform. Every feature can be toggled on or off from <strong>Settings</strong> in the admin panel.</p>
<hr />
<h2 id="advocacy-campaigns">Advocacy Campaigns<a class="headerlink" href="#advocacy-campaigns" title="Permanent link">&para;</a></h2>
<p>Help supporters contact their elected representatives through email campaigns.</p>
<h3 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">&para;</a></h3>
<ol>
<li><strong>An admin creates a campaign</strong> — writes the email subject and body, selects which government levels to target (federal, provincial, municipal, school board), and publishes it.</li>
<li><strong>A supporter visits the campaign page</strong> — enters their postal code to look up their representatives.</li>
<li><strong>The supporter sends the email</strong> — either directly through the platform ("Send Now") or by opening it in their own email app (Gmail, Outlook, etc.).</li>
<li><strong>Responses get tracked</strong> — supporters and admins can share representative responses on the Response Wall, with upvoting and moderation.</li>
</ol>
<h3 id="key-features">Key Features<a class="headerlink" href="#key-features" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Postal code lookup</strong> — powered by the Represent API, returns representatives at all government levels</li>
<li><strong>Two send methods</strong> — server-sent SMTP (tracked) or mailto link (opens user's email app)</li>
<li><strong>Email editing</strong> — optionally let supporters personalize the email before sending</li>
<li><strong>Response Wall</strong> — public wall where people share how their representatives responded, with moderation and verification</li>
<li><strong>Campaign stats</strong> — track emails sent, responses received, and upvotes</li>
<li><strong>Featured campaigns</strong> — highlight important campaigns on the public listing page</li>
</ul>
<h3 id="admin-routes">Admin Routes<a class="headerlink" href="#admin-routes" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/campaigns</code> — create, edit, and manage campaigns</li>
<li><code>/app/responses</code> — moderate submitted responses</li>
<li><code>/app/email-queue</code> — monitor outgoing email delivery</li>
</ul>
<h3 id="public-routes">Public Routes<a class="headerlink" href="#public-routes" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/campaigns</code> — browse active campaigns</li>
<li><code>/campaign/:slug</code> — take action on a specific campaign</li>
<li><code>/campaign/:slug/responses</code> — view the response wall</li>
</ul>
<hr />
<h2 id="map-canvassing">Map &amp; Canvassing<a class="headerlink" href="#map-canvassing" title="Permanent link">&para;</a></h2>
<p>Manage locations, organize canvassing territories, and coordinate volunteer door-to-door outreach.</p>
<h3 id="locations">Locations<a class="headerlink" href="#locations" title="Permanent link">&para;</a></h3>
<p>Import addresses via CSV or the Canadian NAR (National Address Register) dataset. Each location can be geocoded using multiple providers (Nominatim, ArcGIS, Photon, Mapbox, and more). Locations appear as color-coded markers on admin and public maps.</p>
<h3 id="areas-cuts">Areas (Cuts)<a class="headerlink" href="#areas-cuts" title="Permanent link">&para;</a></h3>
<p>Draw polygon regions on the map to define canvassing territories. Areas help organize locations into manageable chunks for volunteers. Each area shows stats like total addresses, visit counts, and coverage percentage.</p>
<h3 id="shifts">Shifts<a class="headerlink" href="#shifts" title="Permanent link">&para;</a></h3>
<p>Schedule volunteer time slots and let people sign up through a public page. Shifts can be linked to specific areas so volunteers know where they'll be canvassing.</p>
<h3 id="canvassing">Canvassing<a class="headerlink" href="#canvassing" title="Permanent link">&para;</a></h3>
<p>The volunteer canvass map is a full-screen GPS-tracked experience:</p>
<ul>
<li><strong>Walking routes</strong> — the system generates an efficient route through assigned locations</li>
<li><strong>Visit recording</strong> — tap a marker, record the outcome (not home, supportive, opposed, etc.)</li>
<li><strong>GPS tracking</strong> — real-time position shown on the map</li>
<li><strong>Cluster markers</strong> — addresses grouped intelligently for performance at scale</li>
</ul>
<h3 id="admin-routes_1">Admin Routes<a class="headerlink" href="#admin-routes_1" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/map</code> — manage locations (CRUD, CSV import/export, geocoding)</li>
<li><code>/app/map/cuts</code> — draw and manage canvassing areas</li>
<li><code>/app/map/shifts</code> — schedule shifts and view signups</li>
<li><code>/app/map/canvass</code> — canvass dashboard (stats, activity feed, leaderboard)</li>
</ul>
<h3 id="public-routes_1">Public Routes<a class="headerlink" href="#public-routes_1" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/map</code> — public map view (address locations only, no canvass data)</li>
<li><code>/shifts</code> — sign up for volunteer shifts</li>
</ul>
<h3 id="volunteer-routes">Volunteer Routes<a class="headerlink" href="#volunteer-routes" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/volunteer</code> — full-screen canvass map with GPS and visit recording</li>
<li><code>/volunteer/shifts</code> — view assigned shifts</li>
<li><code>/volunteer/activity</code> — visit history and outcome breakdown</li>
<li><code>/volunteer/routes</code> — past canvassing routes</li>
</ul>
<hr />
<h2 id="media-manager">Media Manager<a class="headerlink" href="#media-manager" title="Permanent link">&para;</a></h2>
<p>Upload, organize, and share campaign videos with built-in analytics.</p>
<h3 id="key-features_1">Key Features<a class="headerlink" href="#key-features_1" title="Permanent link">&para;</a></h3>
<ul>
<li><strong>Video upload</strong> — drag-and-drop upload with automatic metadata extraction (duration, dimensions, quality)</li>
<li><strong>Public gallery</strong> — shareable video gallery at <code>/gallery</code> with category browsing</li>
<li><strong>Analytics</strong> — view counts, watch time, completion rates, and traffic sources (GDPR-compliant)</li>
<li><strong>Scheduled publishing</strong> — automate publish/unpublish with timezone support and a calendar view</li>
<li><strong>Curated playlists</strong> — organize videos into shareable collections</li>
<li><strong>Quick actions</strong> — keyboard shortcuts (E/P/A/S) for edit, preview, analytics, schedule</li>
</ul>
<h3 id="admin-routes_2">Admin Routes<a class="headerlink" href="#admin-routes_2" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/media/library</code> — upload and manage videos</li>
<li><code>/app/media/curated</code> — manage playlists</li>
<li><code>/app/media/jobs</code> — monitor processing jobs</li>
</ul>
<h3 id="public-routes_2">Public Routes<a class="headerlink" href="#public-routes_2" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/gallery</code> — browse the public video gallery</li>
<li><code>/gallery/watch/:id</code> — watch a specific video</li>
</ul>
<hr />
<h2 id="landing-pages">Landing Pages<a class="headerlink" href="#landing-pages" title="Permanent link">&para;</a></h2>
<p>Build campaign microsites with a drag-and-drop visual editor.</p>
<h3 id="how-it-works_1">How It Works<a class="headerlink" href="#how-it-works_1" title="Permanent link">&para;</a></h3>
<ol>
<li>Create a new page from the admin panel</li>
<li>Open the GrapesJS visual editor — drag blocks, edit text, adjust styles</li>
<li>Save and publish — the page goes live at <code>/p/:slug</code></li>
<li>Optionally export to MkDocs for inclusion in the documentation site</li>
</ol>
<h3 id="admin-routes_3">Admin Routes<a class="headerlink" href="#admin-routes_3" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/pages</code> — list and manage landing pages</li>
<li><code>/app/pages/:id/edit</code> — full-screen GrapesJS editor</li>
</ul>
<h3 id="public-routes_3">Public Routes<a class="headerlink" href="#public-routes_3" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/p/:slug</code> — view a published landing page</li>
</ul>
<hr />
<h2 id="newsletter-listmonk">Newsletter (Listmonk)<a class="headerlink" href="#newsletter-listmonk" title="Permanent link">&para;</a></h2>
<p>Integrated with <a href="https://listmonk.app/">Listmonk</a> for opt-in mailing lists and newsletter campaigns.</p>
<h3 id="sync">Sync<a class="headerlink" href="#sync" title="Permanent link">&para;</a></h3>
<p>When enabled (<code>LISTMONK_SYNC_ENABLED=true</code>), the platform syncs shift participants, location contacts, and user accounts to Listmonk subscriber lists. Sync is triggered manually from the admin panel.</p>
<h3 id="admin-routes_4">Admin Routes<a class="headerlink" href="#admin-routes_4" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/listmonk</code> (sidebar: "Newsletter") — sync status, subscriber counts, and manual sync trigger</li>
</ul>
<hr />
<h2 id="email-templates">Email Templates<a class="headerlink" href="#email-templates" title="Permanent link">&para;</a></h2>
<p>Create reusable email templates with variable substitution for campaign communications.</p>
<h3 id="admin-routes_5">Admin Routes<a class="headerlink" href="#admin-routes_5" title="Permanent link">&para;</a></h3>
<ul>
<li><code>/app/email-templates</code> — create and manage email templates with a visual editor</li>
</ul>
</article>
</div>
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
</div>
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
Back to top
</button>
</main>
<footer class="md-footer">
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../getting-started/environment-variables/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Environment Variables">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
</div>
<div class="md-footer__title">
<span class="md-footer__direction">
Previous
</span>
<div class="md-ellipsis">
Environment Variables
</div>
</div>
</a>
<a href="../admin/" class="md-footer__link md-footer__link--next" aria-label="Next: Administration">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Administration
</div>
</div>
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
</div>
</a>
</nav>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 The Bunker Operations <a href="#__consent">Change cookie settings</a>
</div>
</div>
<div class="md-social">
<a href="https://gitea.bnkops.com/admin" target="_blank" rel="noopener" title="Gitea Repository" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
</a>
<a href="https://listmonk.bnkops.com/subscription/form" target="_blank" rel="noopener" title="Newsletter" class="md-social__link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M536.4-26.3c9.8-3.5 20.6-1 28 6.3s9.8 18.2 6.3 28l-178 496.9c-5 13.9-18.1 23.1-32.8 23.1-14.2 0-27-8.6-32.3-21.7l-64.2-158c-4.5-11-2.5-23.6 5.2-32.6l94.5-112.4c5.1-6.1 4.7-15-.9-20.6s-14.6-6-20.6-.9l-112.4 94.3c-9.1 7.6-21.6 9.6-32.6 5.2L38.1 216.8c-13.1-5.3-21.7-18.1-21.7-32.3 0-14.7 9.2-27.8 23.1-32.8z"/></svg>
</a>
</div>
</div>
</div>
</footer>
</div>
<div class="md-dialog" data-md-component="dialog">
<div class="md-dialog__inner md-typeset"></div>
</div>
<script id="__config" type="application/json">{"annotate": null, "base": "../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.footer", "navigation.indexes", "navigation.path", "navigation.prune", "navigation.tabs", "navigation.tabs.sticky", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
<script src="../../assets/javascripts/bundle.79ae519e.min.js"></script>
<script src="../../javascripts/home.js"></script>
<script src="../../javascripts/github-widget.js"></script>
<script src="../../javascripts/gitea-widget.js"></script>
<script src="../../assets/js/env-config.js"></script>
<script src="../../assets/js/video-player.js"></script>
<script src="../../assets/js/payment-widgets.js"></script>
</body>
</html>