Fantasy Kingdom Law & Governance Document

Fantasy Kingdom Law & Governance Document Generator

Draft: The Royal Edicts (Editable)

Define your kingdom's laws using the "Configuration" tab and click "Generate Document."

I. Kingdom Identity & Sovereignty

II. Law & Justice

III. Citizens & Economy

Proclaimed by His ${escapeHTML(data.rulerTitle)} on this day, ${data.today}.

I. FOUNDATIONAL PRINCIPLES
${clause('foundational', 'Article I.I. Source of Authority:', data.foundational)}
II. SOVEREIGNTY AND SUCCESSION
${clause('rulerTitle', 'Article II.I. Title of the Sovereign:', `${data.rulerTitle}`)} ${clause('succession', 'Article II.II. Law of Succession:', data.succession)}
III. JUSTICE AND JUDGMENT
${clause('justiceSystem', 'Article III.I. Judicial Authority:', `Justice shall be administered through the Royal Courts using the ${data.justiceSystem} system.`)} ${clause('crime', 'Article III.II. Highest Penalty:', `The maximum penalty for the crime of Treason against the Crown or the Realm shall be ${data.crime}.`)}
IV. RIGHTS AND RESPONSIBILITIES
${clause('rights', 'Article IV.I. Inalienable Rights of Citizens:', data.rights)} ${clause('labor', 'Article IV.II. Fealty and Labor:', `Every able-bodied subject owes a service of ${data.labor} to the local Lord or the Crown.`)}
V. ECONOMY AND TAXATION
${clause('tax', 'Article V.I. The Royal Tithe:', `All income and yields are subject to the Royal Tithe at a rate of ${data.tax}.`)} `; setupDashboardListeners(); if (!isInitial) showTab('fklg-tab-dashboard'); } /** * Attaches listeners to the dashboard elements for editing */ function setupDashboardListeners() { const output = dashboardOutput; if (!output) return; // Listen for input/change events to update the underlying config values output.querySelectorAll('input, textarea').forEach(element => { element.addEventListener('input', handleDashboardUpdate); element.addEventListener('change', handleDashboardUpdate); }); } /** * Handles updates made directly to the dashboard inputs/textareas */ function handleDashboardUpdate(e) { const target = e.target; const value = target.value; // Update Config Inputs based on Dashboard edits (two-way binding) if (target.id === 'dash-name') configName.value = value; else if (target.id === 'dash-ruler-name') configRulerName.value = value; else if (target.id === 'dash-foundational') configFoundational.value = value; else if (target.id === 'dash-rulerTitle') configRulerTitle.value = value; else if (target.id === 'dash-succession') configSuccession.value = value; else if (target.id === 'dash-justiceSystem') configJusticeSystem.value = value.replace(/Justice shall be administered through the Royal Courts using the (.*?) system\./, '$1').trim(); // Extract value from sentence else if (target.id === 'dash-crime') configCrime.value = value; else if (target.id === 'dash-rights') configRights.value = value; else if (target.id === 'dash-labor') configLabor.value = value; else if (target.id === 'dash-tax') configTaxRate.value = value; } /** * Generates a PDF report from the dashboard data */ function downloadPDF() { if (typeof window.jspdf === 'undefined') { alert("Error: PDF library (jsPDF) could not be loaded. Please try again."); return; } // Get ALL content from the dashboard output area (which is editable) const content = dashboardOutput.innerText; const { jsPDF } = window.jspdf; const doc = new jsPDF("p", "pt", "a4"); const margin = 50; const usableWidth = doc.internal.pageSize.getWidth() - margin * 2; doc.setFont("times", "normal"); doc.setFontSize(11); // Since the dashboard contains complex formatting (headings, indents), // we use doc.text with splitTextTo preserve line breaks and formatting const lines = doc.splitTextToSize(content, usableWidth); let yPos = margin; const lineHeight = 14; lines.forEach((line) => { if (yPos > doc.internal.pageSize.getHeight() - margin) { doc.addPage(); yPos = margin; } doc.text(line, margin, yPos); yPos += lineHeight; }); const fileName = configName.value ? `${configName.value.replace(/ /g,"_")}_Governance_Edict.pdf` : "Fantasy_Governance_Edict.pdf"; doc.save(fileName); } /** * Helper to escape HTML */ function escapeHTML(str) { if (!str) return ""; return str .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // --- 3. INITIALIZATION & EVENT LISTENERS --- // Tab Listeners tabButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); navButtons.forEach((btn) => { btn.addEventListener("click", () => showTab(btn.dataset.target)); }); // Config Tab Listeners if (generateBtn) { generateBtn.addEventListener("click", () => renderDashboard(false)); } // PDF Button if (pdfBtn) { pdfBtn.addEventListener("click", downloadPDF); } // Initial State: Generate dashboard with samples renderDashboard(); showTab("fklg-tab-dashboard"); });
Scroll to Top