# -*- coding: utf-8 -*-
"""
LVT Shared Infrastructure — Help Content.

Centralized bilingual help content for all LVT plugin modules.

Author: Lộc Vũ Trung (LVT) / Slow Forest
License: GPL-3.0
"""

# CSS shared by all help pages
_CSS = """
<style>
body { font-family: Arial, sans-serif; padding: 10px; color: #333; }
h2 { color: #1B5E20; border-bottom: 2px solid #1B5E20; padding-bottom: 5px; }
h3 { color: #2E7D32; margin-top: 16px; }
table { border-collapse: collapse; width: 100%; margin: 8px 0; }
th { background: #1B5E20; color: white; padding: 6px 10px; text-align: left; }
td { border: 1px solid #ccc; padding: 5px 10px; }
tr:nth-child(even) { background: #f5f5f5; }
li { margin-bottom: 4px; }
.tip { background: #E8F5E9; border-left: 4px solid #4CAF50;
       padding: 8px 12px; margin: 8px 0; border-radius: 3px; }
.warn { background: #FFF3E0; border-left: 4px solid #FF9800;
        padding: 8px 12px; margin: 8px 0; border-radius: 3px; }
</style>
"""


def _h(body):
    """Prepend shared CSS to an HTML help body."""
    return _CSS + body


_HELP = {
    # ================================================================
    # MAP LAYOUT
    # ================================================================
    "layout": {
        "en": _h("""
<h2>📐 Map Layout</h2>
<h3>Overview</h3>
<p>Create professional print-ready map layouts with title block,
north arrow, scale bar, legend, and signature block.</p>

<h3>How to Use</h3>
<ol>
<li><b>Select layers</b> to include in the layout</li>
<li><b>Choose paper size</b> (A5–A0) and orientation</li>
<li><b>Fill in metadata</b>: title, organization, study area, date</li>
<li><b>Configure scale</b> and grid settings</li>
<li><b>Add Signature Block</b> (Print mode only)</li>
<li><b>Add Legend Block</b> (Print mode only)</li>
<li>Click <b>Create Layout</b> to generate</li>
</ol>

<h3>Paper Sizes</h3>
<table>
<tr><th>Size</th><th>Dimensions (mm)</th><th>Use Case</th></tr>
<tr><td>A5</td><td>148 × 210</td><td>Field reports</td></tr>
<tr><td>A4</td><td>210 × 297</td><td>Standard reports</td></tr>
<tr><td>A3</td><td>297 × 420</td><td>Presentations</td></tr>
<tr><td>A2–A0</td><td>420+ × 594+</td><td>Wall maps, posters</td></tr>
</table>

<h2>✍ Signature Block (Print Mode)</h2>
<h3>What is it?</h3>
<p>The Signature Block adds formal sign-off boxes at the bottom of
your map layout — typically used for official forestry, cadastral,
or environmental reports that require authorization stamps.</p>

<h3>How to Enable</h3>
<ol>
<li>Select <b>Print / In ấn</b> mode (not Slide mode)</li>
<li>Check <b>✍ Add Signature Block</b> in the Map Settings tab</li>
<li>The signature panel expands with full configuration options</li>
</ol>

<h3>Configuration Parameters</h3>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th><th>Range</th></tr>
<tr><td><b>Count</b></td><td>Number of signature boxes</td><td>2</td><td>1–8</td></tr>
<tr><td><b>Height</b></td><td>Box height</td><td>50 mm</td><td>30–200 mm</td></tr>
<tr><td><b>Width</b></td><td>Box width</td><td>50 mm</td><td>30–200 mm</td></tr>
<tr><td><b>Left margin</b></td><td>Distance from left edge of frame</td><td>3 mm</td><td>0–100 mm</td></tr>
<tr><td><b>Bottom margin</b></td><td>Distance from bottom edge</td><td>3 mm</td><td>0–100 mm</td></tr>
</table>

<h3>Font Styles (per component)</h3>
<p>Each signature block has 3 text components with independent font control:</p>
<table>
<tr><th>Component</th><th>Purpose</th><th>Default Font</th><th>Size</th><th>Style</th></tr>
<tr><td><b>Title</b></td><td>Role/organization label</td><td>Times New Roman</td><td>12pt</td><td>Bold</td></tr>
<tr><td><b>Date</b></td><td>Signing date line</td><td>Times New Roman</td><td>10pt</td><td>Italic</td></tr>
<tr><td><b>Name</b></td><td>Signatory's full name</td><td>Times New Roman</td><td>11pt</td><td>Bold</td></tr>
</table>

<h3>Block Content</h3>
<p>Each block has 3 editable fields:</p>
<ul>
<li><b>Title:</b> e.g. "REPRESENTATIVE PARTY A" (auto-fills A, B, C...)</li>
<li><b>Date:</b> e.g. "Day 10 Month 5 Year 2026" (auto-fills today's date)</li>
<li><b>Name:</b> Full name of signatory (blank by default)</li>
</ul>

<div class='tip'>💡 For 2-party contracts, use Count=2. For multi-stakeholder
reviews (e.g. forestry + environment + commune), use Count=3–4.</div>

<div class='warn'>⚠️ Signature Block is only available in <b>Print mode</b>.
Switching to Slide mode will hide and uncheck the signature option.</div>

<h2>📋 Legend Block (Print Mode)</h2>
<h3>What is it?</h3>
<p>The Legend Block generates a native QGIS legend showing map symbols,
layer names, and classification categories. It replaces any template
legend with a dynamic, data-driven legend.</p>

<h3>How to Enable</h3>
<ol>
<li>Select <b>Print / In ấn</b> mode</li>
<li>Go to the <b>Legend/Content</b> tab</li>
<li>Check <b>📋 Add Legend Block</b></li>
<li>Configure title, columns, fonts, and select layers</li>
</ol>

<h3>Legend Title &amp; Layout</h3>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th></tr>
<tr><td><b>Title</b></td><td>Legend heading text</td><td>CHÚ DẪN</td></tr>
<tr><td><b>Title size</b></td><td>Font size for title</td><td>14pt (8–36)</td></tr>
<tr><td><b>Columns</b></td><td>Number of legend columns</td><td>2 (1–6)</td></tr>
<tr><td><b>Split layers</b></td><td>Allow layer items to split across columns</td><td>✅ On</td></tr>
<tr><td><b>Filter by Map</b></td><td>Only show layers visible in the map extent</td><td>✅ On</td></tr>
<tr><td><b>Auto-update</b></td><td>Legend updates when layers change</td><td>✅ On</td></tr>
</table>

<h3>Symbol &amp; Spacing</h3>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th><th>Range</th></tr>
<tr><td><b>Symbol W</b></td><td>Symbol preview width</td><td>23 mm</td><td>3–40 mm</td></tr>
<tr><td><b>Symbol H</b></td><td>Symbol preview height</td><td>8 mm</td><td>3–20 mm</td></tr>
<tr><td><b>Bottom margin</b></td><td>Space below legend</td><td>6 mm</td><td>0–50 mm</td></tr>
<tr><td><b>Max Width</b></td><td>Maximum legend width</td><td>120 mm</td><td>60–350 mm</td></tr>
<tr><td><b>Left margin</b></td><td>Distance from left edge</td><td>3 mm</td><td>0–50 mm</td></tr>
</table>

<h3>Font Settings</h3>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th></tr>
<tr><td><b>Font</b></td><td>Font family</td><td>Times New Roman / Arial</td></tr>
<tr><td><b>Font size</b></td><td>Item text size</td><td>8pt (5–18)</td></tr>
<tr><td><b>Line spacing</b></td><td>Vertical spacing multiplier</td><td>1.4 (0.8–3.0)</td></tr>
<tr><td><b>Header Bold</b></td><td>Bold layer group headers</td><td>✅ On</td></tr>
</table>

<h3>Layer Selection</h3>
<p>The layer list shows all layers in your QGIS project with:</p>
<ul>
<li><b>Checkbox:</b> Include/exclude each layer from the legend</li>
<li><b>Display name:</b> Override the layer name shown in legend (leave blank = original name)</li>
<li><b>Symbol picker:</b> Choose a different symbol from the QGIS Style Manager</li>
<li><b>Geometry icons:</b> 🔵 Point, 📏 Line, ⬛ Polygon</li>
</ul>

<p>Toolbar buttons:</p>
<ul>
<li><b>🔄 Refresh:</b> Reload layers from current project</li>
<li><b>☑ Select All:</b> Check all layers</li>
<li><b>☐ Deselect:</b> Uncheck all layers</li>
<li><b>Hide groups:</b> Collapse layer group headers</li>
<li><b>🔍 Search:</b> Filter layers by name</li>
</ul>

<div class='tip'>💡 For thematic maps with many categories (e.g. forestry land use),
increase Columns to 3–4 and reduce Symbol size to fit more items.</div>

<div class='warn'>⚠️ Legend Block is only available in <b>Print mode</b>.
When enabled, it replaces any template legend. The legend is positioned
at the bottom-left of the layout frame.</div>
"""),
        "vi": _h("""
<h2>📐 Xây dựng Layout bản đồ</h2>
<h3>Tổng quan</h3>
<p>Tạo khung bản đồ in ấn chuyên nghiệp với khối tiêu đề,
mũi tên Bắc, thanh tỷ lệ, chú dẫn và khối chữ ký.</p>

<h3>Cách sử dụng</h3>
<ol>
<li><b>Chọn các lớp</b> cần đưa vào layout</li>
<li><b>Chọn khổ giấy</b> (A5–A0) và hướng giấy</li>
<li><b>Điền thông tin</b>: tiêu đề, đơn vị, khu vực, ngày</li>
<li><b>Cấu hình tỷ lệ</b> và lưới tọa độ</li>
<li><b>Thêm ô ký</b> (chỉ chế độ In ấn)</li>
<li><b>Thêm chú dẫn</b> (chỉ chế độ In ấn)</li>
<li>Nhấn <b>Tạo khung</b> để tạo layout</li>
</ol>

<h3>Khổ giấy</h3>
<table>
<tr><th>Khổ</th><th>Kích thước (mm)</th><th>Mục đích</th></tr>
<tr><td>A5</td><td>148 × 210</td><td>Báo cáo thực địa</td></tr>
<tr><td>A4</td><td>210 × 297</td><td>Báo cáo tiêu chuẩn</td></tr>
<tr><td>A3</td><td>297 × 420</td><td>Thuyết trình</td></tr>
<tr><td>A2–A0</td><td>420+ × 594+</td><td>Bản đồ treo tường</td></tr>
</table>

<h2>✍ Ô ký / Khối chữ ký (Chế độ In ấn)</h2>
<h3>Mô tả</h3>
<p>Ô ký thêm các khung chữ ký chính thức ở cuối bản đồ —
thường dùng cho báo cáo lâm nghiệp, địa chính hoặc môi trường
cần con dấu và chữ ký xác nhận.</p>

<h3>Cách bật</h3>
<ol>
<li>Chọn chế độ <b>In ấn / Print</b> (không phải Slide)</li>
<li>Tích chọn <b>✍ Thêm ô ký / Add Signature Block</b> trong tab Cài đặt bản đồ</li>
<li>Bảng cấu hình ô ký sẽ mở rộng hiển thị</li>
</ol>

<h3>Thông số cấu hình</h3>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th><th>Phạm vi</th></tr>
<tr><td><b>Số lượng</b></td><td>Số ô ký cần tạo</td><td>2</td><td>1–8</td></tr>
<tr><td><b>Cao</b></td><td>Chiều cao mỗi ô</td><td>50 mm</td><td>30–200 mm</td></tr>
<tr><td><b>Rộng</b></td><td>Chiều rộng mỗi ô</td><td>50 mm</td><td>30–200 mm</td></tr>
<tr><td><b>Cách trái</b></td><td>Khoảng cách từ mép trái khung</td><td>3 mm</td><td>0–100 mm</td></tr>
<tr><td><b>Cách dưới</b></td><td>Khoảng cách từ mép dưới</td><td>3 mm</td><td>0–100 mm</td></tr>
</table>

<h3>Kiểu chữ (theo từng thành phần)</h3>
<p>Mỗi ô ký có 3 thành phần văn bản với font độc lập:</p>
<table>
<tr><th>Thành phần</th><th>Chức năng</th><th>Font mặc định</th><th>Cỡ</th><th>Kiểu</th></tr>
<tr><td><b>Tiêu đề</b></td><td>Tên chức danh/đơn vị</td><td>Times New Roman</td><td>12pt</td><td>Đậm</td></tr>
<tr><td><b>Ngày</b></td><td>Dòng ngày ký</td><td>Times New Roman</td><td>10pt</td><td>Nghiêng</td></tr>
<tr><td><b>Họ tên</b></td><td>Tên người ký</td><td>Times New Roman</td><td>11pt</td><td>Đậm</td></tr>
</table>

<h3>Nội dung mỗi ô ký</h3>
<p>Mỗi ô ký có 3 trường nhập liệu:</p>
<ul>
<li><b>Tiêu đề:</b> VD: "ĐẠI DIỆN BÊN A" (tự động điền A, B, C...)</li>
<li><b>Ngày:</b> VD: "Ngày 10 tháng 5 năm 2026" (tự động điền ngày hiện tại)</li>
<li><b>Họ tên:</b> Tên đầy đủ người ký (để trống mặc định)</li>
</ul>

<div class='tip'>💡 Hợp đồng 2 bên: Số lượng = 2. Biên bản đa bên
(lâm nghiệp + môi trường + xã): Số lượng = 3–4.</div>

<div class='warn'>⚠️ Ô ký chỉ khả dụng ở chế độ <b>In ấn</b>.
Chuyển sang Slide sẽ ẩn và bỏ chọn tùy chọn ô ký.</div>

<h2>📋 Khối chú dẫn / Legend (Chế độ In ấn)</h2>
<h3>Mô tả</h3>
<p>Khối chú dẫn tạo bảng chú dẫn QGIS gốc hiển thị ký hiệu bản đồ,
tên lớp và phân loại. Nó thay thế chú dẫn mẫu bằng chú dẫn
động theo dữ liệu thực tế.</p>

<h3>Cách bật</h3>
<ol>
<li>Chọn chế độ <b>In ấn / Print</b></li>
<li>Chuyển sang tab <b>Legend/Content</b></li>
<li>Tích chọn <b>📋 Thêm chú dẫn / Add Legend Block</b></li>
<li>Cấu hình tiêu đề, số cột, font và chọn lớp</li>
</ol>

<h3>Tiêu đề &amp; Bố cục chú dẫn</h3>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th></tr>
<tr><td><b>Tiêu đề</b></td><td>Dòng tiêu đề chú dẫn</td><td>CHÚ DẪN</td></tr>
<tr><td><b>Cỡ tiêu đề</b></td><td>Cỡ chữ tiêu đề</td><td>14pt (8–36)</td></tr>
<tr><td><b>Số cột</b></td><td>Số cột hiển thị</td><td>2 (1–6)</td></tr>
<tr><td><b>Split layers</b></td><td>Cho phép chia mục sang cột khác</td><td>✅ Bật</td></tr>
<tr><td><b>Lọc theo Map</b></td><td>Chỉ hiện lớp trong phạm vi bản đồ</td><td>✅ Bật</td></tr>
<tr><td><b>Tự cập nhật</b></td><td>Chú dẫn cập nhật khi lớp thay đổi</td><td>✅ Bật</td></tr>
</table>

<h3>Ký hiệu &amp; Khoảng cách</h3>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th><th>Phạm vi</th></tr>
<tr><td><b>Symbol W</b></td><td>Chiều rộng ký hiệu</td><td>23 mm</td><td>3–40 mm</td></tr>
<tr><td><b>Symbol H</b></td><td>Chiều cao ký hiệu</td><td>8 mm</td><td>3–20 mm</td></tr>
<tr><td><b>Cách dưới</b></td><td>Khoảng cách phía dưới chú dẫn</td><td>6 mm</td><td>0–50 mm</td></tr>
<tr><td><b>Max W</b></td><td>Chiều rộng tối đa chú dẫn</td><td>120 mm</td><td>60–350 mm</td></tr>
<tr><td><b>Cách trái</b></td><td>Khoảng cách từ mép trái</td><td>3 mm</td><td>0–50 mm</td></tr>
</table>

<h3>Cài đặt font chữ</h3>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th></tr>
<tr><td><b>Font</b></td><td>Phông chữ</td><td>Times New Roman / Arial</td></tr>
<tr><td><b>Cỡ chữ</b></td><td>Cỡ chữ mô tả</td><td>8pt (5–18)</td></tr>
<tr><td><b>Giãn dòng</b></td><td>Hệ số giãn dòng</td><td>1.4 (0.8–3.0)</td></tr>
<tr><td><b>Header B</b></td><td>In đậm tên nhóm lớp</td><td>✅ Bật</td></tr>
</table>

<h3>Chọn lớp hiển thị</h3>
<p>Danh sách lớp hiển thị tất cả các lớp trong dự án QGIS với:</p>
<ul>
<li><b>Ô tích:</b> Chọn/bỏ chọn từng lớp trong chú dẫn</li>
<li><b>Tên hiển thị:</b> Đổi tên lớp trong chú dẫn (để trống = giữ tên gốc)</li>
<li><b>Chọn ký hiệu:</b> Chọn ký hiệu khác từ QGIS Style Manager</li>
<li><b>Biểu tượng:</b> 🔵 Điểm, 📏 Đường, ⬛ Vùng</li>
</ul>

<p>Thanh công cụ:</p>
<ul>
<li><b>🔄 Làm mới:</b> Tải lại danh sách lớp từ dự án</li>
<li><b>☑ Chọn tất cả:</b> Tích chọn toàn bộ lớp</li>
<li><b>☐ Bỏ chọn:</b> Bỏ tích tất cả</li>
<li><b>Ẩn nhóm:</b> Thu gọn tiêu đề nhóm lớp</li>
<li><b>🔍 Tìm kiếm:</b> Lọc lớp theo tên</li>
</ul>

<div class='tip'>💡 Bản đồ chuyên đề nhiều hạng mục (VD: hiện trạng rừng),
tăng số cột lên 3–4 và giảm cỡ ký hiệu để chứa nhiều mục hơn.</div>

<div class='warn'>⚠️ Khối chú dẫn chỉ khả dụng ở chế độ <b>In ấn</b>.
Khi bật, nó thay thế chú dẫn mẫu. Chú dẫn được đặt ở góc
dưới-trái của khung bản đồ.</div>
"""),
    },

    # ================================================================
    # KML
    # ================================================================
    "kml": {
        "en": _h("""
<h2>🌍 KML / KMZ Converter</h2>
<h3>Overview</h3>
<p>Two-way conversion between Shapefile/GIS layers and KML/KMZ for Google Earth.
Includes custom popup styling, field selection, and color configuration.</p>

<h3>📌 Tab 1 — SHP → KML/KMZ Export</h3>

<h4>Step 1: Select Layer</h4>
<p>Choose a vector layer from your QGIS project. All geometry types
(Point, Line, Polygon) are supported.</p>

<h4>Step 2: Choose Output Format</h4>
<table>
<tr><th>Format</th><th>Description</th><th>Use Case</th></tr>
<tr><td><b>KML</b></td><td>Plain XML text</td><td>Editable, small datasets</td></tr>
<tr><td><b>KMZ</b></td><td>Compressed archive</td><td>Sharing, large datasets</td></tr>
</table>

<h4>Step 3: Select Fields</h4>
<p>Check which attribute fields appear in Google Earth popups.
Uncheck fields you don't want to expose (e.g. internal IDs).</p>

<h4>Step 4: Configure Popup Style</h4>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th></tr>
<tr><td><b>Fill color</b></td><td>Polygon/point fill</td><td>Yellow</td></tr>
<tr><td><b>Outline color</b></td><td>Border color</td><td>Red</td></tr>
<tr><td><b>Outline width</b></td><td>Border thickness (px)</td><td>2</td></tr>
<tr><td><b>Opacity</b></td><td>Fill transparency (0–100%)</td><td>50%</td></tr>
<tr><td><b>Label field</b></td><td>Field shown as placemark name</td><td>First field</td></tr>
</table>

<h4>Step 5: Export</h4>
<ol>
<li>Click <b>Export KML/KMZ</b></li>
<li>Choose save location</li>
<li>Open in Google Earth to verify</li>
</ol>

<h3>📌 Tab 2 — KML/KMZ → SHP Import</h3>

<h4>Step 1: Browse File</h4>
<p>Select a .kml or .kmz file. KMZ is auto-decompressed.</p>

<h4>Step 2: Review Layers</h4>
<p>The converter auto-detects geometry types and splits into
separate layers (Point, Line, Polygon) if mixed.</p>

<h4>Step 3: Select Fields</h4>
<p>Choose which KML attributes to import. Extended Data and
description fields are parsed automatically.</p>

<h4>Step 4: Import</h4>
<ol>
<li>Click <b>Import</b></li>
<li>Layers are added to QGIS with correct CRS (WGS84)</li>
<li>Save as Shapefile/GeoPackage if needed</li>
</ol>

<h3>📌 Tab 3 — Guide</h3>
<p>Built-in visual guide with popup preview showing how your
KML will appear in Google Earth.</p>

<h3>💾 Configuration</h3>
<ul>
<li><b>Save Config:</b> Save current settings for reuse</li>
<li><b>Load Config:</b> Restore saved settings</li>
<li><b>Reset:</b> Restore all defaults</li>
</ul>

<div class='tip'>💡 KMZ files are compressed KML — up to 10x smaller for sharing.
Use KML only when you need to edit the XML manually.</div>

<div class='warn'>⚠️ KML uses WGS84 (EPSG:4326) only. Layers in other CRS
will be automatically reprojected during export.</div>
"""),
        "vi": _h("""
<h2>🌍 Chuyển đổi KML / KMZ</h2>
<h3>Tổng quan</h3>
<p>Chuyển đổi 2 chiều giữa Shapefile/lớp GIS và KML/KMZ cho Google Earth.
Bao gồm tùy chỉnh popup, chọn trường, và cấu hình màu sắc.</p>

<h3>📌 Tab 1 — Xuất SHP → KML/KMZ</h3>

<h4>Bước 1: Chọn lớp</h4>
<p>Chọn lớp vector từ dự án QGIS. Hỗ trợ tất cả loại hình học
(Điểm, Đường, Vùng).</p>

<h4>Bước 2: Chọn định dạng xuất</h4>
<table>
<tr><th>Định dạng</th><th>Mô tả</th><th>Trường hợp dùng</th></tr>
<tr><td><b>KML</b></td><td>File XML văn bản</td><td>Chỉnh sửa, dữ liệu nhỏ</td></tr>
<tr><td><b>KMZ</b></td><td>File nén</td><td>Chia sẻ, dữ liệu lớn</td></tr>
</table>

<h4>Bước 3: Chọn trường hiển thị</h4>
<p>Tích chọn trường thuộc tính hiện trong popup Google Earth.
Bỏ tích các trường không cần (VD: mã nội bộ).</p>

<h4>Bước 4: Cấu hình kiểu popup</h4>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th></tr>
<tr><td><b>Màu tô</b></td><td>Tô vùng/điểm</td><td>Vàng</td></tr>
<tr><td><b>Màu viền</b></td><td>Màu đường bao</td><td>Đỏ</td></tr>
<tr><td><b>Độ rộng viền</b></td><td>Độ dày (px)</td><td>2</td></tr>
<tr><td><b>Độ trong suốt</b></td><td>0–100%</td><td>50%</td></tr>
<tr><td><b>Trường nhãn</b></td><td>Tên hiển thị trên bản đồ</td><td>Trường đầu</td></tr>
</table>

<h4>Bước 5: Xuất file</h4>
<ol>
<li>Nhấn <b>Xuất KML/KMZ</b></li>
<li>Chọn thư mục lưu</li>
<li>Mở bằng Google Earth để kiểm tra</li>
</ol>

<h3>📌 Tab 2 — Nhập KML/KMZ → SHP</h3>

<h4>Bước 1: Chọn file</h4>
<p>Chọn file .kml hoặc .kmz. KMZ tự động giải nén.</p>

<h4>Bước 2: Xem trước lớp</h4>
<p>Tự động phát hiện loại hình học và tách thành các lớp riêng
(Điểm, Đường, Vùng) nếu hỗn hợp.</p>

<h4>Bước 3: Chọn trường</h4>
<p>Chọn thuộc tính KML cần nhập. Extended Data và description
được phân tích tự động.</p>

<h4>Bước 4: Nhập</h4>
<ol>
<li>Nhấn <b>Nhập</b></li>
<li>Lớp được thêm vào QGIS với CRS đúng (WGS84)</li>
<li>Lưu thành Shapefile/GeoPackage nếu cần</li>
</ol>

<h3>📌 Tab 3 — Hướng dẫn</h3>
<p>Hướng dẫn trực quan với preview popup cho thấy KML
sẽ hiển thị như thế nào trên Google Earth.</p>

<h3>💾 Cấu hình</h3>
<ul>
<li><b>Lưu cấu hình:</b> Lưu cài đặt hiện tại để dùng lại</li>
<li><b>Tải cấu hình:</b> Khôi phục cài đặt đã lưu</li>
<li><b>Đặt lại:</b> Khôi phục mặc định</li>
</ul>

<div class='tip'>💡 KMZ là KML nén — nhỏ hơn tới 10 lần để chia sẻ.
Chỉ dùng KML khi cần chỉnh sửa XML thủ công.</div>

<div class='warn'>⚠️ KML chỉ dùng WGS84 (EPSG:4326). Các lớp ở CRS khác
sẽ tự động chuyển đổi khi xuất.</div>
"""),
    },

    # ================================================================
    # PLOT LABELS
    # ================================================================
    "plot_labels": {
        "en": _h("""
<h2>🏷️ Plot Labels — Fraction-style Parcel Labels</h2>
<h3>Overview</h3>
<p>Create fraction-style parcel labels for cadastral/forestry maps
showing Plot_ID / LDLR code and Area in a stacked format.</p>

<h3>📌 Step 1 — Select Layer</h3>
<p>Choose the polygon layer containing plot data with fields for
ID, land-use type, and area.</p>

<h3>📌 Step 2 — Configure Numerator / Denominator</h3>
<table>
<tr><th>Position</th><th>Typical Field</th><th>Example</th></tr>
<tr><td><b>Top (Numerator)</b></td><td>Plot_ID or TK_LO</td><td>LO_01</td></tr>
<tr><td><b>Bottom (Denominator)</b></td><td>LDLR + Area</td><td>TXG / 3.25</td></tr>
</table>

<h3>📌 Step 3 — Formatting</h3>
<ul>
<li><b>Decimal places:</b> Rounding for area (-1 = no rounding)</li>
<li><b>Font:</b> Family, size, color</li>
<li><b>Buffer:</b> White halo around text</li>
<li><b>Scale range:</b> Min/max zoom for visibility</li>
</ul>

<h3>📌 Step 4 — Apply</h3>
<ol>
<li>Click <b>Apply</b> to generate labels</li>
<li>Labels appear at polygon centroids</li>
<li>Adjust settings and re-apply as needed</li>
</ol>

<div class='tip'>💡 The fraction format matches Vietnamese forestry standards
for plot annotation on thematic maps.</div>
"""),
        "vi": _h("""
<h2>🏷️ Nhãn lô — Phân số trên bản đồ</h2>
<h3>Tổng quan</h3>
<p>Tạo nhãn dạng phân số cho lô đất/rừng trên bản đồ
hiển thị Mã lô / Mã LDLR và Diện tích theo dạng xếp chồng.</p>

<h3>📌 Bước 1 — Chọn lớp</h3>
<p>Chọn lớp polygon chứa dữ liệu lô với các trường
mã lô, loại đất loại rừng, và diện tích.</p>

<h3>📌 Bước 2 — Cấu hình Tử số / Mẫu số</h3>
<table>
<tr><th>Vị trí</th><th>Trường phổ biến</th><th>Ví dụ</th></tr>
<tr><td><b>Trên (Tử số)</b></td><td>Mã lô hoặc TK_LO</td><td>LO_01</td></tr>
<tr><td><b>Dưới (Mẫu số)</b></td><td>LDLR + Diện tích</td><td>TXG / 3.25</td></tr>
</table>

<h3>📌 Bước 3 — Định dạng</h3>
<ul>
<li><b>Số thập phân:</b> Làm tròn diện tích (-1 = không làm tròn)</li>
<li><b>Font:</b> Phông, cỡ, màu</li>
<li><b>Buffer:</b> Quầng trắng quanh chữ</li>
<li><b>Phạm vi tỷ lệ:</b> Zoom min/max hiển thị</li>
</ul>

<h3>📌 Bước 4 — Áp dụng</h3>
<ol>
<li>Nhấn <b>Áp dụng</b> để tạo nhãn</li>
<li>Nhãn hiện tại tâm polygon</li>
<li>Chỉnh cài đặt và áp dụng lại nếu cần</li>
</ol>

<div class='tip'>💡 Dạng phân số phù hợp với tiêu chuẩn lâm nghiệp Việt Nam
cho ghi chú lô trên bản đồ chuyên đề.</div>
"""),
    },

    # ================================================================
    # MBTILES
    # ================================================================
    "mbtiles": {
        "en": _h("""
<h2>🗺️ MBTiles Creator — Offline Map Tiles</h2>
<h3>Overview</h3>
<p>Export your QGIS map as MBTiles for offline mobile use in QField,
Avenza Maps, or any MBTiles-compatible app. Includes polygon styling
and integrated plot labeling.</p>

<h3>📌 Step 1 — Select Layer</h3>
<p>Choose a vector polygon layer from the dropdown.
Geometry type and feature count are shown automatically.</p>

<h3>📌 Step 2 — Stroke & Fill</h3>
<p><b>Stroke:</b> Pick outline color (#55ff00 = green) and width (default 0.5 px).<br>
<b>Fill:</b> Pick fill color (#ffff00 = yellow) and opacity (default 5% = nearly transparent).</p>

<h3>📌 Step 3 — Configure Plot Label (Fraction format)</h3>
<p>☑ Check <b>"Show Label"</b> to enable.</p>
<p><b>▲ Numerator (top):</b> Check fields to display. Check order = display order left → right.<br>
<b>▼ Denominator (bottom):</b> Check fields similarly.<br>
<b>Sep:</b> Separator character between fields (default "-").<br>
<b>Suffix:</b> Append unit after value (e.g. "ha", "trees", "m²").</p>

<h3>📌 Step 4 — Font & Formatting</h3>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th></tr>
<tr><td><b>Font</b></td><td>Font family</td><td>Arial</td></tr>
<tr><td><b>Size</b></td><td>Point size</td><td>10 pt</td></tr>
<tr><td><b>Color</b></td><td>Font color</td><td>#00ffff (cyan)</td></tr>
<tr><td><b>Bold</b></td><td>Bold text</td><td>Off</td></tr>
<tr><td><b>Line Height (%)</b></td><td>Spacing between numerator/denominator</td><td>20% (compact)</td></tr>
<tr><td><b>Underline count</b></td><td>Number of "_" chars</td><td>Auto</td></tr>
<tr><td><b>Spacing lines</b></td><td>Extra blank lines between underline and denominator</td><td>0</td></tr>
</table>

<h3>📌 Step 5 — Scale Visibility</h3>
<p><b>🔍+ Near:</b> Most zoomed-in scale (default 1:1,000).<br>
<b>🔍− Far:</b> Most zoomed-out scale (default 1:7,500).<br>
Labels only render when the map is within this range.</p>

<h3>📌 Step 6 — Buffer & Background</h3>
<p><b>☑ Buffer:</b> Text outline for readability. Pick color and size (mm).<br>
<b>☐ Background:</b> Rectangle behind label. Pick color and corner radius (mm).</p>

<h3>📌 Step 7 — Preview</h3>
<p>The <b>"Preview"</b> area renders the label on the polygon live.<br>
☑ <b>Satellite BG:</b> Toggle satellite background to check contrast.</p>

<h3>📌 Step 8 — Apply / Export</h3>
<p>🎨 <b>Apply Style:</b> Apply all settings to the QGIS layer instantly.<br>
📦 <b>Export MBTiles:</b> Export selected area as .mbtiles file.<br>
🗺️ <b>Include basemap:</b> Embed satellite/street tiles in export.<br>
🔄 <b>Reset:</b> Restore all settings to defaults.<br>
💾 <b>Save Config:</b> Save current settings to a JSON file.<br>
📂 <b>Load Config:</b> Load settings from a previously saved JSON file.</p>

<div class='tip'>💡 Start with zoom 10–14 for reasonable file sizes.
Each additional zoom level quadruples the number of tiles.</div>

<div class='warn'>⚠️ Zoom 17+ with basemap can produce files >500 MB.
Disable basemap for vector-only exports.</div>
"""),
        "vi": _h("""
<h2>🗺️ Hướng dẫn sử dụng MBTiles Creator</h2>
<h3>Tổng quan</h3>
<p>Xuất bản đồ QGIS thành MBTiles để dùng offline trên điện thoại
(QField, Avenza Maps, hoặc ứng dụng hỗ trợ MBTiles). Bao gồm tô màu
polygon và nhãn lô tích hợp.</p>

<h3>📌 Bước 1 — Chọn lớp dữ liệu</h3>
<p>Chọn lớp vector polygon từ danh sách.
Thông tin hình học và số đối tượng sẽ hiển thị tự động.</p>

<h3>📌 Bước 2 — Thiết lập nét lực / nền polygon</h3>
<p><b>Nét lực (Stroke):</b> Chọn màu viền lô (#55ff00 = xanh lá) và độ rộng (mặc định 0.5 px).<br>
<b>Nền (Fill):</b> Chọn màu nền lô (#ffff00 = vàng) và độ mờ (mặc định 5% = gần trong suốt).</p>

<h3>📌 Bước 3 — Cấu hình Nhãn lô (dạng phân số)</h3>
<p>☑ Tick <b>"Hiển thị nhãn"</b> để bật.</p>
<p><b>▲ Tử số (trên):</b> Tick các trường muốn hiển thị. Thứ tự tick = thứ tự hiển thị từ trái → phải.<br>
<b>▼ Mẫu số (dưới):</b> Tick các trường tương tự.<br>
<b>Nối:</b> Ký tự nối giữa các trường (mặc định "-").<br>
<b>Hậu tố:</b> Thêm đơn vị sau giá trị (ví dụ: "ha", "cây", "m²").</p>

<h3>📌 Bước 4 — Phông chữ & Định dạng</h3>
<table>
<tr><th>Thông số</th><th>Mô tả</th><th>Mặc định</th></tr>
<tr><td><b>Phông</b></td><td>Font chữ</td><td>Arial</td></tr>
<tr><td><b>Cỡ</b></td><td>Kích thước (pt)</td><td>10 pt</td></tr>
<tr><td><b>Màu</b></td><td>Màu chữ</td><td>#00ffff (cyan)</td></tr>
<tr><td><b>Đậm</b></td><td>In đậm</td><td>Tắt</td></tr>
<tr><td><b>Giãn dòng (%)</b></td><td>Khoảng cách tử số/mẫu số</td><td>20% (compact)</td></tr>
<tr><td><b>Số gạch dưới</b></td><td>Số ký tự "_" ngăn cách</td><td>Tự động</td></tr>
<tr><td><b>Số dòng giãn</b></td><td>Dòng trống thêm giữa gạch và mẫu số</td><td>0</td></tr>
</table>

<h3>📌 Bước 5 — Tỷ lệ hiển thị</h3>
<p><b>🔍+ Gần:</b> Tỷ lệ khi zoom gần nhất (mặc định 1:1.000).<br>
<b>🔍− Xa:</b> Tỷ lệ khi zoom xa nhất (mặc định 1:7.500).<br>
Nhãn chỉ hiển thị khi bản đồ nằm trong khoảng này.</p>

<h3>📌 Bước 6 — Viền chữ & Nền chữ</h3>
<p><b>☑ Viền chữ (Buffer):</b> Tạo viền xung quanh chữ giúp dễ đọc. Chọn màu và độ dày (mm).<br>
<b>☐ Nền chữ (Background):</b> Khung nền phía sau nhãn. Chọn màu, bo góc (mm).</p>

<h3>📌 Bước 7 — Xem trước</h3>
<p>Khu vực <b>"Xem trước"</b> hiển thị nhãn trên nền polygon ngay khi thay đổi.<br>
☑ <b>Nền vệ tinh:</b> Bật tắt ảnh nền để kiểm tra tương phản.</p>

<h3>📌 Bước 8 — Áp dụng / Xuất</h3>
<p>🎨 <b>Áp dụng kiểu:</b> Gán tất cả cài đặt lên layer QGIS ngay lập tức.<br>
📦 <b>Export MBTiles:</b> Xuất vùng chọn thành file .mbtiles.<br>
🗺️ <b>Bao gồm bản đồ nền:</b> Nhúng ảnh vệ tinh/đường vào export.<br>
🔄 <b>Đặt lại:</b> Khôi phục toàn bộ về mặc định.<br>
💾 <b>Lưu cấu hình:</b> Lưu cài đặt hiện tại ra file JSON.<br>
📂 <b>Tải cấu hình:</b> Nạp lại cài đặt từ file JSON đã lưu.</p>

<div class='tip'>💡 Bắt đầu với zoom 10–14 cho kích thước file hợp lý.
Mỗi mức zoom thêm sẽ gấp 4 lần số tile.</div>

<div class='warn'>⚠️ Zoom 17+ kèm bản đồ nền có thể tạo file >500 MB.
Tắt bản đồ nền nếu chỉ xuất vector.</div>
"""),
    },

    # ================================================================
    # LEGAL DOCS
    # ================================================================
    "legal_docs": {
        "en": _h("""
<h2>📜 Legal Documents</h2>
<h3>Overview</h3>
<p>Browse embedded Vietnamese forestry legal documents (TCVN standards).</p>
<ul>
<li>TCVN 11565-2016: Forest status map symbols</li>
<li>TCVN 11566-2016: Forestry planning map symbols</li>
</ul>
<div class='tip'>💡 Documents are bundled with the plugin — no internet required.</div>
"""),
        "vi": _h("""
<h2>📜 Văn bản pháp lý</h2>
<h3>Tổng quan</h3>
<p>Tra cứu văn bản pháp lý lâm nghiệp Việt Nam (tiêu chuẩn TCVN).</p>
<ul>
<li>TCVN 11565-2016: Ký hiệu bản đồ hiện trạng rừng</li>
<li>TCVN 11566-2016: Ký hiệu bản đồ quy hoạch lâm nghiệp</li>
</ul>
<div class='tip'>💡 Tài liệu đã tích hợp trong plugin — không cần internet.</div>
"""),
    },

    # ================================================================
    # MAP PACKAGER
    # ================================================================
    "map_packager": {
        "en": _h("""
<h2>📦 Package Map — Portable GeoPackage</h2>
<h3>Overview</h3>
<p>Package multiple map layers into a single portable GeoPackage (.gpkg)
file for sharing, backup, or offline use.</p>

<h3>📌 Step 1 — Select Layers</h3>
<p>Check the layers you want to include in the package.
All geometry types and attribute data are preserved.</p>

<h3>📌 Step 2 — Choose Output</h3>
<table>
<tr><th>Option</th><th>Description</th></tr>
<tr><td><b>Output folder</b></td><td>Where to save the .gpkg file</td></tr>
<tr><td><b>File name</b></td><td>Name for the output package</td></tr>
<tr><td><b>Include styles</b></td><td>Embed QGIS layer styles in package</td></tr>
</table>

<h3>📌 Step 3 — Package</h3>
<ol>
<li>Click <b>Package</b></li>
<li>Wait for processing (progress bar shown)</li>
<li>Open the .gpkg in QGIS on any computer</li>
</ol>

<h3>Why GeoPackage?</h3>
<ul>
<li>Single file — no .shp/.shx/.dbf/.prj mess</li>
<li>No 10-char field name limit (unlike Shapefile)</li>
<li>Supports multiple layers in one file</li>
<li>Stores styles, metadata, and CRS information</li>
</ul>

<div class='tip'>💡 GeoPackage is the modern replacement for Shapefile.
Use it for sharing data with colleagues or archiving projects.</div>
"""),
        "vi": _h("""
<h2>📦 Đóng gói bản đồ — GeoPackage di động</h2>
<h3>Tổng quan</h3>
<p>Đóng gói nhiều lớp bản đồ thành 1 file GeoPackage (.gpkg)
để chia sẻ, sao lưu, hoặc dùng offline.</p>

<h3>📌 Bước 1 — Chọn lớp</h3>
<p>Tích chọn các lớp cần đóng gói.
Toàn bộ hình học và thuộc tính được giữ nguyên.</p>

<h3>📌 Bước 2 — Chọn đầu ra</h3>
<table>
<tr><th>Tùy chọn</th><th>Mô tả</th></tr>
<tr><td><b>Thư mục</b></td><td>Nơi lưu file .gpkg</td></tr>
<tr><td><b>Tên file</b></td><td>Tên gói đầu ra</td></tr>
<tr><td><b>Kèm style</b></td><td>Nhúng kiểu hiển thị QGIS vào gói</td></tr>
</table>

<h3>📌 Bước 3 — Đóng gói</h3>
<ol>
<li>Nhấn <b>Đóng gói</b></li>
<li>Chờ xử lý (có thanh tiến trình)</li>
<li>Mở file .gpkg trên QGIS bất kỳ máy nào</li>
</ol>

<h3>Tại sao dùng GeoPackage?</h3>
<ul>
<li>1 file duy nhất — không còn .shp/.shx/.dbf/.prj rời rạc</li>
<li>Không giới hạn 10 ký tự tên trường (khác Shapefile)</li>
<li>Hỗ trợ nhiều lớp trong 1 file</li>
<li>Lưu style, metadata, và thông tin CRS</li>
</ul>

<div class='tip'>💡 GeoPackage là thay thế hiện đại cho Shapefile.
Dùng để chia sẻ dữ liệu với đồng nghiệp hoặc lưu trữ dự án.</div>
"""),
    },
    # ================================================================
    # EXCEL TO GIS
    # ================================================================
    "excel_gis": {
        "en": _h("""
<h2>📊 Excel → GIS Converter</h2>
<h3>Overview</h3>
<p>Import Excel (.xlsx) or CSV files containing coordinate columns
into QGIS as point vector layers. Supports WGS84, VN-2000, and UTM.</p>

<h3>📌 Step 1 — Select File</h3>
<p>Click <b>Browse</b> and choose your Excel or CSV file.
Supported formats: .xlsx, .xls, .csv</p>

<h3>📌 Step 2 — Select Sheet</h3>
<p>For multi-sheet Excel files, choose the sheet containing coordinates
from the dropdown. CSV files skip this step.</p>

<h3>📌 Step 3 — Map Coordinate Columns</h3>
<table>
<tr><th>Field</th><th>Description</th><th>Example</th></tr>
<tr><td><b>X / Longitude</b></td><td>East-West coordinate column</td><td>lon, X, E, Kinh_do</td></tr>
<tr><td><b>Y / Latitude</b></td><td>North-South coordinate column</td><td>lat, Y, N, Vi_do</td></tr>
</table>
<p>The plugin auto-detects common column names (lon, lat, x, y).</p>

<h3>📌 Step 4 — Choose CRS</h3>
<table>
<tr><th>Coordinate Type</th><th>CRS to Select</th></tr>
<tr><td>Decimal degrees (105.8, 16.4)</td><td>EPSG:4326 (WGS84)</td></tr>
<tr><td>VN-2000 province (500000, 1800000)</td><td>VN-2000 / province zone</td></tr>
<tr><td>UTM zone (600000, 1800000)</td><td>UTM Zone 48N/49N</td></tr>
</table>

<h3>📌 Step 5 — Import & Verify</h3>
<ol>
<li>Click <b>Import</b></li>
<li>Points appear on the map canvas</li>
<li>Open attribute table to verify data</li>
<li>Save as Shapefile/GeoPackage if needed</li>
</ol>

<div class='tip'>💡 For VN-2000 coordinates, select the correct province zone.
Wrong zone = points shifted hundreds of meters.</div>

<div class='warn'>⚠️ Ensure coordinates are numeric, not text.
Remove spaces, commas in numbers, and header formatting.</div>
"""),
        "vi": _h("""
<h2>📊 Chuyển Excel vào bản đồ</h2>
<h3>Tổng quan</h3>
<p>Nhập file Excel (.xlsx) hoặc CSV chứa cột tọa độ vào QGIS
thành lớp vector điểm. Hỗ trợ WGS84, VN-2000, và UTM.</p>

<h3>📌 Bước 1 — Chọn file</h3>
<p>Nhấn <b>Duyệt</b> và chọn file Excel hoặc CSV.
Định dạng hỗ trợ: .xlsx, .xls, .csv</p>

<h3>📌 Bước 2 — Chọn sheet</h3>
<p>Với file Excel nhiều sheet, chọn sheet chứa tọa độ.
File CSV bỏ qua bước này.</p>

<h3>📌 Bước 3 — Ánh xạ cột tọa độ</h3>
<table>
<tr><th>Trường</th><th>Mô tả</th><th>Ví dụ</th></tr>
<tr><td><b>X / Kinh độ</b></td><td>Cột tọa độ Đông-Tây</td><td>lon, X, E, Kinh_do</td></tr>
<tr><td><b>Y / Vĩ độ</b></td><td>Cột tọa độ Bắc-Nam</td><td>lat, Y, N, Vi_do</td></tr>
</table>
<p>Plugin tự phát hiện tên cột phổ biến (lon, lat, x, y).</p>

<h3>📌 Bước 4 — Chọn hệ tọa độ</h3>
<table>
<tr><th>Loại tọa độ</th><th>CRS cần chọn</th></tr>
<tr><td>Độ thập phân (105.8, 16.4)</td><td>EPSG:4326 (WGS84)</td></tr>
<tr><td>VN-2000 tỉnh (500000, 1800000)</td><td>VN-2000 / múi tỉnh</td></tr>
<tr><td>UTM zone (600000, 1800000)</td><td>UTM Zone 48N/49N</td></tr>
</table>

<h3>📌 Bước 5 — Nhập & Kiểm tra</h3>
<ol>
<li>Nhấn <b>Nhập</b></li>
<li>Điểm xuất hiện trên canvas</li>
<li>Mở bảng thuộc tính để kiểm tra</li>
<li>Lưu thành Shapefile/GeoPackage nếu cần</li>
</ol>

<div class='tip'>💡 Với tọa độ VN-2000, chọn đúng múi tỉnh.
Sai múi = điểm lệch hàng trăm mét.</div>

<div class='warn'>⚠️ Đảm bảo tọa độ là số, không phải chữ.
Xóa dấu cách, dấu phẩy trong số, và định dạng tiêu đề.</div>
"""),
    },
    # ================================================================
    # FONT CONVERTER
    # ================================================================
    "font_converter": {
        "en": _h("""
<h2>🔤 Font Encoding Converter</h2>
<h3>Overview</h3>
<p>Convert Vietnamese text encoding between Unicode, TCVN3 (.VnTime),
and VNI in GIS attribute tables. Export to Shapefile or MapInfo TAB.</p>

<h3>📌 Step 1 — Select Layer</h3>
<p>Choose the vector layer containing text fields to convert.</p>

<h3>📌 Step 2 — Choose Conversion Mode</h3>
<table>
<tr><th>Mode</th><th>From</th><th>To</th><th>Use Case</th></tr>
<tr><td><b>Unicode → TCVN3</b></td><td>Unicode</td><td>.VnTime</td><td>Export for MapInfo</td></tr>
<tr><td><b>TCVN3 → Unicode</b></td><td>.VnTime</td><td>Unicode</td><td>Modernize legacy data</td></tr>
<tr><td><b>VNI → Unicode</b></td><td>VNI-Windows</td><td>Unicode</td><td>Convert old VNI files</td></tr>
<tr><td><b>No conversion</b></td><td>—</td><td>—</td><td>Export format change only</td></tr>
</table>

<h3>📌 Step 3 — Select Fields</h3>
<p>Check which text fields to convert. Numeric fields are skipped.</p>

<h3>📌 Step 4 — Choose Output Format</h3>
<table>
<tr><th>Format</th><th>Extension</th><th>Notes</th></tr>
<tr><td><b>Shapefile</b></td><td>.shp</td><td>Most compatible</td></tr>
<tr><td><b>MapInfo TAB</b></td><td>.tab</td><td>For MapInfo Professional</td></tr>
<tr><td><b>GeoPackage</b></td><td>.gpkg</td><td>Modern single-file</td></tr>
</table>

<h3>📌 Step 5 — Export</h3>
<ol>
<li>Click <b>Convert & Export</b></li>
<li>Choose save location</li>
<li>Converted layer is added to QGIS</li>
</ol>

<div class='tip'>💡 Preview conversion: check the attribute table before exporting
to verify Vietnamese characters display correctly.</div>

<div class='warn'>⚠️ For MapInfo TAB with TCVN3: disable Enhanced Rendering
in MapInfo settings, otherwise .VnTime fonts display incorrectly.</div>
"""),
        "vi": _h("""
<h2>🔤 Chuyển đổi mã font chữ</h2>
<h3>Tổng quan</h3>
<p>Chuyển đổi mã hóa chữ Việt giữa Unicode, TCVN3 (.VnTime),
và VNI trong bảng thuộc tính GIS. Xuất ra Shapefile hoặc MapInfo TAB.</p>

<h3>📌 Bước 1 — Chọn lớp</h3>
<p>Chọn lớp vector chứa trường văn bản cần chuyển.</p>

<h3>📌 Bước 2 — Chọn chế độ chuyển đổi</h3>
<table>
<tr><th>Chế độ</th><th>Từ</th><th>Sang</th><th>Mục đích</th></tr>
<tr><td><b>Unicode → TCVN3</b></td><td>Unicode</td><td>.VnTime</td><td>Xuất cho MapInfo</td></tr>
<tr><td><b>TCVN3 → Unicode</b></td><td>.VnTime</td><td>Unicode</td><td>Hiện đại hóa dữ liệu cũ</td></tr>
<tr><td><b>VNI → Unicode</b></td><td>VNI-Windows</td><td>Unicode</td><td>Chuyển file VNI cũ</td></tr>
<tr><td><b>Không chuyển</b></td><td>—</td><td>—</td><td>Chỉ đổi định dạng</td></tr>
</table>

<h3>📌 Bước 3 — Chọn trường</h3>
<p>Tích chọn trường văn bản cần chuyển. Trường số tự bỏ qua.</p>

<h3>📌 Bước 4 — Chọn định dạng xuất</h3>
<table>
<tr><th>Định dạng</th><th>Đuôi file</th><th>Ghi chú</th></tr>
<tr><td><b>Shapefile</b></td><td>.shp</td><td>Tương thích nhất</td></tr>
<tr><td><b>MapInfo TAB</b></td><td>.tab</td><td>Cho MapInfo Professional</td></tr>
<tr><td><b>GeoPackage</b></td><td>.gpkg</td><td>Hiện đại, 1 file</td></tr>
</table>

<h3>📌 Bước 5 — Xuất</h3>
<ol>
<li>Nhấn <b>Chuyển đổi & Xuất</b></li>
<li>Chọn nơi lưu</li>
<li>Lớp đã chuyển đổi thêm vào QGIS</li>
</ol>

<div class='tip'>💡 Xem trước: kiểm tra bảng thuộc tính trước khi xuất
để xác nhận chữ Việt hiển thị đúng.</div>

<div class='warn'>⚠️ MapInfo TAB với TCVN3: tắt Enhanced Rendering
trong cài đặt MapInfo, nếu không font .VnTime hiển thị sai.</div>
"""),
    },
    # ================================================================
    # CRS TOOLS
    # ================================================================
    "crs_tools": {
        "en": _h("""
<h2>🌐 Coordinate System (CRS Tools)</h2>
<h3>Overview</h3>
<p>Transform or define coordinate reference systems for GIS layers.
Includes a complete VN-2000 province zone catalog.</p>

<h3>📌 Tab 1 — CRS Conversion (Transform)</h3>
<p>Reproject a layer from one CRS to another (coordinates change):</p>
<ol>
<li>Select <b>input layer</b></li>
<li>Select <b>target CRS</b> (e.g. WGS84, VN-2000 province)</li>
<li>Click <b>Convert</b> — new layer created with transformed coordinates</li>
</ol>

<h3>📌 Tab 2 — Define CRS (Assign)</h3>
<p>Assign CRS to a layer WITHOUT transforming coordinates.
Use when data is correct but CRS metadata is missing/wrong:</p>
<ol>
<li>Select layer with unknown/wrong CRS</li>
<li>Select the <b>correct CRS</b> the data is already in</li>
<li>Click <b>Define</b> — only metadata changes, coordinates unchanged</li>
</ol>

<h3>📌 Tab 3 — VN-2000 Catalog</h3>
<table>
<tr><th>Info</th><th>Description</th></tr>
<tr><td><b>Province</b></td><td>All 63 provinces with cadastral codes</td></tr>
<tr><td><b>Central Meridian</b></td><td>3-degree zone meridian for each province</td></tr>
<tr><td><b>EPSG Code</b></td><td>Corresponding EPSG identifier</td></tr>
</table>

<div class='tip'>💡 <b>Convert vs Define:</b> Convert = change coordinates.
Define = keep coordinates, change label. Use Define when your data
"floats in the ocean" because CRS is not set.</div>

<div class='warn'>⚠️ VN-2000 uses 3-degree zones. Each province has a specific
central meridian. Using the wrong zone shifts data by kilometers.</div>
"""),
        "vi": _h("""
<h2>🌐 Hệ tọa độ (CRS Tools)</h2>
<h3>Tổng quan</h3>
<p>Chuyển đổi hoặc gán hệ tọa độ cho lớp GIS.
Kèm danh mục đầy đủ múi VN-2000 theo tỉnh.</p>

<h3>📌 Tab 1 — Chuyển đổi CRS</h3>
<p>Chiếu lại lớp từ CRS này sang CRS khác (tọa độ thay đổi):</p>
<ol>
<li>Chọn <b>lớp đầu vào</b></li>
<li>Chọn <b>CRS đích</b> (VD: WGS84, VN-2000 tỉnh)</li>
<li>Nhấn <b>Chuyển đổi</b> — tạo lớp mới với tọa độ đã chuyển</li>
</ol>

<h3>📌 Tab 2 — Gán CRS</h3>
<p>Gán CRS cho lớp MÀ KHÔNG chuyển đổi tọa độ.
Dùng khi dữ liệu đúng nhưng thiếu/sai metadata CRS:</p>
<ol>
<li>Chọn lớp không rõ CRS</li>
<li>Chọn <b>CRS đúng</b> mà dữ liệu đang dùng</li>
<li>Nhấn <b>Gán</b> — chỉ đổi nhãn, tọa độ giữ nguyên</li>
</ol>

<h3>📌 Tab 3 — Danh mục VN-2000</h3>
<table>
<tr><th>Thông tin</th><th>Mô tả</th></tr>
<tr><td><b>Tỉnh</b></td><td>63 tỉnh/TP với mã địa chính</td></tr>
<tr><td><b>Kinh tuyến trục</b></td><td>Kinh tuyến múi 3 độ từng tỉnh</td></tr>
<tr><td><b>Mã EPSG</b></td><td>Mã EPSG tương ứng</td></tr>
</table>

<div class='tip'>💡 <b>Chuyển đổi vs Gán:</b> Chuyển đổi = đổi tọa độ.
Gán = giữ tọa độ, đổi nhãn. Dùng Gán khi dữ liệu
"trôi ngoài đại dương" vì chưa có CRS.</div>

<div class='warn'>⚠️ VN-2000 dùng múi 3 độ. Mỗi tỉnh có kinh tuyến trục riêng.
Sai múi = dữ liệu lệch hàng km.</div>
"""),
    },
    # ================================================================
    # COORD CONVERTER
    # ================================================================
    "coord_convert": {
        "en": _h("""
<h2>📍 Coordinate Converter (Lat/Long)</h2>
<h3>Overview</h3>
<p>Convert individual coordinate pairs between CRS systems.
Supports VN-2000, WGS84, UTM, and custom CRS.</p>

<h3>📌 Step 1 — Enter Coordinates</h3>
<table>
<tr><th>Input Format</th><th>Example</th></tr>
<tr><td>Decimal degrees</td><td>X: 107.5901, Y: 16.4637</td></tr>
<tr><td>VN-2000 meters</td><td>X: 548234.5, Y: 1821456.7</td></tr>
<tr><td>UTM meters</td><td>X: 648234.5, Y: 1821456.7</td></tr>
</table>

<h3>📌 Step 2 — Select CRS</h3>
<ul>
<li><b>Source CRS:</b> The CRS your input coordinates are in</li>
<li><b>Target CRS:</b> The CRS you want to convert to</li>
</ul>

<h3>📌 Step 3 — Actions</h3>
<table>
<tr><th>Button</th><th>Action</th></tr>
<tr><td><b>Convert</b></td><td>Calculate converted coordinates</td></tr>
<tr><td><b>Zoom</b></td><td>Pan map to the converted location</td></tr>
<tr><td><b>Add Marker</b></td><td>Place a point on the map</td></tr>
<tr><td><b>Copy</b></td><td>Copy result to clipboard</td></tr>
</table>

<div class='tip'>💡 Use Zoom to visually verify the coordinate is correct
before using it in reports or field work.</div>

<div class='warn'>⚠️ Ensure X = Longitude (East-West) and Y = Latitude (North-South).
Swapping them places the point in the wrong hemisphere.</div>
"""),
        "vi": _h("""
<h2>📍 Chuyển đổi tọa độ (Lat/Long)</h2>
<h3>Tổng quan</h3>
<p>Chuyển đổi cặp tọa độ đơn lẻ giữa các hệ tọa độ.
Hỗ trợ VN-2000, WGS84, UTM, và CRS tùy chỉnh.</p>

<h3>📌 Bước 1 — Nhập tọa độ</h3>
<table>
<tr><th>Định dạng nhập</th><th>Ví dụ</th></tr>
<tr><td>Độ thập phân</td><td>X: 107.5901, Y: 16.4637</td></tr>
<tr><td>VN-2000 mét</td><td>X: 548234.5, Y: 1821456.7</td></tr>
<tr><td>UTM mét</td><td>X: 648234.5, Y: 1821456.7</td></tr>
</table>

<h3>📌 Bước 2 — Chọn hệ tọa độ</h3>
<ul>
<li><b>CRS nguồn:</b> Hệ tọa độ của tọa độ nhập vào</li>
<li><b>CRS đích:</b> Hệ tọa độ muốn chuyển sang</li>
</ul>

<h3>📌 Bước 3 — Thao tác</h3>
<table>
<tr><th>Nút</th><th>Chức năng</th></tr>
<tr><td><b>Chuyển đổi</b></td><td>Tính tọa độ đã chuyển</td></tr>
<tr><td><b>Zoom</b></td><td>Di chuyển bản đồ đến vị trí</td></tr>
<tr><td><b>Thêm điểm</b></td><td>Đặt điểm trên bản đồ</td></tr>
<tr><td><b>Sao chép</b></td><td>Copy kết quả vào clipboard</td></tr>
</table>

<div class='tip'>💡 Dùng Zoom để xác nhận trực quan tọa độ đúng
trước khi dùng trong báo cáo hoặc khảo sát thực địa.</div>

<div class='warn'>⚠️ Đảm bảo X = Kinh độ (Đông-Tây) và Y = Vĩ độ (Bắc-Nam).
Đảo ngược sẽ đặt điểm sai bán cầu.</div>
"""),
    },
    # ================================================================
    "eudr": {
        "en": _h("""
<h2>🌍 EUDR GeoJSON Export</h2>
<h3>Overview</h3>
<p>Export vector layers to EUDR-compliant GeoJSON format per
EU Regulation 2023/1115 (EU Deforestation Regulation).</p>

<div class='tip'><b>Objective:</b> Collect, process, and deliver geolocation data
for production plots to prove no deforestation link after 31/12/2020.</div>

<h3>GIS Workflow for EUDR</h3>
<table>
<tr><th>Step</th><th>Objective</th><th>Work</th></tr>
<tr><td>Collect</td><td>Record plots</td><td>GPS, draw polygon or point</td></tr>
<tr><td>Clean</td><td>Remove errors</td><td>Check geometry, fix coordinates</td></tr>
<tr><td>Standardize</td><td>EUDR format</td><td>EPSG:4326, correct identifiers</td></tr>
<tr><td>Submit</td><td>Deliver data</td><td>Check deforestation risk, attach docs</td></tr>
</table>

<h3>Data Types</h3>
<ul>
<li><b>Point:</b> Plots under 4 ha → single coordinate [long, lat]</li>
<li><b>Polygon:</b> Plots 4 ha+ → closed polygon boundary</li>
</ul>

<h3>Required Fields</h3>
<table>
<tr><th>Field</th><th>Description</th><th>Type</th><th>Required</th></tr>
<tr><td>Plot_ID</td><td>Plot identifier</td><td>Text</td><td>✅</td></tr>
<tr><td>Species</td><td>Crop species</td><td>Text</td><td>✅</td></tr>
<tr><td>Latitude</td><td>Lat of point</td><td>Float</td><td>✅ auto</td></tr>
<tr><td>Longitude</td><td>Lon of point</td><td>Float</td><td>✅ auto</td></tr>
<tr><td>Area_ha</td><td>Area in hectares</td><td>Float</td><td>✅ auto</td></tr>
<tr><td>Date</td><td>Collection date</td><td>yyyy-mm-dd</td><td>✅</td></tr>
<tr><td>FarmerID</td><td>Farmer/producer ID</td><td>Text</td><td>✅</td></tr>
<tr><td>ProducerCountry</td><td>ISO2 country code</td><td>2 chars</td><td>✅</td></tr>
<tr><td>ProductionPlace</td><td>Location name</td><td>Text</td><td>✅</td></tr>
</table>

<h3>Technical Requirements</h3>
<ul>
<li><b>CRS:</b> WGS84 (EPSG:4326)</li>
<li><b>Precision:</b> ≥6 decimal places (e.g. 105.123456)</li>
<li><b>Polygons:</b> Must be closed, no self-intersections</li>
<li><b>File size:</b> Max 25 MB</li>
</ul>

<h3>How to Use</h3>
<ol>
<li>Select vector layer with plot data</li>
<li>Map source fields to EUDR properties</li>
<li>Click <b>Preview Statistics</b> to check Point/Polygon split and detect errors</li>
<li>Click <b>Export GeoJSON</b> to save</li>
</ol>

<h3>Common Errors</h3>
<table>
<tr><th>#</th><th>Error</th><th>Fix</th></tr>
<tr><td>1</td><td>Unclosed polygon</td><td>Add last point = first</td></tr>
<tr><td>2</td><td>Wrong CRS</td><td>Reproject to EPSG:4326</td></tr>
<tr><td>3</td><td>Polygon holes</td><td>Split into 2 polygons</td></tr>
<tr><td>4</td><td>Self-intersection</td><td>Use Fix Geometry</td></tr>
<tr><td>5</td><td>Area as string</td><td>Use numeric 3.2 not "3.2"</td></tr>
<tr><td>6</td><td>File >25 MB</td><td>Simplify or split files</td></tr>
<tr><td>7</td><td>Duplicate coords</td><td>Use 6 decimal places</td></tr>
<tr><td>8</td><td>LineString type</td><td>Only Point/Polygon allowed</td></tr>
</table>

<div class='warn'>⚠️ Verify exported data on geojson.io and check against
GFW/EarthMap for forest overlap after 31/12/2020.</div>

<h3>File Naming</h3>
<p><code>FarmerID_VN_Acacia_2025-06.geojson</code></p>
"""),
        "vi": _h("""
<h2>🌍 Xuất GeoJSON EUDR</h2>
<h3>Tổng quan</h3>
<p>Xuất lớp vector sang định dạng GeoJSON tuân thủ EUDR
theo Quy định EU 2023/1115 (Quy định Chống phá rừng EU).</p>

<div class='tip'><b>Mục tiêu:</b> Thu thập, xử lý và cung cấp dữ liệu vị trí
vùng trồng nhằm chứng minh không liên quan đến mất rừng sau 31/12/2020.</div>

<h3>Quy trình GIS phục vụ EUDR</h3>
<table>
<tr><th>Bước</th><th>Mục tiêu</th><th>Công việc</th></tr>
<tr><td>Thu thập</td><td>Ghi nhận vùng trồng</td><td>GPS, vẽ polygon/point</td></tr>
<tr><td>Làm sạch</td><td>Loại sai sót</td><td>Kiểm tra hình học, tọa độ</td></tr>
<tr><td>Chuẩn hóa</td><td>Định dạng EUDR</td><td>EPSG:4326, định danh đúng</td></tr>
<tr><td>Gửi đi</td><td>Giao nộp chuẩn</td><td>Kiểm tra rủi ro phá rừng, đính kèm hồ sơ</td></tr>
</table>

<h3>Loại dữ liệu</h3>
<ul>
<li><b>Point:</b> Lô nhỏ dưới 4 ha → 1 tọa độ [long, lat]</li>
<li><b>Polygon:</b> Lô từ 4 ha trở lên → đa giác khép kín</li>
</ul>

<h3>Các trường bắt buộc</h3>
<table>
<tr><th>Trường</th><th>Ý nghĩa</th><th>Kiểu</th><th>Bắt buộc</th></tr>
<tr><td>Plot_ID</td><td>Mã số lô</td><td>Text</td><td>✅</td></tr>
<tr><td>Species</td><td>Loài cây trồng</td><td>Text</td><td>✅</td></tr>
<tr><td>Latitude</td><td>Vĩ độ</td><td>Float</td><td>✅ tự động</td></tr>
<tr><td>Longitude</td><td>Kinh độ</td><td>Float</td><td>✅ tự động</td></tr>
<tr><td>Area_ha</td><td>Diện tích (ha)</td><td>Float</td><td>✅ tự động</td></tr>
<tr><td>Date</td><td>Ngày thu thập</td><td>yyyy-mm-dd</td><td>✅</td></tr>
<tr><td>FarmerID</td><td>Mã nông hộ</td><td>Text</td><td>✅</td></tr>
<tr><td>ProducerCountry</td><td>Mã quốc gia ISO2</td><td>2 ký tự</td><td>✅</td></tr>
<tr><td>ProductionPlace</td><td>Nơi sản xuất</td><td>Text</td><td>✅</td></tr>
</table>

<h3>Yêu cầu kỹ thuật</h3>
<ul>
<li><b>Hệ tọa độ:</b> WGS84 (EPSG:4326)</li>
<li><b>Độ chính xác:</b> ≥6 số thập phân (VD: 105.123456)</li>
<li><b>Đa giác:</b> Phải đóng kín, không tự cắt</li>
<li><b>Kích thước file:</b> Tối đa 25 MB</li>
</ul>

<h3>Cách sử dụng</h3>
<ol>
<li>Chọn lớp vector chứa dữ liệu lô đất</li>
<li>Ánh xạ trường dữ liệu nguồn sang trường EUDR</li>
<li>Nhấn <b>Xem thống kê</b> để kiểm tra phân loại Point/Polygon và phát hiện lỗi</li>
<li>Nhấn <b>Xuất GeoJSON</b> để lưu file</li>
</ol>

<h3>Các lỗi phổ biến</h3>
<table>
<tr><th>STT</th><th>Lỗi</th><th>Cách khắc phục</th></tr>
<tr><td>1</td><td>Polygon không khép kín</td><td>Thêm điểm cuối = điểm đầu</td></tr>
<tr><td>2</td><td>Sai hệ tọa độ</td><td>Chuyển về EPSG:4326</td></tr>
<tr><td>3</td><td>Có lỗ trong polygon</td><td>Tách thành 2 polygon</td></tr>
<tr><td>4</td><td>Polygon tự cắt</td><td>Dùng Fix Geometry</td></tr>
<tr><td>5</td><td>Area dạng chuỗi</td><td>Ghi số 3.2 thay vì "3.2"</td></tr>
<tr><td>6</td><td>File vượt 25 MB</td><td>Simplify hoặc tách file</td></tr>
<tr><td>7</td><td>Tọa độ trùng</td><td>Dùng 6 số thập phân</td></tr>
<tr><td>8</td><td>LineString</td><td>Chỉ dùng Point/Polygon</td></tr>
</table>

<div class='warn'>⚠️ Kiểm tra dữ liệu xuất trên geojson.io và đối chiếu
GFW/EarthMap cho chồng lấn rừng sau 31/12/2020.</div>

<h3>Quy ước đặt tên file</h3>
<p><code>ID_Farmer_VN_Acacia_2025-06.geojson</code></p>
"""),
    },
    # ================================================================
    # THEMATIC MAP (TT 16/2023)
    # ================================================================
    "thematic": {
        "en": _h("""
<h2>🎨 Thematic Map — TT 16/2023 Style Library</h2>
<h3>Overview</h3>
<p>Apply official Vietnam forestry/land-use color symbology to polygon layers
using Circular 16/2023 (55 LDLR codes) or TT 33/2018 (98 codes).
Includes border styling and integrated plot labeling.</p>

<h3>📌 Step 1 — Select Standard</h3>
<p>Choose the classification standard at the top:</p>
<table>
<tr><th>Option</th><th>Description</th><th>Codes</th></tr>
<tr><td><b>🆕 TT 16/2023</b></td><td>New standard (current)</td><td>55 LDLR codes</td></tr>
<tr><td><b>📗 TT 33/2018</b></td><td>Old standard (legacy)</td><td>98 codes</td></tr>
</table>

<h3>📌 Step 2 — Select Layer</h3>
<p>In the <b>Layer</b> box, select a <b>polygon</b> vector layer from your project.
The geometry type is shown below (e.g. "Polygon — 1234 features").
Only polygon layers are supported for thematic maps.</p>

<h3>📌 Step 3 — Choose Style</h3>
<p>In the <b>Style</b> box, select a color scheme:</p>
<table>
<tr><th>Style</th><th>Classify By</th><th>Description</th></tr>
<tr><td><b>LDLR (text code) — VN</b></td><td>LDLR_VT</td><td>Text code, Vietnamese labels</td></tr>
<tr><td><b>LDLR (text code) — EN</b></td><td>LDLR_VT</td><td>Text code, English labels</td></tr>
<tr><td><b>Code (numeric) — VN</b></td><td>forest_typ</td><td>Numeric code (1–55), Vietnamese labels</td></tr>
<tr><td><b>Code (numeric) — EN</b></td><td>Code</td><td>Numeric code (1–55), English labels</td></tr>
</table>
<p>The plugin <b>auto-matches</b> the classify field. If not found, select it
manually in the <b>Field</b> dropdown.</p>

<h3>📌 Step 4 — Border / Outline</h3>
<p>Configure polygon border/outline appearance:</p>
<table>
<tr><th>Parameter</th><th>Options</th><th>Default</th></tr>
<tr><td><b>✏️ Border on/off</b></td><td>Checkbox to enable</td><td>✅ On</td></tr>
<tr><td><b>Line style</b></td><td>Solid, Dash, Dot, Dash-Dot</td><td>··· Dot</td></tr>
<tr><td><b>Line width</b></td><td>0.0 – 5.0 mm</td><td>0.1 mm</td></tr>
<tr><td><b>Line color</b></td><td>Black, Red, White, Brown, Blue, Green, Gray</td><td>⬛ Black</td></tr>
</table>
<div class='tip'>💡 Use <b>Dot</b> style with <b>0.1 mm</b> for subtle boundaries.
Use <b>Solid</b> with <b>0.5 mm Red</b> for emphasis.</div>

<h3>📌 Step 5 — Plot Labels</h3>
<p>The integrated label panel lets you add text labels to each polygon:</p>

<h4>5a. Label Fields</h4>
<p>Select which attribute fields to display as labels. You can combine
multiple fields (e.g. plot number + area + land type).
Each field row has:</p>
<ul>
<li><b>Checkbox:</b> Enable/disable this field in the label</li>
<li><b>Field dropdown:</b> Choose an attribute from the layer</li>
<li><b>Prefix/Suffix:</b> Add text before/after the value (e.g. "S=" prefix, "ha" suffix)</li>
</ul>

<h4>5b. Font Settings</h4>
<table>
<tr><th>Parameter</th><th>Description</th><th>Default</th></tr>
<tr><td><b>Font family</b></td><td>Select any installed font</td><td>System default</td></tr>
<tr><td><b>Font size</b></td><td>Text point size</td><td>12 pt</td></tr>
<tr><td><b>Bold</b></td><td>Bold weight toggle</td><td>Off</td></tr>
<tr><td><b>Font color</b></td><td>Click color button to pick</td><td>Black</td></tr>
<tr><td><b>Line height</b></td><td>Spacing between multi-line labels (%)</td><td>100%</td></tr>
</table>

<h4>5c. Scale Visibility</h4>
<p>Control when labels appear based on zoom level:</p>
<ul>
<li><b>Zoom-in limit:</b> Labels hide below this scale (too close)</li>
<li><b>Zoom-out limit:</b> Labels hide above this scale (too far)</li>
</ul>

<h4>5d. Buffer (Halo)</h4>
<p>Add a text halo for readability over colored polygons:</p>
<ul>
<li><b>Enable buffer:</b> Checkbox toggle</li>
<li><b>Size:</b> Buffer thickness (mm)</li>
<li><b>Color:</b> Buffer color (usually white)</li>
</ul>

<h4>5e. Background</h4>
<p>Add a solid background rectangle behind the label text:</p>
<ul>
<li><b>Enable background:</b> Checkbox toggle</li>
<li><b>Color:</b> Background fill color</li>
<li><b>Corner radius:</b> Rounded corners (mm)</li>
</ul>

<h3>📌 Step 6 — Apply</h3>
<ol>
<li>Click <b>🎨 Apply</b> to apply thematic colors + labels to the layer.</li>
<li>The layer symbology updates immediately in the map canvas.</li>
<li>Review the result and adjust settings if needed.</li>
</ol>

<h3>📋 Reference Tabs</h3>
<table>
<tr><th>Tab</th><th>Content</th></tr>
<tr><td><b>📋 LDLR_Ref</b></td><td>Full LDLR code reference table with colors</td></tr>
<tr><td><b>📗 Appendix 1</b></td><td>Official appendix from TT16 or TT33</td></tr>
<tr><td><b>📗 Appendix E</b></td><td>TCVN 11565:2016 classification reference</td></tr>
</table>

<div class='warn'>⚠️ Make sure your layer has the correct attribute field
(LDLR_VT, forest_typ, or Code) matching the selected style.
If no match is found, the plugin will warn you.</div>
"""),
        "vi": _h("""
<h2>🎨 Bản đồ chuyên đề — Thư viện kiểu TT 16/2023</h2>
<h3>Tổng quan</h3>
<p>Áp dụng bảng màu phân loại đất/rừng chính thức theo
Thông tư 16/2023 (55 mã LĐLR) hoặc TT 33/2018 (98 mã).
Bao gồm tùy chỉnh viền và nhãn lô tích hợp.</p>

<h3>📌 Bước 1 — Chọn tiêu chuẩn</h3>
<p>Chọn tiêu chuẩn phân loại ở đầu giao diện:</p>
<table>
<tr><th>Tùy chọn</th><th>Mô tả</th><th>Mã</th></tr>
<tr><td><b>🆕 TT 16/2023</b></td><td>Tiêu chuẩn mới (hiện hành)</td><td>55 mã LĐLR</td></tr>
<tr><td><b>📗 TT 33/2018</b></td><td>Tiêu chuẩn cũ</td><td>98 mã</td></tr>
</table>

<h3>📌 Bước 2 — Chọn lớp dữ liệu</h3>
<p>Trong ô <b>Layer</b>, chọn lớp vector <b>polygon</b> từ dự án.
Loại hình học hiển thị bên dưới (VD: "Polygon — 1234 features").
Chỉ hỗ trợ lớp dạng polygon cho bản đồ chuyên đề.</p>

<h3>📌 Bước 3 — Chọn kiểu màu</h3>
<p>Trong ô <b>Style</b>, chọn bảng màu:</p>
<table>
<tr><th>Kiểu</th><th>Phân loại theo</th><th>Mô tả</th></tr>
<tr><td><b>LDLR (mã chữ) — VN</b></td><td>LDLR_VT</td><td>Mã chữ, nhãn tiếng Việt</td></tr>
<tr><td><b>LDLR (mã chữ) — EN</b></td><td>LDLR_VT</td><td>Mã chữ, nhãn tiếng Anh</td></tr>
<tr><td><b>Code (mã số) — VN</b></td><td>forest_typ</td><td>Mã số (1–55), nhãn tiếng Việt</td></tr>
<tr><td><b>Code (mã số) — EN</b></td><td>Code</td><td>Mã số (1–55), nhãn tiếng Anh</td></tr>
</table>
<p>Plugin <b>tự động khớp</b> trường phân loại. Nếu không tìm thấy, chọn thủ công
trong dropdown <b>Field</b>.</p>

<h3>📌 Bước 4 — Viền lô / Border</h3>
<p>Cấu hình viền đường bao polygon:</p>
<table>
<tr><th>Thông số</th><th>Tùy chọn</th><th>Mặc định</th></tr>
<tr><td><b>✏️ Viền bật/tắt</b></td><td>Ô tích để bật</td><td>✅ Bật</td></tr>
<tr><td><b>Kiểu đường</b></td><td>Liền, Đứt, Chấm, Gạch-Chấm</td><td>··· Chấm</td></tr>
<tr><td><b>Độ rộng</b></td><td>0.0 – 5.0 mm</td><td>0.1 mm</td></tr>
<tr><td><b>Màu đường</b></td><td>Đen, Đỏ, Trắng, Nâu, Xanh dương, Xanh lá, Xám</td><td>⬛ Đen</td></tr>
</table>
<div class='tip'>💡 Dùng <b>Chấm</b> với <b>0.1 mm</b> cho ranh giới tinh tế.
Dùng <b>Liền</b> với <b>0.5 mm Đỏ</b> để nhấn mạnh.</div>

<h3>📌 Bước 5 — Nhãn lô / Plot Labels</h3>
<p>Bảng nhãn tích hợp cho phép thêm nhãn văn bản vào từng polygon:</p>

<h4>5a. Trường nhãn</h4>
<p>Chọn trường thuộc tính hiển thị làm nhãn. Có thể kết hợp
nhiều trường (VD: số lô + diện tích + loại đất).
Mỗi dòng trường có:</p>
<ul>
<li><b>Ô tích:</b> Bật/tắt trường này trong nhãn</li>
<li><b>Dropdown trường:</b> Chọn thuộc tính từ lớp</li>
<li><b>Tiền tố/Hậu tố:</b> Thêm ký tự trước/sau giá trị (VD: "S=" tiền tố, "ha" hậu tố)</li>
</ul>

<h4>5b. Cài đặt phông chữ</h4>
<table>
<tr><th>Thông số</th><th>Ý nghĩa</th><th>Mặc định</th></tr>
<tr><td><b>Phông chữ</b></td><td>Chọn font đã cài đặt</td><td>Font hệ thống</td></tr>
<tr><td><b>Cỡ chữ</b></td><td>Kích thước điểm (pt)</td><td>12 pt</td></tr>
<tr><td><b>In đậm</b></td><td>Bật/tắt chữ đậm</td><td>Tắt</td></tr>
<tr><td><b>Màu chữ</b></td><td>Nhấn nút màu để chọn</td><td>Đen</td></tr>
<tr><td><b>Giãn dòng</b></td><td>Khoảng cách giữa các dòng nhãn (%)</td><td>100%</td></tr>
</table>

<h4>5c. Phạm vi hiển thị theo tỷ lệ</h4>
<p>Kiểm soát nhãn xuất hiện theo mức zoom:</p>
<ul>
<li><b>Giới hạn phóng to:</b> Nhãn ẩn khi zoom quá gần</li>
<li><b>Giới hạn thu nhỏ:</b> Nhãn ẩn khi zoom quá xa</li>
</ul>

<h4>5d. Viền chữ / Buffer (Halo)</h4>
<p>Thêm quầng sáng xung quanh chữ để dễ đọc trên nền màu:</p>
<ul>
<li><b>Bật buffer:</b> Ô tích bật/tắt</li>
<li><b>Kích thước:</b> Độ dày viền (mm)</li>
<li><b>Màu:</b> Màu viền (thường là trắng)</li>
</ul>

<h4>5e. Nền nhãn / Background</h4>
<p>Thêm hình chữ nhật nền phía sau nhãn:</p>
<ul>
<li><b>Bật nền:</b> Ô tích bật/tắt</li>
<li><b>Màu:</b> Màu nền</li>
<li><b>Bo góc:</b> Độ bo tròn góc (mm)</li>
</ul>

<h3>📌 Bước 6 — Áp dụng</h3>
<ol>
<li>Nhấn <b>🎨 Áp dụng</b> để tô màu chuyên đề + nhãn lên lớp.</li>
<li>Symbology cập nhật ngay lập tức trên canvas.</li>
<li>Xem kết quả và điều chỉnh nếu cần.</li>
</ol>

<h3>📋 Các tab tham khảo</h3>
<table>
<tr><th>Tab</th><th>Nội dung</th></tr>
<tr><td><b>📋 LDLR_Ref</b></td><td>Bảng mã LĐLR đầy đủ kèm màu sắc</td></tr>
<tr><td><b>📗 Phụ lục 1</b></td><td>Phụ lục chính thức từ TT16 hoặc TT33</td></tr>
<tr><td><b>📗 Phụ lục E</b></td><td>Phân loại TCVN 11565:2016</td></tr>
</table>

<div class='warn'>⚠️ Đảm bảo lớp dữ liệu có trường thuộc tính đúng
(LDLR_VT, forest_typ, hoặc Code) khớp với kiểu đã chọn.
Nếu không khớp, plugin sẽ cảnh báo.</div>
"""),
    },

    # ================================================================
    # LAYER EDITOR
    # ================================================================
    "layer_editor": {
        "en": _h("""
<h2>🗂️ Layer Editor</h2>

<h3>1. Overview</h3>
<p>The Layer Editor is a centralized tool for managing all vector layers
in your current QGIS project. It provides a <b>3-column layout</b>
organized by geometry type: <b>Point</b>, <b>Line</b>, and <b>Polygon</b>,
allowing you to rename, restyle, and organize layers efficiently.</p>

<h3>2. Getting Started</h3>
<ol>
<li>Open the Layer Editor from the <b>LVT4U menu &rarr; Layer Editor</b>
or click the <b>first icon</b> on the LVT4U toolbar.</li>
<li>All vector layers in your project are automatically scanned and
sorted into the three geometry columns.</li>
<li>Use the <b>🌐</b> button (top-right) to switch between
<b>English</b> and <b>Vietnamese</b> interface.</li>
</ol>

<h3>3. The 3-Column Interface</h3>
<table>
<tr><th>Column</th><th>Content</th><th>Description</th></tr>
<tr><td><b>📍 Point</b></td><td>Point layers</td>
<td>Stations, fire points, settlements, GPS waypoints</td></tr>
<tr><td><b>📏 Line</b></td><td>Line layers</td>
<td>Roads, rivers, boundaries, contours</td></tr>
<tr><td><b>🔷 Polygon</b></td><td>Polygon layers</td>
<td>Forest plots, land use, administrative zones</td></tr>
</table>
<p>Each column is a table with 4 fields per layer:</p>
<table>
<tr><th>Field</th><th>Description</th></tr>
<tr><td><b>☑</b></td><td>Check/uncheck to include in Apply</td></tr>
<tr><td><b>Source Layer</b></td><td>Original layer name (read-only)</td></tr>
<tr><td><b>Display Name</b></td><td>Editable &mdash; auto-suggested based on
Vietnamese forestry naming conventions (30+ keyword patterns)</td></tr>
<tr><td><b>Style</b></td><td>Dropdown with visual icon preview from QGIS
Style Manager + bundled LVT QML presets</td></tr>
</table>

<h3>4. Choosing Styles</h3>
<p>The Style dropdown contains <b>two sections</b>:</p>
<ol>
<li><b>QGIS Style Manager symbols</b> &mdash; filtered by geometry type.
Each entry shows a <b>24&times;24 icon preview</b> of the actual symbol.</li>
<li><b>📄 QML Presets (LVT)</b> &mdash; bundled forestry styles:
land use classification (LDLR), administrative boundaries,
forest compartments, road networks, cadastral map styles.
QML presets apply <b>full renderer + labeling</b> rules.</li>
</ol>

<h3>5. Column Filter (Enable/Disable)</h3>
<p>Above the 3 columns, there are <b>3 checkboxes</b> to enable or disable
each geometry type. <span style='color:red'>A red warning</span> explains this feature.</p>
<ul>
<li><b>Checked</b> (default) &mdash; the column is active, changes will be applied</li>
<li><b>Unchecked</b> &mdash; the column is greyed out and <b>completely skipped</b>
when you click Apply All</li>
</ul>
<p>This is useful when you only want to restyle Point layers without
affecting your existing Line or Polygon configurations.</p>

<h3>6. Action Buttons</h3>
<table>
<tr><th>Button</th><th>Action</th></tr>
<tr><td><b>🔄 Refresh</b></td><td>Re-scan project layers</td></tr>
<tr><td><b>✅ Apply All</b></td><td>Apply display names + styles to all checked layers</td></tr>
<tr><td><b>📋 Group in Panel</b></td><td>Create geometry groups in the QGIS Layer Panel</td></tr>
<tr><td><b>💾 Save Preset</b></td><td>Export configuration as JSON file</td></tr>
<tr><td><b>📂 Load Preset</b></td><td>Import a previously saved JSON preset</td></tr>
</table>

<h3>7. Group Mode</h3>
<ul>
<li><b>Auto Group</b> &mdash; Layers classified by geometry type (default)</li>
<li><b>Manual Group</b> &mdash; You control grouping</li>
</ul>

<h3>8. Save / Load Presets</h3>
<p>Presets store your layer configuration as a <b>JSON file</b>
(display names, selected styles, checked state). Useful for
projects with similar layer structures.</p>

<h3>9. XML Style Library Auto-Install</h3>
<p>On first load, LVT4U imports bundled style libraries:</p>
<ul>
<li><b>TCVN 11565-2016</b> &mdash; Vietnamese forestry map symbology</li>
<li><b>LVT Style Library</b> &mdash; Cadastral + forestry styles</li>
</ul>

<div class='tip'>💡 <b>Workflow:</b> Open &rarr; Rename &rarr; Select Styles &rarr;
Apply All &rarr; Group in Panel &rarr; Save Preset for reuse.</div>
"""),
        "vi": _h("""
<h2>🗂️ Bi&ecirc;n tập Layer</h2>

<h3>1. Tổng quan</h3>
<p>Bi&ecirc;n tập Layer l&agrave; c&ocirc;ng cụ quản l&yacute; tập trung tất cả lớp dữ liệu vector
trong dự &aacute;n QGIS hiện tại. Giao diện bố tr&iacute; <b>3 cột</b>
theo loại h&igrave;nh học: <b>Điểm</b>, <b>Đường</b>, v&agrave; <b>V&ugrave;ng</b>.</p>

<h3>2. Bắt đầu sử dụng</h3>
<ol>
<li>Mở Bi&ecirc;n tập Layer từ <b>menu LVT4U &rarr; Bi&ecirc;n tập Layer</b>
hoặc nhấn <b>biểu tượng đầu ti&ecirc;n</b> tr&ecirc;n thanh c&ocirc;ng cụ LVT4U.</li>
<li>Tất cả layer vector trong dự &aacute;n được tự động qu&eacute;t v&agrave;
ph&acirc;n loại v&agrave;o 3 cột theo h&igrave;nh học.</li>
<li>D&ugrave;ng n&uacute;t <b>🌐</b> (g&oacute;c tr&ecirc;n phải) để chuyển đổi giữa
giao diện <b>Tiếng Anh</b> v&agrave; <b>Tiếng Việt</b>.</li>
</ol>

<h3>3. Giao diện 3 cột</h3>
<table>
<tr><th>Cột</th><th>Nội dung</th><th>M&ocirc; tả</th></tr>
<tr><td><b>📍 Điểm</b></td><td>Lớp dạng điểm</td>
<td>Trạm, điểm ch&aacute;y, khu d&acirc;n cư, tọa độ GPS</td></tr>
<tr><td><b>📏 Đường</b></td><td>Lớp dạng đường</td>
<td>Đường giao th&ocirc;ng, s&ocirc;ng suối, ranh giới, đường đồng mức</td></tr>
<tr><td><b>🔷 V&ugrave;ng</b></td><td>Lớp dạng v&ugrave;ng</td>
<td>L&ocirc; rừng, hiện trạng sử dụng đất, ranh giới h&agrave;nh ch&iacute;nh</td></tr>
</table>
<p>Mỗi cột c&oacute; bảng với 4 trường cho mỗi layer:</p>
<table>
<tr><th>Trường</th><th>M&ocirc; tả</th></tr>
<tr><td><b>☑</b></td><td>Chọn/bỏ chọn layer để &aacute;p dụng thao t&aacute;c</td></tr>
<tr><td><b>Layer gốc</b></td><td>T&ecirc;n layer gốc (chỉ đọc)</td></tr>
<tr><td><b>T&ecirc;n hiển thị</b></td><td>C&oacute; thể sửa &mdash; tự động gợi &yacute; dựa tr&ecirc;n
quy ước đặt t&ecirc;n l&acirc;m nghiệp Việt Nam (30+ từ kh&oacute;a)</td></tr>
<tr><td><b>Style</b></td><td>Danh s&aacute;ch thả xuống c&oacute; xem trước biểu tượng
từ QGIS Style Manager + bộ QML preset LVT đi k&egrave;m</td></tr>
</table>

<h3>4. Chọn Style (Định dạng hiển thị)</h3>
<p>Danh s&aacute;ch Style chứa <b>hai phần</b>:</p>
<ol>
<li><b>Biểu tượng QGIS Style Manager</b> &mdash; lọc theo loại h&igrave;nh học.
Mỗi mục hiển thị <b>biểu tượng xem trước 24&times;24</b> với m&agrave;u sắc,
hoa văn, h&igrave;nh dạng thực tế.</li>
<li><b>📄 QML Preset (LVT)</b> &mdash; bộ style l&acirc;m nghiệp đi k&egrave;m:
ph&acirc;n loại loại đất loại rừng (LDLR), ranh giới h&agrave;nh ch&iacute;nh,
tiểu khu, khoảnh rừng, mạng lưới đường, style bản đồ địa ch&iacute;nh.
QML preset &aacute;p dụng <b>to&agrave;n bộ renderer + quy tắc nh&atilde;n</b>.</li>
</ol>

<h3>5. Bộ lọc cột (Bật/Tắt)</h3>
<p>Ph&iacute;a tr&ecirc;n 3 cột c&oacute; <b>3 checkbox</b> để bật hoặc tắt
từng loại h&igrave;nh học. <span style='color:red'>C&acirc;u cảnh b&aacute;o m&agrave;u đỏ</span>
giải th&iacute;ch t&iacute;nh năng n&agrave;y.</p>
<ul>
<li><b>Được chọn</b> (mặc định) &mdash; cột hoạt động, thay đổi sẽ được &aacute;p dụng</li>
<li><b>Bỏ chọn</b> &mdash; cột bị x&aacute;m v&agrave; <b>bị bỏ qua ho&agrave;n to&agrave;n</b>
khi nhấn &Aacute;p dụng tất cả</li>
</ul>
<p>Hữu &iacute;ch khi bạn chỉ muốn định dạng layer Điểm m&agrave; kh&ocirc;ng
ảnh hưởng đến c&aacute;c cấu h&igrave;nh Đường hoặc V&ugrave;ng hiện c&oacute;.</p>

<h3>6. C&aacute;c n&uacute;t thao t&aacute;c</h3>
<table>
<tr><th>N&uacute;t</th><th>Chức năng</th></tr>
<tr><td><b>🔄 L&agrave;m mới</b></td><td>Qu&eacute;t lại layer trong dự &aacute;n</td></tr>
<tr><td><b>✅ &Aacute;p dụng tất cả</b></td><td>&Aacute;p dụng t&ecirc;n hiển thị + style
cho tất cả layer đ&atilde; chọn c&ugrave;ng l&uacute;c</td></tr>
<tr><td><b>📋 Nh&oacute;m trong Panel</b></td><td>Tạo nh&oacute;m theo h&igrave;nh học
trong Panel Layer QGIS v&agrave; di chuyển layer v&agrave;o</td></tr>
<tr><td><b>💾 Lưu cấu h&igrave;nh</b></td><td>Xuất cấu h&igrave;nh hiện tại ra file JSON</td></tr>
<tr><td><b>📂 Tải cấu h&igrave;nh</b></td><td>Nhập file JSON preset đ&atilde; lưu</td></tr>
</table>

<h3>7. Chế độ nh&oacute;m</h3>
<ul>
<li><b>Nh&oacute;m tự động</b> &mdash; Layer tự động ph&acirc;n loại theo loại h&igrave;nh học (mặc định)</li>
<li><b>Nh&oacute;m thủ c&ocirc;ng</b> &mdash; Bạn tự quyết định nh&oacute;m</li>
</ul>

<h3>8. Lưu / Tải cấu h&igrave;nh (Preset)</h3>
<p>Cấu h&igrave;nh được lưu dưới dạng <b>file JSON</b>: t&ecirc;n hiển thị,
style đ&atilde; chọn, trạng th&aacute;i chọn/bỏ chọn. Rất hữu &iacute;ch khi l&agrave;m việc
với nhiều dự &aacute;n c&oacute; quy ước đặt t&ecirc;n tương tự.</p>

<h3>9. Tự động c&agrave;i đặt thư viện Style XML</h3>
<p>Khi LVT4U khởi chạy lần đầu, plugin tự động nhập:</p>
<ul>
<li><b>TCVN 11565-2016</b> &mdash; Ti&ecirc;u chuẩn k&yacute; hiệu bản đồ l&acirc;m nghiệp VN</li>
<li><b>Thư viện Style LVT</b> &mdash; Style địa ch&iacute;nh + l&acirc;m nghiệp</li>
</ul>

<div class='tip'>💡 <b>Quy tr&igrave;nh gợi &yacute;:</b>
<br>1. Mở Bi&ecirc;n tập Layer &rarr; 2. Đổi t&ecirc;n &rarr; 3. Chọn style &rarr;
4. &Aacute;p dụng tất cả &rarr; 5. Nh&oacute;m trong Panel &rarr; 6. Lưu cấu h&igrave;nh.</div>
"""),
    },

    # ================================================================
    # POLYFIX — Topology Check & Fix
    # ================================================================
    "polyfix": {
        "en": _h("""
<h2>TopoFix &mdash; Topology Check &amp; Fix</h2>
<p><i>Loc Vu Trung &mdash; compiled from passion!</i></p>

<h3>I. Quick Start (3 Steps)</h3>
<ol>
<li><b>Select layer</b> &rarr; choose a polygon layer from dropdown</li>
<li><b>Click &#128269; Scan All Errors</b> &rarr; automatically checks all 11 error types</li>
<li><b>Review results</b> &rarr; only error types with count &gt; 0 are shown.
    Click <b>Show</b> to highlight on map, tick <b>Fix</b> checkboxes,
    then click <b>&#128295; Fix Errors</b></li>
</ol>
<p>A virtual layer (<code>*_TopoFixed</code>) is created for review.
Click <b>&#128260; Re-Scan</b> to verify. When satisfied,
right-click layer &gt; Export to save permanently.</p>

<h3>II. Scientific Foundation</h3>
<h4>OGC Simple Feature (ISO 19125)</h4>
<table><tr><th>Relation</th><th>DE-9IM</th><th>Used by</th></tr>
<tr><td>Equals</td><td>T*F**FFF*</td><td>#4 Duplicates</td></tr>
<tr><td>Overlaps</td><td>T*T***T**</td><td>#5 Overlaps, #6 MNO</td></tr>
<tr><td>Touches</td><td>FT*******</td><td>#7 Gaps</td></tr></table>

<h4>GEOS Engine via QGIS</h4>
<table><tr><th>GEOS</th><th>QGIS API</th><th>Algorithm</th></tr>
<tr><td>GEOSisValid</td><td>isGeosValid()</td><td>#2 Invalid</td></tr>
<tr><td>GEOSOverlaps</td><td>overlaps()</td><td>#5,#6</td></tr>
<tr><td>GEOSIntersection</td><td>intersection()</td><td>#5,#6</td></tr>
<tr><td>GEOSDifference</td><td>difference()</td><td>#5,#6 fix</td></tr>
<tr><td>GEOSUnaryUnion</td><td>unaryUnion()</td><td>#7 Gaps</td></tr></table>

<h4>Custom Algorithms</h4>
<p><b>Point-on-Segment (#10):</b> t = dot(AP,AB)/dot(AB,AB);
P on AB when 0 &lt; t &lt; 1 AND dist &lt; tolerance</p>
<p><b>Douglas-Peucker (#8):</b> Iterative vertex reduction preserving shape</p>
<p><b>R-Tree Index:</b> O(n&sup2;) &rarr; O(n&middot;log n) via QgsSpatialIndex</p>
<p><b>Sliver Compactness (#9):</b> ratio = Perimeter / &radic;Area &gt; threshold</p>

<h3>III. 11 Algorithms Detail</h3>
<table><tr><th>#</th><th>Name</th><th>Detection</th><th>Fix</th><th>Complexity</th></tr>
<tr><td>1</td><td>Multipart</td><td>numGeometries() &gt; 1</td>
    <td>multiparttosingleparts</td><td>O(n)</td></tr>
<tr><td>2</td><td>Invalid Geometry</td><td>isGeosValid() = False</td>
    <td>fixgeometries &times;2 (structure+linework)</td><td>O(n)</td></tr>
<tr><td>3</td><td>Unclosed Rings</td><td>first vertex &ne; last vertex</td>
    <td>fixgeometries</td><td>O(n)</td></tr>
<tr><td>4</td><td>Duplicates</td><td>WKT hash comparison</td>
    <td>deleteduplicategeometries</td><td>O(n)</td></tr>
<tr><td>5</td><td>Overlaps</td><td>R-Tree + intersection area</td>
    <td>g1.difference(intersection)</td><td>O(n&middot;log n)</td></tr>
<tr><td>6</td><td>Must Not Overlap</td><td>overlaps() + area &gt; threshold</td>
    <td>Cut from smaller polygon</td><td>O(n&middot;log n)</td></tr>
<tr><td>7</td><td>Gaps</td><td>Dissolve &rarr; interior rings</td>
    <td>Merge into longest-shared-edge neighbor</td><td>O(n&middot;log n)</td></tr>
<tr><td>8</td><td>Redundant Vertices</td><td>vertexCount &gt; max_verts</td>
    <td>Douglas-Peucker simplification</td><td>O(n&middot;k)</td></tr>
<tr><td>9</td><td>Sliver Polygons</td><td>P/&radic;A &gt; ratio threshold</td>
    <td>Remove (filter out)</td><td>O(n)</td></tr>
<tr><td>10</td><td>Missing Nodes</td><td>Point-on-segment projection</td>
    <td>Insert node + rebuild geometry</td><td>O(n&sup2;)</td></tr>
<tr><td>11</td><td>Tiny Polygons</td><td>area &lt; min_area</td>
    <td>Iterative merge (max 20 rounds)</td><td>O(n&middot;k)</td></tr></table>

<h3>IV. Fix Pipeline</h3>
<p><b>Output of step N = Input of step N+1</b></p>
<p>1&rarr;2&rarr;3&rarr;4&rarr;5&rarr;6&rarr;7&rarr;8&rarr;9&rarr;10&rarr;11</p>
<p>Order matters: structural fixes first, then geometric, then topological.</p>

<h3>V. Parameters</h3>
<p>Only parameters relevant to detected errors are shown.</p>
<table><tr><th>Parameter</th><th>Default</th><th>Unit</th><th>Effect</th></tr>
<tr><td>Gap tolerance</td><td>0.001</td><td>ha</td><td>Smaller gaps ignored</td></tr>
<tr><td>Sliver max area</td><td>1.0</td><td>ha</td><td>Larger = not sliver</td></tr>
<tr><td>Sliver ratio</td><td>20.0</td><td>-</td><td>Lower = stricter</td></tr>
<tr><td>MNO min area</td><td>0.001</td><td>m&sup2;</td><td>Smaller intersections ignored</td></tr>
<tr><td>Missing node tol</td><td>0.001</td><td>map units</td><td>VN-2000: 0.001m, WGS84: 1e-8</td></tr>
<tr><td>Tiny polygon min</td><td>user</td><td>ha</td><td>Polygons below merged</td></tr>
<tr><td>Max vertices</td><td>500</td><td>count</td><td>Above = redundant</td></tr></table>

<h3>VI. Interface Guide</h3>
<table><tr><th>State</th><th>What you see</th><th>Action</th></tr>
<tr><td>Initial</td><td>Layer selector + &#128269; Scan</td><td>Select layer, click Scan</td></tr>
<tr><td>Scanning</td><td>Progress bar</td><td>Wait (or Stop)</td></tr>
<tr><td>Results</td><td>Only errors with count&gt;0</td><td>Show, tick Fix, adjust params</td></tr>
<tr><td>Fixing</td><td>Progress bar</td><td>Wait for virtual layer</td></tr></table>

<div class='warn'>&#9888; Always backup before fixing. Some errors may cascade
&mdash; re-scan after fix to verify.</div>
"""),
        "vi": _h("""
<h2>TopoFix &mdash; Ki&#7875;m tra &amp; S&#7917;a Topology</h2>
<p><i>L&#7897;c V&#361; Trung t&#7893;ng h&#7907;p v&igrave; &#273;am m&ecirc;!</i></p>

<h3>I. B&#7855;t &#273;&#7847;u nhanh (3 b&#432;&#7899;c)</h3>
<ol>
<li><b>Ch&#7885;n layer</b> &rarr; ch&#7885;n l&#7899;p polygon t&#7915; dropdown</li>
<li><b>Click &#128269; Scan All Errors</b> &rarr; t&#7921; &#273;&#7897;ng qu&eacute;t 11 lo&#7841;i l&#7895;i</li>
<li><b>Xem k&#7871;t qu&#7843;</b> &rarr; ch&#7881; hi&#7879;n l&#7895;i c&oacute; s&#7889; l&#432;&#7907;ng &gt; 0.
    Click <b>Show</b>, tick <b>Fix</b>, click <b>&#128295; Fix Errors</b></li>
</ol>
<p>Layer &#7843;o (<code>*_TopoFixed</code>) &#273;&#432;&#7907;c t&#7841;o.
Click <b>&#128260; Re-Scan</b> &#273;&#7875; ki&#7875;m tra. Khi h&agrave;i l&ograve;ng,
chu&#7897;t ph&#7843;i &gt; Export &#273;&#7875; l&#432;u.</p>

<h3>II. N&#7873;n t&#7843;ng khoa h&#7885;c</h3>
<h4>OGC Simple Feature (ISO 19125)</h4>
<table><tr><th>Quan h&#7879;</th><th>DE-9IM</th><th>D&ugrave;ng cho</th></tr>
<tr><td>Equals</td><td>T*F**FFF*</td><td>#4 Tr&ugrave;ng l&#7863;p</td></tr>
<tr><td>Overlaps</td><td>T*T***T**</td><td>#5 Ch&#7891;ng, #6 MNO</td></tr>
<tr><td>Touches</td><td>FT*******</td><td>#7 Kho&#7843;ng h&#7903;</td></tr></table>

<h4>GEOS qua QGIS</h4>
<table><tr><th>GEOS</th><th>QGIS API</th><th>Thu&#7853;t to&aacute;n</th></tr>
<tr><td>GEOSisValid</td><td>isGeosValid()</td><td>#2</td></tr>
<tr><td>GEOSOverlaps</td><td>overlaps()</td><td>#5,#6</td></tr>
<tr><td>GEOSIntersection</td><td>intersection()</td><td>#5,#6</td></tr>
<tr><td>GEOSDifference</td><td>difference()</td><td>#5,#6 s&#7917;a</td></tr>
<tr><td>GEOSUnaryUnion</td><td>unaryUnion()</td><td>#7</td></tr></table>

<h4>Thu&#7853;t to&aacute;n ri&ecirc;ng</h4>
<p><b>Point-on-Segment (#10):</b> t = dot(AP,AB)/dot(AB,AB);
P thu&#7897;c AB khi 0 &lt; t &lt; 1 v&agrave; kho&#7843;ng c&aacute;ch &lt; dung sai</p>
<p><b>Douglas-Peucker (#8):</b> Gi&#7843;m &#273;&#7881;nh b&#7843;o to&agrave;n h&igrave;nh d&#7841;ng</p>
<p><b>R-Tree:</b> O(n&sup2;) &rarr; O(n&middot;log n) qua QgsSpatialIndex</p>
<p><b>Sliver (#9):</b> t&#7927; l&#7879; = Chu vi / &radic;Di&#7879;n t&iacute;ch &gt; ng&#432;&#7905;ng</p>

<h3>III. 11 Thu&#7853;t to&aacute;n chi ti&#7871;t</h3>
<table><tr><th>#</th><th>Lo&#7841;i</th><th>Ph&aacute;t hi&#7879;n</th><th>S&#7917;a</th><th>&#272;&#7897; ph&#7913;c t&#7841;p</th></tr>
<tr><td>1</td><td>&#272;a ph&#7847;n</td><td>numGeometries() &gt; 1</td>
    <td>T&aacute;ch multipart</td><td>O(n)</td></tr>
<tr><td>2</td><td>Kh&ocirc;ng h&#7907;p l&#7879;</td><td>isGeosValid()=False</td>
    <td>fixgeometries &times;2</td><td>O(n)</td></tr>
<tr><td>3</td><td>V&ograve;ng kh&ocirc;ng kh&eacute;p</td><td>&#273;&#7881;nh &#273;&#7847;u &ne; cu&#7889;i</td>
    <td>fixgeometries</td><td>O(n)</td></tr>
<tr><td>4</td><td>Tr&ugrave;ng l&#7863;p</td><td>So WKT hash</td>
    <td>X&oacute;a b&#7843;n tr&ugrave;ng</td><td>O(n)</td></tr>
<tr><td>5</td><td>Ch&#7891;ng &#273;&egrave;</td><td>R-Tree + DT giao</td>
    <td>difference(intersection)</td><td>O(n&middot;log n)</td></tr>
<tr><td>6</td><td>C&#7855;t th&ocirc;ng minh</td><td>overlaps() + DT &gt; ng&#432;&#7905;ng</td>
    <td>C&#7855;t t&#7915; polygon nh&#7887; h&#417;n</td><td>O(n&middot;log n)</td></tr>
<tr><td>7</td><td>Kho&#7843;ng h&#7903;</td><td>Dissolve &rarr; interior rings</td>
    <td>G&#7897;p v&agrave;o polygon chung c&#7841;nh d&agrave;i nh&#7845;t</td><td>O(n&middot;log n)</td></tr>
<tr><td>8</td><td>&#272;&#7881;nh d&#432; th&#7915;a</td><td>vertexCount &gt; max</td>
    <td>Douglas-Peucker</td><td>O(n&middot;k)</td></tr>
<tr><td>9</td><td>V&ugrave;ng h&igrave;nh kim</td><td>P/&radic;A &gt; ng&#432;&#7905;ng</td>
    <td>Lo&#7841;i b&#7887;</td><td>O(n)</td></tr>
<tr><td>10</td><td>Thi&#7871;u n&uacute;t</td><td>Chi&#7871;u &#273;i&#7875;m l&ecirc;n c&#7841;nh</td>
    <td>Ch&egrave;n n&uacute;t + rebuild</td><td>O(n&sup2;)</td></tr>
<tr><td>11</td><td>Polygon nh&#7887;</td><td>DT &lt; ng&#432;&#7905;ng</td>
    <td>G&#7897;p l&#7863;p (max 20 v&ograve;ng)</td><td>O(n&middot;k)</td></tr></table>

<h3>IV. Pipeline s&#7917;a l&#7895;i</h3>
<p><b>Output b&#432;&#7899;c N = Input b&#432;&#7899;c N+1</b></p>
<p>1&rarr;2&rarr;3&rarr;4&rarr;5&rarr;6&rarr;7&rarr;8&rarr;9&rarr;10&rarr;11</p>
<p>Th&#7913; t&#7921; quan tr&#7885;ng: s&#7917;a c&#7845;u tr&uacute;c tr&#432;&#7899;c, h&igrave;nh h&#7885;c sau, topology cu&#7889;i.</p>

<h3>V. Tham s&#7889;</h3>
<p>Ch&#7881; hi&#7879;n tham s&#7889; li&ecirc;n quan &#273;&#7871;n l&#7895;i ph&aacute;t hi&#7879;n.</p>
<table><tr><th>Tham s&#7889;</th><th>M&#7863;c &#273;&#7883;nh</th><th>&#272;&#417;n v&#7883;</th><th>T&aacute;c d&#7909;ng</th></tr>
<tr><td>Gap tolerance</td><td>0.001</td><td>ha</td><td>Gap nh&#7887; h&#417;n b&#7883; b&#7887; qua</td></tr>
<tr><td>Sliver max area</td><td>1.0</td><td>ha</td><td>L&#7899;n h&#417;n kh&ocirc;ng ph&#7843;i sliver</td></tr>
<tr><td>Sliver ratio</td><td>20.0</td><td>-</td><td>Nh&#7887; h&#417;n = ch&#7863;t h&#417;n</td></tr>
<tr><td>MNO min area</td><td>0.001</td><td>m&sup2;</td><td>Giao nh&#7887; h&#417;n b&#7883; b&#7887; qua</td></tr>
<tr><td>Missing node tol</td><td>0.001</td><td>map units</td><td>VN-2000: 0.001m, WGS84: 1e-8</td></tr>
<tr><td>Tiny polygon min</td><td>ng&#432;&#7901;i d&ugrave;ng</td><td>ha</td><td>Nh&#7887; h&#417;n s&#7869; g&#7897;p</td></tr>
<tr><td>Max vertices</td><td>500</td><td>count</td><td>Nhi&#7873;u h&#417;n = d&#432; th&#7915;a</td></tr></table>

<h3>VI. Giao di&#7879;n</h3>
<table><tr><th>Tr&#7841;ng th&aacute;i</th><th>Hi&#7875;n th&#7883;</th><th>Thao t&aacute;c</th></tr>
<tr><td>Kh&#7903;i &#273;&#7897;ng</td><td>Ch&#7885;n layer + &#128269; Scan</td><td>Ch&#7885;n layer, click Scan</td></tr>
<tr><td>&#272;ang qu&eacute;t</td><td>Progress bar</td><td>Ch&#7901; (ho&#7863;c Stop)</td></tr>
<tr><td>K&#7871;t qu&#7843;</td><td>Ch&#7881; l&#7895;i c&oacute; count&gt;0</td><td>Show, tick Fix, ch&#7881;nh params</td></tr>
<tr><td>&#272;ang s&#7917;a</td><td>Progress bar</td><td>Ch&#7901; layer &#7843;o</td></tr></table>

<div class='warn'>&#9888; Lu&ocirc;n backup tr&#432;&#7899;c khi s&#7917;a. L&#7895;i c&oacute; th&#7875;
cascade &mdash; Re-Scan sau fix &#273;&#7875; ki&#7875;m tra.</div>
"""),
    },

    # ================================================================
    # FLYCAM PHOTOS
    # ================================================================
    "flycam": {
        "en": _h("""
<h2>📷 Flycam Photos — Geotagged Drone Photo Importer</h2>
<h3>Overview</h3>
<p>Import geotagged drone/camera photos as GIS point layers with full
EXIF and DJI XMP metadata extraction. View, update, and export your
photo collection directly within QGIS.</p>

<h3>📌 Tab 1 — 📥 Import</h3>
<h4>Step 1: Select Photo Folder</h4>
<p>Browse to the folder containing your geotagged JPEG photos.
The tool scans <b>recursively</b> — subfolders are included.</p>

<h4>Step 2: Choose Output File</h4>
<table>
<tr><th>Format</th><th>Driver</th><th>Extension</th><th>Best For</th></tr>
<tr><td><b>GeoPackage</b></td><td>GPKG</td><td>.gpkg</td><td>Modern, recommended</td></tr>
<tr><td><b>Shapefile</b></td><td>ESRI Shapefile</td><td>.shp</td><td>Legacy compatibility</td></tr>
<tr><td><b>GeoJSON</b></td><td>GeoJSON</td><td>.geojson</td><td>Web maps, sharing</td></tr>
<tr><td><b>CSV</b></td><td>CSV</td><td>.csv</td><td>Spreadsheet analysis</td></tr>
<tr><td><b>KML</b></td><td>KML</td><td>.kml</td><td>Google Earth</td></tr>
<tr><td><b>MapInfo TAB</b></td><td>MapInfo File</td><td>.tab</td><td>MapInfo users</td></tr>
</table>

<h4>Step 3: Optional Settings</h4>
<table>
<tr><th>Option</th><th>Description</th></tr>
<tr><td><b>Relative root</b></td><td>Base folder for relative path calculation (useful for portable projects)</td></tr>
<tr><td><b>Web root</b></td><td>URL prefix for KML exports (e.g. http://myserver.com/photos/)</td></tr>
<tr><td><b>Canvas extent filter</b></td><td>Only import photos whose GPS falls within the current map view</td></tr>
</table>

<h4>Step 4: Import</h4>
<ol>
<li>Click <b>🚀 Import Photos</b></li>
<li>Processing runs in the background (QGIS remains responsive)</li>
<li>Layer is automatically added to the map with photo thumbnail tooltips</li>
</ol>

<h4>Extracted Metadata Fields</h4>
<table>
<tr><th>Field</th><th>Type</th><th>Source</th></tr>
<tr><td><b>Name</b></td><td>Text</td><td>File name</td></tr>
<tr><td><b>Date / Time</b></td><td>Text</td><td>EXIF DateTimeOriginal</td></tr>
<tr><td><b>Lon / Lat</b></td><td>Double</td><td>EXIF GPS coordinates (WGS84)</td></tr>
<tr><td><b>Altitude</b></td><td>Double</td><td>EXIF GPS altitude (meters)</td></tr>
<tr><td><b>Azimuth</b></td><td>Double</td><td>DJI XMP FlightYawDegree or EXIF GPSImgDirection</td></tr>
<tr><td><b>Cam_Maker / Cam_Model</b></td><td>Text</td><td>EXIF camera info</td></tr>
<tr><td><b>Path / RelPath</b></td><td>Text</td><td>Absolute and relative file paths</td></tr>
</table>

<div class='tip'>💡 <b>DJI drone support:</b> FlightYawDegree is automatically extracted
from DJI XMP metadata, giving you precise heading/azimuth for each photo.
This is more accurate than EXIF GPSImgDirection.</div>

<h3>📌 Tab 2 — 👁️ View</h3>
<h4>Click-on-Map Viewing</h4>
<ol>
<li>Select the photo layer from the dropdown</li>
<li>Click <b>🖱️ Click Photos on Map</b></li>
<li>Click any photo point in the map canvas</li>
<li>The Photo Viewer window opens with the selected photo</li>
</ol>

<h4>Photo Viewer Features</h4>
<table>
<tr><th>Action</th><th>Button / Key</th><th>Description</th></tr>
<tr><td><b>Navigate</b></td><td>◀ ▶ / ← →</td><td>Previous / Next photo</td></tr>
<tr><td><b>Zoom</b></td><td>Mouse wheel</td><td>Zoom in/out with anchor under mouse</td></tr>
<tr><td><b>Pan</b></td><td>Click & drag</td><td>Drag to move around the image</td></tr>
<tr><td><b>Fit</b></td><td>⊞ / F</td><td>Fit image to window</td></tr>
<tr><td><b>Rotate 90°</b></td><td>↻ / R</td><td>Rotate clockwise</td></tr>
<tr><td><b>Rotate azimuth</b></td><td>🧭</td><td>Rotate based on GPS heading (north-up)</td></tr>
<tr><td><b>Fullscreen</b></td><td>F11</td><td>Toggle fullscreen view</td></tr>
<tr><td><b>Save</b></td><td>💾</td><td>Save current view as JPEG/PNG/BMP</td></tr>
</table>

<h4>Image Filters</h4>
<table>
<tr><th>Filter</th><th>Requires OpenCV</th><th>Description</th></tr>
<tr><td>None</td><td>❌</td><td>Original image (default)</td></tr>
<tr><td>Gray</td><td>❌</td><td>Convert to grayscale</td></tr>
<tr><td>Mirror</td><td>❌</td><td>Horizontal flip</td></tr>
<tr><td>Mono</td><td>❌</td><td>Black & white (1-bit)</td></tr>
<tr><td>Edges</td><td>✅</td><td>Canny edge detection</td></tr>
<tr><td>Red / Green / Blue Band</td><td>✅</td><td>Isolate single color channel</td></tr>
<tr><td>Gaussian Blur</td><td>✅</td><td>Smooth/blur the image</td></tr>
</table>

<div class='tip'>💡 <b>Map tooltip:</b> Hover over any photo point on the map to see
a thumbnail preview — no need to open the viewer for quick identification.</div>

<h3>📌 Tab 3 — 🔄 Update</h3>
<p>Synchronize an existing photo layer with its source folder:</p>
<ul>
<li><b>New photos</b> added to the folder → automatically added as new points</li>
<li><b>Deleted photos</b> removed from the folder → their points are removed</li>
</ul>
<ol>
<li>Select the photo layer to update</li>
<li>Click <b>🔄 Update Layer</b></li>
<li>The source folder is determined from the first photo's <code>Path</code> field</li>
</ol>

<h3>📌 Tab 4 — 📤 Export</h3>
<p>Bulk copy all photos referenced in a layer to a single folder:</p>
<ol>
<li>Select the photo layer</li>
<li>Browse to the destination folder</li>
<li>Click <b>📤 Export All Photos</b></li>
</ol>
<p>Photos are copied with original filenames. Useful for archiving,
backup, or preparing a delivery folder.</p>

<h3>⚙️ Dependencies</h3>
<table>
<tr><th>Library</th><th>Status</th><th>Purpose</th></tr>
<tr><td><b>exifread</b></td><td>Recommended</td><td>Primary EXIF parser (pip install exifread)</td></tr>
<tr><td><b>Pillow (PIL)</b></td><td>Fallback</td><td>EXIF parser if exifread not available</td></tr>
<tr><td><b>opencv-python</b></td><td>Optional</td><td>Advanced filters (Edges, Color Bands, Blur)</td></tr>
</table>

<div class='warn'>⚠️ Photos must have GPS EXIF data (geotagged). Photos without
GPS coordinates are silently skipped during import. Most DJI drones
automatically geotag every photo.</div>
"""),
        "vi": _h("""
<h2>📷 Ảnh Flycam — Nhập ảnh drone có tọa độ GPS</h2>
<h3>Tổng quan</h3>
<p>Nhập ảnh drone/máy ảnh có gắn tọa độ GPS thành lớp điểm GIS với đầy đủ
metadata EXIF và DJI XMP. Xem, cập nhật và xuất bộ sưu tập ảnh
trực tiếp trong QGIS.</p>

<h3>📌 Tab 1 — 📥 Nhập ảnh</h3>
<h4>Bước 1: Chọn thư mục ảnh</h4>
<p>Duyệt tới thư mục chứa ảnh JPEG có tọa độ GPS.
Công cụ quét <b>đệ quy</b> — bao gồm cả thư mục con.</p>

<h4>Bước 2: Chọn file đầu ra</h4>
<table>
<tr><th>Định dạng</th><th>Driver</th><th>Phần mở rộng</th><th>Phù hợp cho</th></tr>
<tr><td><b>GeoPackage</b></td><td>GPKG</td><td>.gpkg</td><td>Hiện đại, khuyến nghị</td></tr>
<tr><td><b>Shapefile</b></td><td>ESRI Shapefile</td><td>.shp</td><td>Tương thích cũ</td></tr>
<tr><td><b>GeoJSON</b></td><td>GeoJSON</td><td>.geojson</td><td>Bản đồ web, chia sẻ</td></tr>
<tr><td><b>CSV</b></td><td>CSV</td><td>.csv</td><td>Phân tích bảng tính</td></tr>
<tr><td><b>KML</b></td><td>KML</td><td>.kml</td><td>Google Earth</td></tr>
<tr><td><b>MapInfo TAB</b></td><td>MapInfo File</td><td>.tab</td><td>Người dùng MapInfo</td></tr>
</table>

<h4>Bước 3: Tùy chọn nâng cao</h4>
<table>
<tr><th>Tùy chọn</th><th>Mô tả</th></tr>
<tr><td><b>Thư mục gốc tương đối</b></td><td>Thư mục gốc để tính đường dẫn tương đối (hữu ích cho dự án di động)</td></tr>
<tr><td><b>Đường dẫn web</b></td><td>Tiền tố URL cho xuất KML (VD: http://myserver.com/photos/)</td></tr>
<tr><td><b>Lọc theo phạm vi bản đồ</b></td><td>Chỉ nhập ảnh có GPS nằm trong vùng bản đồ đang hiển thị</td></tr>
</table>

<h4>Bước 4: Nhập ảnh</h4>
<ol>
<li>Nhấn <b>🚀 Nhập ảnh</b></li>
<li>Xử lý chạy nền (QGIS vẫn hoạt động bình thường)</li>
<li>Lớp tự động được thêm vào bản đồ với tooltip hiện ảnh thu nhỏ</li>
</ol>

<h4>Các trường metadata được trích xuất</h4>
<table>
<tr><th>Trường</th><th>Kiểu</th><th>Nguồn</th></tr>
<tr><td><b>Name</b></td><td>Văn bản</td><td>Tên file</td></tr>
<tr><td><b>Date / Time</b></td><td>Văn bản</td><td>EXIF DateTimeOriginal</td></tr>
<tr><td><b>Lon / Lat</b></td><td>Số thực</td><td>Tọa độ GPS EXIF (WGS84)</td></tr>
<tr><td><b>Altitude</b></td><td>Số thực</td><td>Độ cao GPS EXIF (mét)</td></tr>
<tr><td><b>Azimuth</b></td><td>Số thực</td><td>DJI XMP FlightYawDegree hoặc EXIF GPSImgDirection</td></tr>
<tr><td><b>Cam_Maker / Cam_Model</b></td><td>Văn bản</td><td>Thông tin máy ảnh EXIF</td></tr>
<tr><td><b>Path / RelPath</b></td><td>Văn bản</td><td>Đường dẫn tuyệt đối và tương đối</td></tr>
</table>

<div class='tip'>💡 <b>Hỗ trợ drone DJI:</b> FlightYawDegree được tự động trích xuất
từ metadata XMP của DJI, cung cấp hướng bay/phương vị chính xác cho mỗi ảnh.
Chính xác hơn EXIF GPSImgDirection.</div>

<h3>📌 Tab 2 — 👁️ Xem ảnh</h3>
<h4>Xem ảnh bằng click trên bản đồ</h4>
<ol>
<li>Chọn lớp ảnh từ danh sách</li>
<li>Nhấn <b>🖱️ Click ảnh trên bản đồ</b></li>
<li>Click vào bất kỳ điểm ảnh nào trên bản đồ</li>
<li>Cửa sổ Xem ảnh mở ra với ảnh đã chọn</li>
</ol>

<h4>Tính năng Trình xem ảnh</h4>
<table>
<tr><th>Thao tác</th><th>Nút / Phím</th><th>Mô tả</th></tr>
<tr><td><b>Điều hướng</b></td><td>◀ ▶ / ← →</td><td>Ảnh trước / Ảnh sau</td></tr>
<tr><td><b>Zoom</b></td><td>Cuộn chuột</td><td>Phóng to/thu nhỏ tại vị trí chuột</td></tr>
<tr><td><b>Kéo</b></td><td>Click & kéo</td><td>Kéo để di chuyển ảnh</td></tr>
<tr><td><b>Vừa cửa sổ</b></td><td>⊞ / F</td><td>Vừa ảnh vào cửa sổ</td></tr>
<tr><td><b>Xoay 90°</b></td><td>↻ / R</td><td>Xoay theo chiều kim đồng hồ</td></tr>
<tr><td><b>Xoay phương vị</b></td><td>🧭</td><td>Xoay theo hướng GPS (Bắc lên trên)</td></tr>
<tr><td><b>Toàn màn hình</b></td><td>F11</td><td>Bật/tắt chế độ toàn màn hình</td></tr>
<tr><td><b>Lưu</b></td><td>💾</td><td>Lưu ảnh hiện tại thành JPEG/PNG/BMP</td></tr>
</table>

<h4>Bộ lọc ảnh</h4>
<table>
<tr><th>Bộ lọc</th><th>Cần OpenCV</th><th>Mô tả</th></tr>
<tr><td>None</td><td>❌</td><td>Ảnh gốc (mặc định)</td></tr>
<tr><td>Gray</td><td>❌</td><td>Chuyển sang ảnh xám</td></tr>
<tr><td>Mirror</td><td>❌</td><td>Lật ngang</td></tr>
<tr><td>Mono</td><td>❌</td><td>Đen trắng (1-bit)</td></tr>
<tr><td>Edges</td><td>✅</td><td>Phát hiện cạnh Canny</td></tr>
<tr><td>Red / Green / Blue Band</td><td>✅</td><td>Tách kênh màu đơn</td></tr>
<tr><td>Gaussian Blur</td><td>✅</td><td>Làm mờ ảnh</td></tr>
</table>

<div class='tip'>💡 <b>Tooltip bản đồ:</b> Rê chuột qua bất kỳ điểm ảnh nào trên bản đồ
để xem ảnh thu nhỏ — không cần mở trình xem ảnh cho việc nhận diện nhanh.</div>

<h3>📌 Tab 3 — 🔄 Cập nhật</h3>
<p>Đồng bộ lớp ảnh hiện có với thư mục nguồn:</p>
<ul>
<li><b>Ảnh mới</b> thêm vào thư mục → tự động tạo điểm mới</li>
<li><b>Ảnh đã xóa</b> khỏi thư mục → điểm tương ứng bị xóa</li>
</ul>
<ol>
<li>Chọn lớp ảnh cần cập nhật</li>
<li>Nhấn <b>🔄 Cập nhật lớp</b></li>
<li>Thư mục nguồn được xác định từ trường <code>Path</code> của ảnh đầu tiên</li>
</ol>

<h3>📌 Tab 4 — 📤 Xuất ảnh</h3>
<p>Sao chép toàn bộ ảnh trong lớp sang một thư mục:</p>
<ol>
<li>Chọn lớp ảnh</li>
<li>Duyệt tới thư mục đích</li>
<li>Nhấn <b>📤 Xuất tất cả ảnh</b></li>
</ol>
<p>Ảnh được sao chép giữ nguyên tên file. Hữu ích cho lưu trữ,
sao lưu, hoặc chuẩn bị thư mục giao nộp.</p>

<h3>⚙️ Thư viện phụ thuộc</h3>
<table>
<tr><th>Thư viện</th><th>Trạng thái</th><th>Chức năng</th></tr>
<tr><td><b>exifread</b></td><td>Khuyến nghị</td><td>Đọc EXIF chính (pip install exifread)</td></tr>
<tr><td><b>Pillow (PIL)</b></td><td>Dự phòng</td><td>Đọc EXIF nếu không có exifread</td></tr>
<tr><td><b>opencv-python</b></td><td>Tùy chọn</td><td>Bộ lọc nâng cao (Edges, Color Bands, Blur)</td></tr>
</table>

<div class='warn'>⚠️ Ảnh phải có dữ liệu GPS EXIF (đã gắn tọa độ). Ảnh không có
tọa độ GPS sẽ tự động bỏ qua khi nhập. Hầu hết drone DJI
tự động gắn tọa độ cho mọi ảnh.</div>
"""),
    },

    # ══════════════════════════════════════════════════════════════
    # FSC Plot Layout — Batch harvest map export
    # ══════════════════════════════════════════════════════════════
    "fsc_harvest": {
        "en": _h("""
<h2>🗺️ FSC Plot Layout — Harvest Map Export</h2>

<p>Batch-export individual <b>A4 portrait PDF maps</b> for FSC harvest plots.
Each PDF shows a single plot polygon with auto-fit scale, coordinate grid,
north arrow, scale bar, and signature blocks.</p>

<h3>① Data Selection</h3>
<ul>
<li><b>Main layer</b> — Select the polygon layer containing harvest plots</li>
<li><b>Plot ID field</b> — Choose which field to display as the plot code
(e.g. <code>Plot_ID</code> or <code>PlotID_New</code>)</li>
<li><b>Month field</b> — Field containing the harvest month
(e.g. <code>ThangKT</code>). <b>This field is required in your GPKG</b></li>
<li><b>Auxiliary layers</b> — Optional context layers:
contour lines, sub-compartment boundaries, roads, compartment labels</li>
</ul>

<h3>② Plot Selection</h3>
<ul>
<li><b>Filter</b> — Narrow plots by commune (Xã), month, or year</li>
<li><b>Table</b> — Check individual plots or use Select All / Deselect All</li>
<li><b>Counter</b> — Shows selected vs total count</li>
</ul>

<h3>③ Map Settings</h3>
<ul>
<li><b>Title</b> — Default: "BẢN ĐỒ THIẾT KẾ KHAI THÁC RỪNG TRỒNG" (editable)</li>
<li><b>Scale</b> — Auto (1:1000→1:10000 based on plot size) or custom value</li>
<li><b>Signature boxes</b> — Toggle "Plot Owner" and/or "Group Representative"</li>
</ul>

<h3>④ Output</h3>
<ul>
<li><b>Separate PDFs</b> — One file per plot (recommended)</li>
<li><b>Merged PDF</b> — All plots in one multi-page file (requires PyPDF2)</li>
</ul>

<h3>File Naming</h3>
<p>Output files: <code>{Owner}_{PlotID}_T{Month}{Year}.pdf</code><br>
Example: <code>Ban_Thi_Phuong_BDA-TCM-028_T62025.pdf</code></p>

<div class='tip'>💡 <b>Tip</b>: The scale auto-adjusts to fit each plot
within the A4 page. Small plots (~0.3ha) get 1:1000, larger plots
(>2ha) get up to 1:5000.</div>

<div class='warn'>⚠️ Your GPKG must include a harvest month field
(e.g. <code>ThangKT</code>) for proper labeling.</div>
"""),

        "vi": _h("""
<h2>🗺️ Bản đồ trích lục FSC — Xuất bản đồ khai thác</h2>

<p>Xuất hàng loạt <b>bản đồ PDF khổ A4 dọc</b> cho từng lô khai thác FSC.
Mỗi file PDF thể hiện duy nhất một lô rừng với tỷ lệ tự động,
lưới tọa độ, mũi tên Bắc, thước tỷ lệ và ô ký.</p>

<h3>① Chọn dữ liệu</h3>
<ul>
<li><b>Layer chính</b> — Chọn layer polygon chứa các lô khai thác</li>
<li><b>Trường mã lô</b> — Chọn trường hiển thị mã lô
(ví dụ: <code>Plot_ID</code> hoặc <code>PlotID_New</code>)</li>
<li><b>Trường tháng KT</b> — Trường chứa tháng khai thác
(ví dụ: <code>ThangKT</code>). <b>Trường này bắt buộc trong GPKG</b></li>
<li><b>Layer phụ trợ</b> — Các lớp ngữ cảnh (tùy chọn):
đường đồng mức, ranh tiểu khu, giao thông, số hiệu TK/khoảnh</li>
</ul>

<h3>② Chọn lô khai thác</h3>
<ul>
<li><b>Lọc</b> — Lọc theo xã, tháng, hoặc năm</li>
<li><b>Bảng</b> — Đánh dấu từng lô hoặc dùng Chọn tất cả / Bỏ chọn</li>
<li><b>Bộ đếm</b> — Hiển thị số lô đã chọn / tổng</li>
</ul>

<h3>③ Cài đặt bản đồ</h3>
<ul>
<li><b>Tiêu đề</b> — Mặc định: "BẢN ĐỒ THIẾT KẾ KHAI THÁC RỪNG TRỒNG" (có thể sửa)</li>
<li><b>Tỷ lệ</b> — Tự động (1:1000→1:10000 tùy kích thước lô) hoặc tùy chỉnh</li>
<li><b>Ô ký</b> — Bật/tắt "Chủ rừng" và/hoặc "Đại diện nhóm chứng chỉ"</li>
</ul>

<h3>④ Đầu ra</h3>
<ul>
<li><b>Nhiều file PDF riêng</b> — Mỗi lô 1 file (khuyến nghị)</li>
<li><b>Gộp 1 file PDF</b> — Tất cả lô trong 1 file nhiều trang (cần PyPDF2)</li>
</ul>

<h3>Quy tắc đặt tên file</h3>
<p>Tên file: <code>{Chủ_rừng}_{Mã_lô}_T{Tháng}{Năm}.pdf</code><br>
Ví dụ: <code>Ban_Thi_Phuong_BDA-TCM-028_T62025.pdf</code></p>

<div class='tip'>💡 <b>Mẹo</b>: Tỷ lệ tự điều chỉnh để lô rừng
nằm trọn trong trang A4. Lô nhỏ (~0.3ha) → 1:1000, lô lớn
(>2ha) → đến 1:5000.</div>

<div class='warn'>⚠️ GPKG phải có trường tháng khai thác
(ví dụ: <code>ThangKT</code>) để ghi nhãn chính xác.</div>
"""),
    },

}


def get_help_html(module_key, lang="en"):
    """Return HTML help content for the given module and language.

    Args:
        module_key: str, one of the keys in _HELP dict.
        lang: 'en' or 'vi'.

    Returns:
        str: HTML content string.
    """
    entry = _HELP.get(module_key)
    if not entry:
        fallback = "No help available." if lang == "en" \
            else "Chưa có hướng dẫn."
        return f"<p>{fallback}</p>"
    return entry.get(lang, entry.get("en", ""))
