Folder Maker

Create a clean folder structure in seconds

Everything is generated locally in your browser. Nothing is uploaded.

Preview

document.addEventListener("DOMContentLoaded", () => { // Application state and translations remain scoped within the listener const TRANSLATIONS = { en: { title: "Folder Maker", subtitle: "Create a clean folder structure in seconds", trustNote: "Everything is generated locally in your browser. Nothing is uploaded.", labelPreset: "Structure Preset", labelRoot: "Root Folder Name (Optional)", labelFolderLang: "Folder Language", labelPreview: "Preview", btnDownload: "Download folder structure", githubNote: "Open source — review the code on GitHub", explanationTitle: "How to use these structures", explanationIntro: "Each structure is a ready-made folder skeleton.", explanationList: [ "use one structure as your main root", "download several and use them side by side", "place one structure inside another as a subfolder system" ], explanationExampleTitle: "Example:", explanationExampleItems: [ "use “Life Aspects” as a main personal structure", "use “Project Archive” inside WORK for one specific project", "use “Action Flow” as a separate operational folder" ], presets: { A: { name: "Life Aspects", desc: "For long-term organization of life and assets", guidance: "Organize life across material and non-material domains" }, B: { name: "Simple Life / Work", desc: "A minimal work-life balance setup", guidance: "Start with a compact everyday structure" }, C: { name: "Project Archive", desc: "Optimized for specific project documentation", guidance: "Store project files, notes, and communications together" }, D: { name: "Action Flow", desc: "GTD-inspired operational setup", guidance: "Manage active work from inbox to archive" } }, toc: { purpose: "Purpose", howToUse: "How to use", optionalTools: "Optional tools", notes: "Notes", toolsText: "- merge markdown notes into one document\n- structure files into clean batches before storing", folders: { MATERIAL: { title: "Material", purpose: "financial and professional life", howTo: "organize documents into subfolders, keep records retrievable" }, NON_MATERIAL: { title: "Non-Material", purpose: "well-being, relationships, growth", howTo: "keep notes and materials organized by domain" }, WORK_CAREER: { title: "Work & Career", purpose: "professional activities", howTo: "store project files, career documents, notes", tools: "- merge AI/chat/planning notes, structure incoming files" }, MONEY_STREAMS: { title: "Money Streams", purpose: "income and financial inflows", howTo: "store contracts, invoices, income records", tools: "- structure financial documents, merge planning notes" }, ASSET_BASE: { title: "Asset Base", purpose: "assets, ownership, long-term value", howTo: "store property, investment, ownership documents", tools: "- structure asset-related files, merge research notes" }, HEALTH: { title: "Health", purpose: "physical and mental well-being", howTo: "store records, routines, notes" }, RELATIONS: { title: "Relations", purpose: "personal and professional relationships", howTo: "store notes and relevant materials, separate by person or context if needed", tools: "- merge conversation notes, structure files" }, SELF_DEVELOPMENT: { title: "Self Development", purpose: "learning and growth", howTo: "store courses, notes, reading materials", tools: "- merge fragmented notes, structure files" }, WORK: { title: "Work", purpose: "work-related materials" }, PERSONAL: { title: "Personal", purpose: "personal documents and notes" }, LEARNING: { title: "Learning", purpose: "study materials and notes" }, FINANCE: { title: "Finance", purpose: "financial records" }, LEGAL: { title: "Legal", purpose: "legal and administrative materials" }, PROJECTS: { title: "Projects", purpose: "project folders and outputs" }, COMMUNICATION: { title: "Communication", purpose: "project communication records and notes" }, FILES: { title: "Files", purpose: "working files and deliveries" }, NOTES: { title: "Notes", purpose: "markdown notes and thinking documents" }, REFERENCES: { title: "References", purpose: "external materials and sources" }, INBOX: { title: "Inbox", purpose: "new, unprocessed items" }, THIS_WEEK: { title: "This Week", purpose: "items to work on this week" }, WAITING: { title: "Waiting", purpose: "items pending response or external action" }, DONE: { title: "Done", purpose: "recently completed items" }, ARCHIVE: { title: "Archive", purpose: "long-term storage of inactive/completed materials" } } } }, fr: { title: "Folder Maker", subtitle: "Créez une structure de dossiers propre en quelques secondes", trustNote: "Tout est généré localement dans votre navigateur. Rien n'est téléchargé vers un serveur.", labelPreset: "Préréglage de Structure", labelRoot: "Nom du dossier racine (Optionnel)", labelFolderLang: "Langue des dossiers", labelPreview: "Aperçu", btnDownload: "Télécharger la structure de dossiers", githubNote: "Open source — examinez le code sur GitHub", explanationTitle: "Comment utiliser ces structures", explanationIntro: "Chaque structure est un squelette de dossiers prêt à l'emploi.", explanationList: [ "utiliser une structure comme racine principale", "en télécharger plusieurs et les utiliser côte à côte", "placer une structure à l'intérieur d'une autre comme système de sous-dossiers" ], explanationExampleTitle: "Exemple :", explanationExampleItems: [ "utiliser « Life Aspects » comme structure personnelle principale", "utiliser « Project Archive » dans WORK pour un projet spécifique", "utiliser « Action Flow » comme dossier opérationnel séparé" ], presets: { A: { name: "Aspects de Vie", desc: "Pour l'organisation à long terme de la vie et des actifs", guidance: "Organiser la vie entre dimensions matérielles et non matérielles" }, B: { name: "Vie / Travail Simple", desc: "Une configuration minimale pour l'équilibre travail-vie personnelle", guidance: "Démarrer avec une structure simple pour le quotidien" }, C: { name: "Archive de Projet", desc: "Optimisé pour la documentation de projets spécifiques", guidance: "Regrouper fichiers, notes et communications d’un projet" }, D: { name: "Action Flow", desc: "Configuration opérationnelle inspirée de GTD", guidance: "Gérer le travail actif de l’entrée jusqu’à l’archive" } }, toc: { purpose: "Objectif", howToUse: "Comment utiliser", optionalTools: "Outils optionnels", notes: "Notes", toolsText: "- fusionner les notes markdown en un seul document\n- structurer les fichiers en lots propres avant le stockage", folders: { MATERIAL: { title: "Matériel", purpose: "vie financière et professionnelle", howTo: "organiser les documents en sous-dossiers, garder les enregistrements accessibles" }, NON_MATERIAL: { title: "Non-Matériel", purpose: "bien-être, relations, croissance", howTo: "garder les notes et matériaux organisés par domaine" }, WORK_CAREER: { title: "Work & Career", purpose: "activités professionnelles", howTo: "stocker les fichiers de projet, documents de carrière, notes", tools: "- fusionner les notes d'IA/chat/planification, structurer les fichiers entrants" }, MONEY_STREAMS: { title: "Flux d'Argent", purpose: "revenus et flux financiers", howTo: "stocker contrats, factures, relevés de revenus", tools: "- structurer les documents financiers, fusionner les notes de planification" }, ASSET_BASE: { title: "Base d'Actifs", purpose: "actifs, propriété, valeur à long terme", howTo: "stocker les documents de propriété, d'investissement, de possession", tools: "- structurer les fichiers liés aux actifs, fusionner les notes de recherche" }, HEALTH: { title: "Santé", purpose: "bien-être physique et mental", howTo: "stocker les dossiers, routines, notes" }, RELATIONS: { title: "Relations", purpose: "relations personnelles et professionnelles", howTo: "stocker les notes et matériaux pertinents, séparer par personne ou contexte si besoin", tools: "- fusionner les notes de conversation, structurer les fichiers" }, SELF_DEVELOPMENT: { title: "Développement Personnel", purpose: "apprentissage et croissance", howTo: "stocker les cours, notes, supports de lecture", tools: "- fusionner les notes fragmentées, structurer les fichiers" }, WORK: { title: "Travail", purpose: "matériel lié au travail" }, PERSONAL: { title: "Personnel", purpose: "documents et notes personnels" }, LEARNING: { title: "Apprentissage", purpose: "matériel d'étude et notes" }, FINANCE: { title: "Finance", purpose: "enregistrements financiers" }, LEGAL: { title: "Juridique", purpose: "matériel juridique et administratif" }, PROJECTS: { title: "Projets", purpose: "dossiers et sorties de projet" }, COMMUNICATION: { title: "Communication", purpose: "enregistrements et notes de communication de projet" }, FILES: { title: "Fichiers", purpose: "fichiers de travail et livrables" }, NOTES: { title: "Notes", purpose: "notes markdown et documents de réflexion" }, REFERENCES: { title: "Références", purpose: "matériaux et sources externes" }, INBOX: { title: "Boîte de réception", purpose: "nouveaux éléments non traités" }, THIS_WEEK: { title: "Cette semaine", purpose: "éléments sur lesquels travailler cette semaine" }, WAITING: { title: "En attente", purpose: "éléments en attente de réponse ou d'action externe" }, DONE: { title: "Fait", purpose: "éléments récemment terminés" }, ARCHIVE: { title: "Archive", purpose: "stockage à long terme de matériaux inactifs/terminés" } } } }, de: { title: "Folder Maker", subtitle: "Erstellen Sie eine saubere Ordnerstruktur in Sekunden", trustNote: "Alles wird lokal in Ihrem Browser generiert. Nichts wird hochgeladen.", labelPreset: "Struktur-Voreinstellung", labelRoot: "Stammordnername (Optional)", labelFolderLang: "Ordnersprache", labelPreview: "Vorschau", btnDownload: "Ordnerstruktur herunterladen", githubNote: "Open Source — prüfen Sie den Code auf GitHub", explanationTitle: "Verwendung dieser Strukturen", explanationIntro: "Jede Struktur ist ein fertiges Ordnerskelett.", explanationList: [ "eine Struktur als Hauptstamm verwenden", "mehrere herunterladen und nebeneinander verwenden", "eine Struktur in eine andere als Unterordnersystem einfügen" ], explanationExampleTitle: "Beispiel:", explanationExampleItems: [ "„Life Aspects“ als persönliche Hauptstruktur verwenden", "„Project Archive“ innerhalb von WORK für ein bestimmtes Projekt verwenden", "„Action Flow“ als separaten operativen Ordner verwenden" ], presets: { A: { name: "Lebensaspekte", desc: "Für die langfristige Organisation von Leben und Vermögen", guidance: "Leben nach materiellen und nicht-materiellen Bereichen strukturieren" }, B: { name: "Einfaches Leben / Arbeit", desc: "Ein minimales Work-Life-Balance-Setup", guidance: "Mit einer kompakten Alltagsstruktur starten" }, C: { name: "Projektarchiv", desc: "Optimiert für spezifische Projektdokumentation", guidance: "Projektdateien, Notizen und Kommunikation bündeln" }, D: { name: "Action Flow", desc: "GTD-inspiriertes operatives Setup", guidance: "Aktive Arbeit vom Eingang bis zum Archiv steuern" } }, toc: { purpose: "Zweck", howToUse: "Anwendung", optionalTools: "Optionale Werkzeuge", notes: "Anmerkungen", toolsText: "- Markdown-Notizen in einem Dokument zusammenführen\n- Dateien in saubere Chargen strukturieren vor der Lagerung", folders: { MATERIAL: { title: "Materielles", purpose: "Finanzielles und berufliches Leben", howTo: "Dokumente in Unterordner organisieren, Aufzeichnungen auffindbar halten" }, NON_MATERIAL: { title: "Immaterielles", purpose: "Wohlbefinden, Beziehungen, Wachstum", howTo: "Notizen und Materialien nach Bereichen organisiert halten" }, WORK_CAREER: { title: "Arbeit & Karriere", purpose: "Berufliche Aktivitäten", howTo: "Projektdateien, Karrieremappen, Notizen speichern", tools: "- KI-/Chat-/Planungsnotizen zusammenführen, eingehende Dateien strukturieren" }, MONEY_STREAMS: { title: "Geldflüsse", purpose: "Einkommen und finanzielle Zuflüsse", howTo: "Verträge, Rechnungen, Einkommensbelege speichern", tools: "- Finanzdokumente strukturieren, Planungsnotizen zusammenführen" }, ASSET_BASE: { title: "Vermögensbasis", purpose: "Vermögenswerte, Eigentum, langfristiger Wert", howTo: "Eigentums-, Investitions- и Besitzdokumente speichern", tools: "- vermögensbezogene Dateien strukturieren, Forschungsnotizen zusammenführen" }, HEALTH: { title: "Gesundheit", purpose: "physisches und mentales Wohlbefinden", howTo: "Aufzeichnungen, Routinen, Notizen speichern" }, RELATIONS: { title: "Beziehungen", purpose: "persönliche und berufliche Beziehungen", howTo: "Notizen und relevante Materialien speichern, bei Bedarf nach Person oder Kontext trennen", tools: "- Gesprächsnotizen zusammenführen, Dateien strukturieren" }, SELF_DEVELOPMENT: { title: "Selbstentwicklung", purpose: "Lernen und Wachstum", howTo: "Kurse, Notizen, Lesematerialien speichern", tools: "- fragmentierte Notizen zusammenführen, Dateien strukturieren" }, WORK: { title: "Arbeit", purpose: "arbeitsbezogene Materialien" }, PERSONAL: { title: "Privat", purpose: "persönliche Dokumente und Notizen" }, LEARNING: { title: "Lernen", purpose: "Studienmaterialien und Notizen" }, FINANCE: { title: "Finanzen", purpose: "Finanzunterlagen" }, LEGAL: { title: "Rechtliches", purpose: "rechtliche und administrative Materialien" }, PROJECTS: { title: "Projekts", purpose: "Projektordner und Ergebnisse" }, COMMUNICATION: { title: "Kommunikation", purpose: "Projektkommunikationsaufzeichnungen und -notizen" }, FILES: { title: "Dateien", purpose: "Arbeitsdateien und Lieferungen" }, NOTES: { title: "Notizen", purpose: "Markdown-Notizen und Denkdokumente" }, REFERENCES: { title: "Referenzen", purpose: "externe Materialien и Quellen" }, INBOX: { title: "Eingang", purpose: "neue, unverarbeitete Elemente" }, THIS_WEEK: { title: "Diese Woche", purpose: "Elemente für diese Woche" }, WAITING: { title: "Wartend", purpose: "Elemente, die auf Antwort oder externe Aktion warten" }, DONE: { title: "Erledigt", purpose: "kürzlich abgeschlossene Elemente" }, ARCHIVE: { title: "Archiv", purpose: "Langzeitaufbewahrung von inaktiven/abgeschlossenen Materialien" } } } }, ru: { title: "Folder Maker", subtitle: "Создайте чистую структуру папок за секунды", trustNote: "Всё генерируется локально в вашем браузере. Ничего не загружается на сервер.", labelPreset: "Пресет структуры", labelRoot: "Имя корневой папки (опционально)", labelFolderLang: "Язык папок", labelPreview: "Предпросмотр", btnDownload: "Скачать структуру папок", githubNote: "Open source — проверьте код на GitHub", explanationTitle: "Как использовать эти структуры", explanationIntro: "Каждая структура — это готовый скелет папок.", explanationList: [ "используйте одну структуру как основной корень", "скачайте несколько и используйте их рядом", "поместите одну структуру внутрь другой как систему подпапок" ], explanationExampleTitle: "Пример:", explanationExampleItems: [ "используйте «Life Aspects» как основную личную структуру", "используйте «Project Archive» внутри WORK для конкретного проекта", "используйте «Action Flow» как отдельную операционную папку" ], presets: { A: { name: "Жизненные аспекты", desc: "Для долгосрочной организации жизни и активов", guidance: "Организовать жизнь по материальным и нематериальным аспектам" }, B: { name: "Простая жизнь / Работа", desc: "Минималистичная настройка баланса работы и жизни", guidance: "Начать с простой структуры для повседневных задач" }, C: { name: "Архив проекта", desc: "Оптимизировано для документации конкретных проектов", guidance: "Хранить файлы, заметки и коммуникации по проекту вместе" }, D: { name: "Поток действий", desc: "Операционная настройка в стиле GTD", guidance: "Управлять текущими задачами от входящих до архива" } }, toc: { purpose: "Цель", howToUse: "Как использовать", optionalTools: "Дополнительные инструменты", notes: "Заметки", toolsText: "- объединяйте заметки markdown в один документ\n- структурируйте файлы в чистые пакеты перед хранением", folders: { MATERIAL: { title: "Материальное", purpose: "финансовая и профессиональная жизнь", howTo: "организуйте документы по подпапкам, поддерживайте порядок" }, NON_MATERIAL: { title: "Нематериальное", purpose: "благополучие, отношения, развитие", howTo: "храните заметки и материалы организованно по доменам" }, WORK_CAREER: { title: "Работа и Карьера", purpose: "профессиональная деятельность", howTo: "храните файлы проектов, карьерные документы, заметки", tools: "- объединяйте заметки ИИ/чатов/планирования, структурируйте входящие файлы" }, MONEY_STREAMS: { title: "Денежные потоки", purpose: "доходы и финансовые поступления", howTo: "храните контракты, счета, записи о доходах", tools: "- структурируйте финансовые документы, объединяйте заметки по планированию" }, ASSET_BASE: { title: "База активов", purpose: "активы, собственность, долгосрочная ценность", howTo: "храните документы на собственность, инвестиции", tools: "- структурируйте файлы активов, объединяйте заметки по исследованиям" }, HEALTH: { title: "Здоровье", purpose: "физическое и ментальное благополучие", howTo: "храните записи, распорядки, заметки" }, RELATIONS: { title: "Отношения", purpose: "личные и профессиональные отношения", howTo: "храните заметки и важные материалы, разделяйте по людям или контексту", tools: "- объединяйте заметки встреч, структурируйте файлы" }, SELF_DEVELOPMENT: { title: "Саморазвитие", purpose: "обучение и рост", howTo: "храните курсы, заметки, материалы для чтения", tools: "- объединяйте фрагментированные заметки, структурируйте файлы" }, WORK: { title: "Работа", purpose: "рабочие материалы" }, PERSONAL: { title: "Личное", purpose: "личные документы и заметки" }, LEARNING: { title: "Обучение", purpose: "учебные материалы и заметки" }, FINANCE: { title: "Финансы", purpose: "финансовые записи" }, LEGAL: { title: "Юридическое", purpose: "юридические и административные материалы" }, PROJECTS: { title: "Проекты", purpose: "папки проектов и результаты" }, COMMUNICATION: { title: "Коммуникации", purpose: "записи коммуникаций по проекту и заметки" }, FILES: { title: "Файлы", purpose: "рабочие файлы и поставки" }, NOTES: { title: "Заметки", purpose: "заметки markdown и документы для размышлений" }, REFERENCES: { title: "Ссылки", purpose: "внешние материалы и источники" }, INBOX: { title: "Входящие", purpose: "новые, необработанные элементы" }, THIS_WEEK: { title: "На этой неделе", purpose: "задачи на текущую неделю" }, WAITING: { title: "Ожидание", purpose: "элементы, ожидающие ответа или внешнего действия" }, DONE: { title: "Сделано", purpose: "недавно завершенные элементы" }, ARCHIVE: { title: "Архив", purpose: "долгосрочное хранение неактивных/завершенных материалов" } } } } }; const PRESETS = { A: { key: "LIFE_ASPECTS", icon: '', structure: { MATERIAL: { WORK_CAREER: {}, MONEY_STREAMS: {}, ASSET_BASE: {} }, NON_MATERIAL: { HEALTH: {}, RELATIONS: {}, SELF_DEVELOPMENT: {} } } }, B: { key: "SIMPLE", icon: '', structure: { WORK: {}, PERSONAL: {}, LEARNING: {}, FINANCE: {}, LEGAL: {} } }, C: { key: "PROJECT_ARCHIVE", icon: '', structure: { PROJECTS: {}, COMMUNICATION: {}, FILES: {}, NOTES: {}, REFERENCES: {} } }, D: { key: "ACTION_FLOW", icon: '', structure: { INBOX: {}, THIS_WEEK: {}, WAITING: {}, DONE: {}, ARCHIVE: {} } } }; class FolderMaker { constructor() { this.lang = localStorage.getItem("fm-lang") || "en"; this.folderLang = localStorage.getItem("fm-folder-lang") || "en"; this.theme = localStorage.getItem("fm-theme") || "system"; this.currentPreset = "A"; this.rootName = ""; this.initEventListeners(); this.applyTheme(); this.updateUI(); } initEventListeners() { document.getElementById("lang-switcher").addEventListener("change", (e) => { this.lang = e.target.value; localStorage.setItem("fm-lang", this.lang); this.updateUI(); }); document.getElementById("folder-lang-switcher").addEventListener("change", (e) => { this.folderLang = e.target.value; localStorage.setItem("fm-folder-lang", this.folderLang); this.updateTree(); }); document.getElementById("theme-switcher").addEventListener("change", (e) => { this.theme = e.target.value; localStorage.setItem("fm-theme", this.theme); this.applyTheme(); }); document.getElementById("preset-selector").addEventListener("change", (e) => { this.currentPreset = e.target.value; this.updateUI(); }); document.getElementById("root-name").addEventListener("input", (e) => { this.rootName = e.target.value; this.updateTree(); }); document.getElementById("download-btn").addEventListener("click", () => { this.generateZip(); }); } applyTheme() { document.body.setAttribute("data-theme", this.theme); document.getElementById("theme-switcher").value = this.theme; } updateUI() { const t = TRANSLATIONS[this.lang]; // Labels and static text document.getElementById("ui-title").textContent = t.title; document.getElementById("ui-subtitle").textContent = t.subtitle; document.getElementById("ui-label-preset").textContent = t.labelPreset; document.getElementById("ui-label-root").textContent = t.labelRoot; document.getElementById("ui-label-folder-lang").textContent = t.labelFolderLang; document.getElementById("ui-label-preview").textContent = t.labelPreview; document.getElementById("download-btn").textContent = t.btnDownload; // Selector values document.getElementById("lang-switcher").value = this.lang; document.getElementById("folder-lang-switcher").value = this.folderLang; // Tooltips document.getElementById("lang-switcher").title = `UI: ${this.lang.toUpperCase()}`; document.getElementById("folder-lang-switcher").title = `Folders: ${this.folderLang.toUpperCase()}`; // Preset choices const selector = document.getElementById("preset-selector"); Array.from(selector.options).forEach((opt) => { opt.textContent = t.presets[opt.value].name; }); // Active preset description document.getElementById("ui-preset-desc").innerHTML = ` ${PRESETS[this.currentPreset].icon}
${t.presets[this.currentPreset].name}

${t.presets[this.currentPreset].guidance}

`; // Trust note document.getElementById("ui-trust-note").innerHTML = `
${t.trustNote}
${t.githubNote}
`; // Explanation box const exp = document.getElementById("explanation-block"); exp.innerHTML = `

${t.explanationTitle}

${t.explanationIntro}

`; this.updateTree(); } sanitize(name) { if (!name) return ""; return name .replace(/[\\/:*?"<>|]/g, "") .replace(/[\s\-_.]+/g, "_") .replace(/^_+|_+$/g, ""); } getLocalizedFolderName(key) { const folderInfo = TRANSLATIONS[this.folderLang].toc.folders[key]; return this.sanitize(folderInfo ? folderInfo.title : key); } getFinalRoot() { const sanitized = this.sanitize(this.rootName); if (sanitized) return sanitized; const presetName = TRANSLATIONS[this.folderLang].presets[this.currentPreset].name; return this.sanitize(`${presetName}_ROOT`); } updateTree() { const root = this.getFinalRoot(); const structure = PRESETS[this.currentPreset].structure; const container = document.getElementById("tree-preview"); if (!container) return; container.innerHTML = ""; const rootEl = document.createElement("div"); rootEl.className = "tree-folder"; rootEl.textContent = root + "/"; container.appendChild(rootEl); this.renderNode(structure, container, 0); } renderNode(node, container, level) { const keys = Object.keys(node); keys.forEach((key, index) => { const isLast = index === keys.length - 1; const localizedName = this.getLocalizedFolderName(key); const nodeEl = document.createElement("div"); nodeEl.className = `tree-node ${isLast ? "last" : ""}`; const nameEl = document.createElement("span"); nameEl.className = "tree-folder"; nameEl.textContent = localizedName + "/"; nodeEl.appendChild(nameEl); container.appendChild(nodeEl); const hasSubfolders = Object.keys(node[key]).length > 0; const tocNode = document.createElement("div"); tocNode.className = `tree-node ${!hasSubfolders ? "last" : ""}`; const tocFile = document.createElement("span"); tocFile.className = "tree-file"; tocFile.textContent = "_INDEX.md"; tocNode.appendChild(tocFile); nodeEl.appendChild(tocNode); if (hasSubfolders) { this.renderNode(node[key], nodeEl, level + 1); } }); } generateINDEX(folderKey) { const t = TRANSLATIONS[this.folderLang].toc; const info = t.folders[folderKey] || { title: folderKey, purpose: "", howTo: "" }; return `# ${info.title} ## ${t.purpose} ${info.purpose} ## ${t.howToUse} ${info.howTo} ## ${t.optionalTools} ${info.tools || t.toolsText} ## ${t.notes} --- `; } async generateZip() { const zip = new JSZip(); const root = this.getFinalRoot(); const structure = PRESETS[this.currentPreset].structure; const rootFolder = zip.folder(root); const addStructure = (node, folder) => { Object.keys(node).forEach((key) => { const localizedName = this.getLocalizedFolderName(key); const subFolder = folder.folder(localizedName); subFolder.file("_INDEX.md", this.generateINDEX(key)); if (Object.keys(node[key]).length > 0) { addStructure(node[key], subFolder); } }); }; addStructure(structure, rootFolder); const content = await zip.generateAsync({ type: "blob" }); const url = window.URL.createObjectURL(content); const a = document.createElement("a"); a.href = url; a.download = `folder_structure_${this.currentPreset.toLowerCase()}.zip`; a.click(); window.URL.revokeObjectURL(url); } } // Start App window.app = new FolderMaker(); });