<!--
  DLM PDF.js System — Interactive Architecture Diagram
  Contributor: Ron Fredericks, BiophysicsLab.com
  Page: https://www.biophysicslab.com/pdf-viewer/
  Paste this entire file into a Kadence Custom HTML block.
-->
<style>
.dlm-doc {
    font-family: inherit;
    max-width: 100%;
}
.dlm-view {
    display: none;
}
.dlm-view.active {
    display: block;
}
.dlm-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-top: 14px;
    padding: 8px 18px;
    border-radius: 6px;
    border: 1.5px solid #ccc;
    background: #f5f5f5;
    color: #333;
    font-size: 14px;
    font-weight: 500;
    cursor: pointer;
    text-decoration: none;
}
.dlm-back:hover {
    background: #e8e8e8;
    color: #111;
}
.dlm-detail-text {
    margin: 12px 0 0;
    padding: 12px 16px;
    border-left: 3px solid #ccc;
    background: #f9f9f9;
    border-radius: 0 6px 6px 0;
    font-size: 14px;
    line-height: 1.7;
    color: #444;
}
.dlm-footer {
    margin-top: 16px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.dlm-hint {
    font-size: 12px;
    color: #888;
    margin: 0 0 8px;
    font-style: italic;
}
.dlm-node {
    cursor: pointer;
}
.dlm-node:hover rect,
.dlm-node:hover ellipse {
    opacity: 0.85;
}
.ct-fill  { fill: #E1F5EE; stroke: #0F6E56; }
.ct-text  { fill: #085041; }
.ct-texts { fill: #0F6E56; }
.cp-fill  { fill: #EEEDFE; stroke: #534AB7; }
.cp-text  { fill: #3C3489; }
.cp-texts { fill: #534AB7; }
.cc-fill  { fill: #FAECE7; stroke: #993C1D; }
.cc-text  { fill: #712B13; }
.cc-texts { fill: #993C1D; }
.arr-line {
    fill: none;
    stroke: #888;
    stroke-width: 1.2;
}
.arr-dash {
    fill: none;
    stroke: #aaa;
    stroke-width: 1;
    stroke-dasharray: 4 3;
}
</style>

<div class="dlm-doc">

<!-- OVERVIEW -->
<div id="view-overview" class="dlm-view active">
<p class="dlm-hint">Click any component box to explore its detail diagram.</p>
<svg width="100%" viewBox="0 0 680 530" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr0" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">DLM PDF.js system &#8212; component overview</text>
<rect class="ct-fill" x="40" y="48" width="600" height="120" rx="14" stroke-width="0.5"/>
<text class="ct-text" font-family="inherit" font-size="14" font-weight="500" x="60" y="74">WordPress page</text>
<text class="ct-texts" font-family="inherit" font-size="12" x="60" y="90">shortcodes placed by site author</text>
<g class="dlm-node" onclick="showView('dlm-pdfjs')">
<rect class="ct-fill" x="64" y="102" width="170" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="149" y="122" text-anchor="middle" dominant-baseline="central">&#91;dlm_pdfjs id=&quot;x&quot;&#93;</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="149" y="142" text-anchor="middle" dominant-baseline="central">opens PDF in new tab</text>
</g>
<g class="dlm-node" onclick="showView('download-sc')">
<rect class="ct-fill" x="254" y="102" width="172" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="122" text-anchor="middle" dominant-baseline="central">&#91;download id=&quot;x&quot;&#93;</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="142" text-anchor="middle" dominant-baseline="central">ZIP / other downloads</text>
</g>
<g class="dlm-node" onclick="showView('live-counter')">
<rect class="ct-fill" x="446" y="102" width="178" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="535" y="122" text-anchor="middle" dominant-baseline="central">&#91;file_event_count_live&#93;</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="535" y="142" text-anchor="middle" dominant-baseline="central">live count + date display</text>
</g>
<line class="arr-line" x1="149" y1="154" x2="149" y2="206" marker-end="url(#arr0)"/>
<line class="arr-line" x1="340" y1="154" x2="340" y2="206" marker-end="url(#arr0)"/>
<line class="arr-line" x1="535" y1="154" x2="535" y2="206" marker-end="url(#arr0)"/>
<rect class="cp-fill" x="40" y="206" width="600" height="120" rx="14" stroke-width="0.5"/>
<text class="cp-text" font-family="inherit" font-size="14" font-weight="500" x="60" y="232">Required plugins</text>
<text class="cp-texts" font-family="inherit" font-size="12" x="60" y="248">must be installed and active in WordPress</text>
<g class="dlm-node" onclick="showView('pdfjs-plugin')">
<rect class="cp-fill" x="64" y="258" width="170" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="149" y="281" text-anchor="middle" dominant-baseline="central">PDF.js Viewer</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="149" y="299" text-anchor="middle" dominant-baseline="central">viewer.php endpoint</text>
</g>
<g class="dlm-node" onclick="showView('dlm-plugin')">
<rect class="cp-fill" x="254" y="258" width="172" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="281" text-anchor="middle" dominant-baseline="central">Download Monitor</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="299" text-anchor="middle" dominant-baseline="central">protected file storage</text>
</g>
<g class="dlm-node" onclick="showView('code-snippets')">
<rect class="cp-fill" x="446" y="258" width="178" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="535" y="281" text-anchor="middle" dominant-baseline="central">Code Snippets</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="535" y="299" text-anchor="middle" dominant-baseline="central">runs the PHP snippets</text>
</g>
<line class="arr-line" x1="149" y1="310" x2="149" y2="362" marker-end="url(#arr0)"/>
<line class="arr-line" x1="340" y1="310" x2="245" y2="362" marker-end="url(#arr0)"/>
<line class="arr-line" x1="535" y1="310" x2="435" y2="362" marker-end="url(#arr0)"/>
<line class="arr-line" x1="535" y1="310" x2="535" y2="362" marker-end="url(#arr0)"/>
<rect class="cc-fill" x="40" y="362" width="600" height="120" rx="14" stroke-width="0.5"/>
<text class="cc-text" font-family="inherit" font-size="14" font-weight="500" x="60" y="388">Required snippets</text>
<text class="cc-texts" font-family="inherit" font-size="12" x="60" y="404">installed via Code Snippets plugin</text>
<g class="dlm-node" onclick="showView('snippet-viewer')">
<rect class="cc-fill" x="64" y="414" width="260" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="194" y="437" text-anchor="middle" dominant-baseline="central">DLM PDF.js Proxy Viewer</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="194" y="455" text-anchor="middle" dominant-baseline="central">Rev 2 &#8212; proxy + &#91;dlm_pdfjs&#93;</text>
</g>
<g class="dlm-node" onclick="showView('snippet-counter')">
<rect class="cc-fill" x="354" y="414" width="260" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="484" y="437" text-anchor="middle" dominant-baseline="central">DLM PDF.js Proxy Counter</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="484" y="455" text-anchor="middle" dominant-baseline="central">Rev 1 &#8212; counting + admin panel</text>
</g>
</svg>
</div>

<!-- DETAIL: [dlm_pdfjs] -->
<div id="view-dlm-pdfjs" class="dlm-view">
<svg width="100%" viewBox="0 0 680 480" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr1" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">&#91;dlm_pdfjs&#93; &#8212; PDF view request flow</text>
<rect class="ct-fill" x="190" y="48" width="300" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="68" text-anchor="middle" dominant-baseline="central">User clicks &#91;dlm_pdfjs id=&quot;x&quot;&#93; link</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="86" text-anchor="middle" dominant-baseline="central">link opens in new browser tab</text>
<line class="arr-line" x1="340" y1="100" x2="340" y2="130" marker-end="url(#arr1)"/>
<rect class="cp-fill" x="190" y="130" width="300" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="150" text-anchor="middle" dominant-baseline="central">viewer.php loads in new tab</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="168" text-anchor="middle" dominant-baseline="central">PDF.js viewer renders in browser</text>
<line class="arr-line" x1="340" y1="182" x2="340" y2="212" marker-end="url(#arr1)"/>
<rect class="cp-fill" x="190" y="212" width="300" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="232" text-anchor="middle" dominant-baseline="central">PDF.js requests proxy URL</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="250" text-anchor="middle" dominant-baseline="central">/?dlm_pdf_proxy=x</text>
<line class="arr-line" x1="340" y1="264" x2="340" y2="294" marker-end="url(#arr1)"/>
<rect class="cc-fill" x="140" y="294" width="400" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="314" text-anchor="middle" dominant-baseline="central">Proxy Viewer snippet handles request</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="340" y="332" text-anchor="middle" dominant-baseline="central">verifies ID, resolves path, checks security</text>
<line class="arr-line" x1="240" y1="346" x2="180" y2="376" marker-end="url(#arr1)"/>
<line class="arr-line" x1="440" y1="346" x2="500" y2="376" marker-end="url(#arr1)"/>
<rect class="cc-fill" x="60" y="376" width="220" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="170" y="396" text-anchor="middle" dominant-baseline="central">Counter incremented</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="170" y="414" text-anchor="middle" dominant-baseline="central">ron_increment_file_event()</text>
<rect class="ct-fill" x="400" y="376" width="220" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="510" y="396" text-anchor="middle" dominant-baseline="central">PDF streamed to browser</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="510" y="414" text-anchor="middle" dominant-baseline="central">readfile() with correct headers</text>
</svg>
<div class="dlm-detail-text">The &#91;dlm_pdfjs&#93; shortcode renders a plain HTML link. Clicking opens viewer.php in a new tab. PDF.js then requests the proxy URL, which verifies the download ID, resolves the file path from Download Monitor metadata, increments the counter, and streams the PDF. The real file path in dlm_uploads is never exposed to the visitor.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: [download id="x"] -->
<div id="view-download-sc" class="dlm-view">
<svg width="100%" viewBox="0 0 680 380" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr2" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">&#91;download id=&quot;x&quot;&#93; &#8212; ZIP download flow</text>
<rect class="ct-fill" x="190" y="48" width="300" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="68" text-anchor="middle" dominant-baseline="central">User clicks &#91;download id=&quot;x&quot;&#93; link</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="86" text-anchor="middle" dominant-baseline="central">standard Download Monitor link</text>
<line class="arr-line" x1="340" y1="100" x2="340" y2="130" marker-end="url(#arr2)"/>
<rect class="cp-fill" x="190" y="130" width="300" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="150" text-anchor="middle" dominant-baseline="central">Download Monitor serves file</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="168" text-anchor="middle" dominant-baseline="central">handles request natively</text>
<line class="arr-line" x1="340" y1="182" x2="340" y2="212" marker-end="url(#arr2)"/>
<rect class="cp-fill" x="190" y="212" width="300" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="232" text-anchor="middle" dominant-baseline="central">dlm_downloading hook fires</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="250" text-anchor="middle" dominant-baseline="central">WordPress action after file served</text>
<line class="arr-line" x1="340" y1="264" x2="340" y2="294" marker-end="url(#arr2)"/>
<rect class="cc-fill" x="100" y="294" width="480" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="314" text-anchor="middle" dominant-baseline="central">Counter snippet catches hook</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="340" y="332" text-anchor="middle" dominant-baseline="central">ron_unified_count_dlm_download() &#8594; ron_increment_file_event()</text>
</svg>
<div class="dlm-detail-text">For ZIP files and any other non-PDF file type, the existing &#91;download id="x"&#93; shortcode works unchanged. Download Monitor handles delivery natively and fires the dlm_downloading hook when done. The Proxy Counter snippet listens for this hook and increments the event counter automatically &#8212; no changes needed for any file type Download Monitor serves.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: live counter -->
<div id="view-live-counter" class="dlm-view">
<svg width="100%" viewBox="0 0 680 520" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr3" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">&#91;file_event_count_live&#93; &#8212; live counter flow</text>
<rect class="ct-fill" x="190" y="48" width="300" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="68" text-anchor="middle" dominant-baseline="central">&#91;file_event_count_live id=&quot;x&quot;&#93;</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="86" text-anchor="middle" dominant-baseline="central">shortcode on page</text>
<line class="arr-line" x1="340" y1="100" x2="340" y2="130" marker-end="url(#arr3)"/>
<rect class="cp-fill" x="100" y="130" width="480" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="150" text-anchor="middle" dominant-baseline="central">PHP renders span with initial count</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="168" text-anchor="middle" dominant-baseline="central">&lt;span class=&quot;ron-file-event-count&quot; data-id=&quot;x&quot;&gt;47&lt;/span&gt;</text>
<line class="arr-line" x1="240" y1="182" x2="170" y2="212" marker-end="url(#arr3)"/>
<line class="arr-line" x1="440" y1="182" x2="510" y2="212" marker-end="url(#arr3)"/>
<rect class="cp-fill" x="60" y="212" width="210" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="165" y="232" text-anchor="middle" dominant-baseline="central">Global flag set true</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="165" y="250" text-anchor="middle" dominant-baseline="central">CSS + JS this page only</text>
<rect class="cp-fill" x="410" y="212" width="210" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="515" y="232" text-anchor="middle" dominant-baseline="central">Count shown immediately</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="515" y="250" text-anchor="middle" dominant-baseline="central">no blank flash on load</text>
<line class="arr-line" x1="165" y1="264" x2="280" y2="330" marker-end="url(#arr3)"/>
<line class="arr-line" x1="515" y1="264" x2="400" y2="330" marker-end="url(#arr3)"/>
<rect class="cc-fill" x="120" y="330" width="440" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="350" text-anchor="middle" dominant-baseline="central">JS polls AJAX every 5 seconds</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="340" y="368" text-anchor="middle" dominant-baseline="central">admin-ajax.php?action=ron_get_file_event&amp;id=x</text>
<line class="arr-line" x1="340" y1="382" x2="340" y2="412" marker-end="url(#arr3)"/>
<rect class="ct-fill" x="120" y="412" width="440" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="432" text-anchor="middle" dominant-baseline="central">DOM updated only if value changed</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="450" text-anchor="middle" dominant-baseline="central">prevents unnecessary page reflows</text>
<path class="arr-dash" d="M562 464 Q620 464 620 372 Q620 280 562 280" marker-end="url(#arr3)"/>
<text font-family="inherit" font-size="11" fill="#888" x="628" y="376" text-anchor="start">every 5s</text>
</svg>
<div class="dlm-detail-text">The live counter renders the current count server-side on first load so there is never a blank value while JavaScript initializes. A global PHP flag ensures the polling JavaScript is only loaded on pages that use a live shortcode &#8212; other pages get no extra overhead. The polling loop only updates the DOM when the value has actually changed, preventing unnecessary reflows.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: PDF.js Viewer plugin -->
<div id="view-pdfjs-plugin" class="dlm-view">
<svg width="100%" viewBox="0 0 680 340" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr4" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">PDF.js Viewer plugin &#8212; role in the system</text>
<rect class="cp-fill" x="40" y="56" width="280" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="180" y="76" text-anchor="middle" dominant-baseline="central">Plugin by TwisterMc</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="180" y="94" text-anchor="middle" dominant-baseline="central">pdfjs-viewer-shortcode v3.0.4</text>
<rect class="cp-fill" x="360" y="56" width="280" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="500" y="76" text-anchor="middle" dominant-baseline="central">Bundles Mozilla PDF.js</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="500" y="94" text-anchor="middle" dominant-baseline="central">open source PDF renderer</text>
<line class="arr-line" x1="180" y1="108" x2="280" y2="158" marker-end="url(#arr4)"/>
<line class="arr-line" x1="500" y1="108" x2="400" y2="158" marker-end="url(#arr4)"/>
<rect class="cc-fill" x="120" y="158" width="440" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="178" text-anchor="middle" dominant-baseline="central">viewer.php endpoint</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="340" y="196" text-anchor="middle" dominant-baseline="central">/wp-content/plugins/pdfjs-viewer-shortcode/pdfjs/web/</text>
<line class="arr-line" x1="340" y1="210" x2="340" y2="258" marker-end="url(#arr4)"/>
<rect class="ct-fill" x="120" y="258" width="440" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="278" text-anchor="middle" dominant-baseline="central">Accepts file= parameter</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="296" text-anchor="middle" dominant-baseline="central">renders PDF from proxy URL in browser</text>
</svg>
<div class="dlm-detail-text">The PDF.js Viewer Shortcode plugin provides the viewer.php endpoint the system relies on. viewer.php is used instead of viewer.html because newer versions of PDF.js bundle ES modules (.mjs files) which require correct MIME types &#8212; viewer.php handles this internally. No plugin configuration changes are needed; the system simply calls its viewer endpoint with the proxy URL as the file= parameter.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: Download Monitor -->
<div id="view-dlm-plugin" class="dlm-view">
<svg width="100%" viewBox="0 0 680 360" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr5" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">Download Monitor &#8212; role in the system</text>
<rect class="cp-fill" x="40" y="56" width="180" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="130" y="76" text-anchor="middle" dominant-baseline="central">File storage</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="130" y="94" text-anchor="middle" dominant-baseline="central">dlm_uploads/YYYY/MM/</text>
<rect class="cp-fill" x="250" y="56" width="180" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="76" text-anchor="middle" dominant-baseline="central">Download IDs</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="94" text-anchor="middle" dominant-baseline="central">unique ID per managed file</text>
<rect class="cp-fill" x="460" y="56" width="180" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="550" y="76" text-anchor="middle" dominant-baseline="central">dlm_downloading hook</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="550" y="94" text-anchor="middle" dominant-baseline="central">fires on every download</text>
<line class="arr-line" x1="130" y1="108" x2="240" y2="188" marker-end="url(#arr5)"/>
<line class="arr-line" x1="340" y1="108" x2="340" y2="188" marker-end="url(#arr5)"/>
<line class="arr-line" x1="550" y1="108" x2="440" y2="188" marker-end="url(#arr5)"/>
<rect class="cc-fill" x="120" y="188" width="440" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="208" text-anchor="middle" dominant-baseline="central">Used by Proxy Viewer snippet</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="340" y="226" text-anchor="middle" dominant-baseline="central">resolves file path from DLM metadata</text>
<line class="arr-line" x1="340" y1="240" x2="340" y2="288" marker-end="url(#arr5)"/>
<rect class="ct-fill" x="120" y="288" width="440" height="52" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="308" text-anchor="middle" dominant-baseline="central">&#91;download id=&quot;x&quot;&#93; for ZIPs unchanged</text>
<text class="ct-texts" font-family="inherit" font-size="11" x="340" y="326" text-anchor="middle" dominant-baseline="central">DLM handles delivery, hook triggers counter</text>
</svg>
<div class="dlm-detail-text">Download Monitor stores protected files in a non-public uploads directory, assigns a unique download ID to each file, and fires the dlm_downloading hook when a file is served. The Proxy Viewer snippet uses DLM metadata to resolve the real file path server-side. DLM's native display counter is disabled since the Proxy Counter provides unified tracking across both PDFs and ZIPs.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: Code Snippets -->
<div id="view-code-snippets" class="dlm-view">
<svg width="100%" viewBox="0 0 680 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<marker id="arr6" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M2 1L8 5L2 9" fill="none" stroke="#888" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</marker>
</defs>
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">Code Snippets plugin &#8212; role in the system</text>
<rect class="cp-fill" x="190" y="56" width="300" height="52" rx="8" stroke-width="1"/>
<text class="cp-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="76" text-anchor="middle" dominant-baseline="central">Code Snippets plugin</text>
<text class="cp-texts" font-family="inherit" font-size="11" x="340" y="94" text-anchor="middle" dominant-baseline="central">manages and executes PHP snippets</text>
<line class="arr-line" x1="270" y1="108" x2="190" y2="158" marker-end="url(#arr6)"/>
<line class="arr-line" x1="410" y1="108" x2="490" y2="158" marker-end="url(#arr6)"/>
<rect class="cc-fill" x="40" y="158" width="260" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="170" y="178" text-anchor="middle" dominant-baseline="central">DLM PDF.js Proxy Viewer</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="170" y="196" text-anchor="middle" dominant-baseline="central">Rev 2 &#8212; snippet 1</text>
<rect class="cc-fill" x="380" y="158" width="260" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="510" y="178" text-anchor="middle" dominant-baseline="central">DLM PDF.js Proxy Counter</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="510" y="196" text-anchor="middle" dominant-baseline="central">Rev 1 &#8212; snippet 2</text>
<line class="arr-line" x1="170" y1="210" x2="280" y2="246" marker-end="url(#arr6)"/>
<line class="arr-line" x1="510" y1="210" x2="400" y2="246" marker-end="url(#arr6)"/>
<rect class="ct-fill" x="140" y="246" width="400" height="36" rx="8" stroke-width="1"/>
<text class="ct-text" font-family="inherit" font-size="13" font-weight="500" x="340" y="268" text-anchor="middle" dominant-baseline="central">Both snippets active and working together</text>
</svg>
<div class="dlm-detail-text">Code Snippets executes the two PHP snippets within the WordPress environment. An important technical note: because Code Snippets runs snippets at an early load stage, WordPress transient functions are not yet available. This is why the counter uses a static PHP array combined with wp_cache (Redis) for duplicate-count prevention rather than the more common get_transient/set_transient pattern.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: Proxy Viewer snippet -->
<div id="view-snippet-viewer" class="dlm-view">
<svg width="100%" viewBox="0 0 680 380" xmlns="http://www.w3.org/2000/svg">
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">DLM PDF.js Proxy Viewer &#8212; what it contains</text>
<rect class="cc-fill" x="40" y="48" width="600" height="300" rx="14" stroke-width="0.5"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="60" y="74">DLM PDF.js Proxy Viewer &#8212; Rev 2</text>
<rect class="cc-fill" x="64" y="88" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="108" text-anchor="middle" dominant-baseline="central">&#91;dlm_pdfjs&#93; shortcode</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="126" text-anchor="middle" dominant-baseline="central">renders link, opens viewer in new tab</text>
<rect class="cc-fill" x="368" y="88" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="108" text-anchor="middle" dominant-baseline="central">manual fallback map</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="126" text-anchor="middle" dominant-baseline="central">override auto-detect per download ID</text>
<rect class="cc-fill" x="64" y="168" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="188" text-anchor="middle" dominant-baseline="central">PDF proxy handler</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="206" text-anchor="middle" dominant-baseline="central">template_redirect, streams PDF</text>
<rect class="cc-fill" x="368" y="168" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="188" text-anchor="middle" dominant-baseline="central">path resolver</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="206" text-anchor="middle" dominant-baseline="central">7-step DLM metadata lookup chain</text>
<rect class="cc-fill" x="64" y="248" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="268" text-anchor="middle" dominant-baseline="central">path cache</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="286" text-anchor="middle" dominant-baseline="central">_ron_pdfjs_relative_path post meta</text>
<rect class="cc-fill" x="368" y="248" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="268" text-anchor="middle" dominant-baseline="central">file_exists() guard</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="286" text-anchor="middle" dominant-baseline="central">graceful fallback if plugin missing</text>
</svg>
<div class="dlm-detail-text">The Proxy Viewer snippet owns the complete PDF delivery pipeline. The &#91;dlm_pdfjs&#93; shortcode renders a link to viewer.php with the proxy URL as the file parameter. The proxy intercepts requests via template_redirect, runs security checks, resolves the file path through a 6-step metadata lookup, caches the result, increments the counter, and streams the PDF. The real file path in dlm_uploads is never exposed to the visitor.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

<!-- DETAIL: Proxy Counter snippet -->
<div id="view-snippet-counter" class="dlm-view">
<svg width="100%" viewBox="0 0 680 380" xmlns="http://www.w3.org/2000/svg">
<text font-family="inherit" font-size="14" font-weight="500" fill="#1a1a1a" x="340" y="28" text-anchor="middle">DLM PDF.js Proxy Counter &#8212; what it contains</text>
<rect class="cc-fill" x="40" y="48" width="600" height="300" rx="14" stroke-width="0.5"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="60" y="74">DLM PDF.js Proxy Counter &#8212; Rev 1</text>
<rect class="cc-fill" x="64" y="88" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="108" text-anchor="middle" dominant-baseline="central">ron_increment_file_event()</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="126" text-anchor="middle" dominant-baseline="central">static array + Redis two-layer lock</text>
<rect class="cc-fill" x="368" y="88" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="108" text-anchor="middle" dominant-baseline="central">dlm_downloading hook</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="126" text-anchor="middle" dominant-baseline="central">counts ZIP and all other downloads</text>
<rect class="cc-fill" x="64" y="168" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="188" text-anchor="middle" dominant-baseline="central">display shortcodes</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="206" text-anchor="middle" dominant-baseline="central">&#91;file_event_count_live&#93; + date</text>
<rect class="cc-fill" x="368" y="168" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="188" text-anchor="middle" dominant-baseline="central">AJAX endpoint</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="206" text-anchor="middle" dominant-baseline="central">ron_get_file_event &#8212; JSON response</text>
<rect class="cc-fill" x="64" y="248" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="188" y="268" text-anchor="middle" dominant-baseline="central">DLM PDF.js Stats panel</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="188" y="286" text-anchor="middle" dominant-baseline="central">Downloads &#8594; admin panel</text>
<rect class="cc-fill" x="368" y="248" width="248" height="52" rx="8" stroke-width="1"/>
<text class="cc-text" font-family="inherit" font-size="13" font-weight="500" x="492" y="268" text-anchor="middle" dominant-baseline="central">conditional JS enqueue</text>
<text class="cc-texts" font-family="inherit" font-size="11" x="492" y="286" text-anchor="middle" dominant-baseline="central">only loads on pages that need it</text>
</svg>
<div class="dlm-detail-text">The Proxy Counter is the shared counting engine for the entire system. It provides the core increment function called by both the PDF proxy and the ZIP download hook. The two-layer lock (static PHP array for within-request duplicates, Redis wp_cache for cross-request duplicates) prevents PDF.js byte-range requests from inflating counts. The admin panel under Downloads &#8594; DLM PDF.js Stats shows sortable stats with editable counts for restoring historical data.</div>
<div class="dlm-footer"><button class="dlm-back" onclick="showView('overview')">&#8592; back to overview</button></div>
</div>

</div>

<script>
function showView(id) {
    var views = document.querySelectorAll('.dlm-view');
    for (var i = 0; i < views.length; i++) {
        views[i].classList.remove('active');
    }
    var el = document.getElementById('view-' + id);
    if (el) { el.classList.add('active'); }
}
</script>