//+------------------------------------------------------------------+ //| Configuracion | //+------------------------------------------------------------------+ // Solo el core sin lenguajes import hljs from 'https://esm.sh/highlight.js/lib/core'; import fgblc_language from './Fgblc/fgblc_language.js'; //+------------------------------------------------------------------+ //| Configuracion | //+------------------------------------------------------------------+ const FEATURES_PER_PAGE = 20; // Color por tipo de categoria (se asigna dinamicamente segun orden de aparicion) const TYPE_COLOR_POOL = [ "#00d084", // verde accent "#0090ff", // azul "#ff6b35", // naranja "#a855f7", // purpura "#f59e0b", // amarillo "#ec4899", // rosa "#06b6d4", // cyan "#84cc16", // lima ]; //+------------------------------------------------------------------+ //| Estado global | //+------------------------------------------------------------------+ let all_features = []; // todas las features cargadas del JSON let type_colors = {}; // mapa tipo -> color let current_cat = "all"; let current_search = ""; let current_page = 1; let all_examples = []; // array string con todos los ejemplos //+------------------------------------------------------------------+ //| Carga del JSON | //+------------------------------------------------------------------+ async function load_features() { try { // Cargar los dos JSON en paralelo con Promise.all const [features_res, examples_res] = await Promise.all([ fetch("features.json"), fetch("Examples/main.json") ]); if (!features_res.ok) throw new Error("Failed to load features.json — status: " + features_res.status); if (!examples_res.ok) throw new Error("Could not load examples/main.json — status: " + examples_res.status); // Obtenemos los datos const features_data = await features_res.json(); const examples_data = await examples_res.json(); // Llenar los dos arrays all_features = features_data.features || []; all_examples = examples_data.examples || []; // Construir todo build_type_colors(); build_sidebar(); render_page(); } catch (err) { console.error(err); document.getElementById("featuresGrid").innerHTML = `
Error loading data: ${err.message}
`; } } /* //+------------------------------------------------------------------+ //| Colores dinamicos por tipo | //+------------------------------------------------------------------+ */ function build_type_colors() { let color_index = 0; all_features.forEach(f => { if (!type_colors[f.type]) { type_colors[f.type] = TYPE_COLOR_POOL[color_index % TYPE_COLOR_POOL.length]; color_index++; } }); } function get_color(type_name) { return type_colors[type_name] || "#275fc0"; } /* //+------------------------------------------------------------------+ //| Sidebar dinamico | //+------------------------------------------------------------------+ */ function build_sidebar() { build_categories(); // usa all_features (primero catergoias parate incial) build_examples(); // usa all_examples } // Parte de exampels function build_examples() { const container = document.getElementById("sidebar_examples"); container.innerHTML = ""; all_examples.forEach(ex => { const btn = document.createElement("button"); btn.className = "filter-btn"; btn.dataset.id = ex.id; btn.innerHTML = ` ${ex.id} `; btn.addEventListener("click", () => on_example_click(ex, btn)); container.appendChild(btn); }); } // Parte de categorias function build_categories() { const container = document.getElementById("sidebar_categories"); container.innerHTML = ""; // Boton "Todas" const total = all_features.length; container.innerHTML += make_sidebar_btn("all", "all", "#5a6478", total, current_cat === "all"); // Un boton por cada tipo unico encontrado en el JSON const types = [...new Set(all_features.map(f => f.type))]; types.forEach(type => { const count = all_features.filter(f => f.type === type).length; const color = get_color(type); container.innerHTML += make_sidebar_btn(type, type, color, count, current_cat === type); }); // Vincular eventos despues de insertar el HTML container.querySelectorAll(".filter-btn").forEach(btn => { btn.addEventListener("click", () => on_filter_cat(btn)); }); } // Boton del sidebar para categorias function make_sidebar_btn(cat, label, color, count, is_active) { const active_class = is_active ? " active" : ""; return ` `; } /* //+------------------------------------------------------------------+ //| Filtros | //+------------------------------------------------------------------+ */ function on_filter_cat(btn) { show_features_view() document.querySelectorAll(".filter-btn").forEach(b => b.classList.remove("active")); btn.classList.add("active"); current_cat = btn.dataset.cat; current_page = 1; render_page(); } function on_search(value) { current_search = value.trim().toLowerCase(); current_page = 1; render_page(); } /* //+------------------------------------------------------------------+ //| Filtrado | //+------------------------------------------------------------------+ */ function get_filtered() { return all_features.filter(f => { const match_cat = current_cat === "all" || f.type === current_cat; const match_search = !current_search || f.name.toLowerCase().includes(current_search) || f.desc.toLowerCase().includes(current_search) || f.type.toLowerCase().includes(current_search); return match_cat && match_search; }); } /* //+------------------------------------------------------------------+ //| Render principal | //+------------------------------------------------------------------+ */ function render_page() { const filtered = get_filtered(); const total_pages = Math.max(1, Math.ceil(filtered.length / FEATURES_PER_PAGE)); const page = Math.min(current_page, total_pages); const start = (page - 1) * FEATURES_PER_PAGE; const page_items = filtered.slice(start, start + FEATURES_PER_PAGE); // Contador topbar document.getElementById("visibleCount").textContent = filtered.length; // Grid const grid = document.getElementById("featuresGrid"); grid.innerHTML = ""; page_items.forEach((f, idx) => grid.appendChild(make_card(f, start + idx))); // Estado vacio const empty = document.getElementById("emptyState"); empty.classList.toggle("show", filtered.length === 0); // Paginacion render_pagination(page, total_pages); } //+------------------------------------------------------------------+ //| Card | //+------------------------------------------------------------------+ function make_card(f, global_idx) { const color = get_color(f.type); const num_str = "#" + String(global_idx + 1).padStart(3, "0"); const param_count = f.params.length; const card = document.createElement("div"); card.className = "feature-card"; card.style.setProperty("--cat-color", color); card.innerHTML = `