/* ============================================================ FitCheck, frontend logic (UI brick) Gathers inputs, calls the /api/advise connector, renders results. The backend currently returns input-aware PLACEHOLDER data; the real engine plugs into the same /api/advise contract later. ============================================================ */ // ---- Inline icon helpers (icons.js loads first) -------------------------- function ic(name) { return (window.ICONS && window.ICONS[name]) || ""; } function hydrate(root) { (root || document).querySelectorAll("[data-ic]").forEach(el => { if (!el.dataset.done) { el.innerHTML = ic(el.dataset.ic); el.dataset.done = "1"; } }); } // ---- Use-case taxonomy: the full realm, not just LLMs -------------------- const USE_CASES = [ { icon: "cat-text", name: "Text & chat", items: [ { id: "chat", icon: "chat", label: "Chatbot / assistant" }, { id: "writing", icon: "writing", label: "Writing & summarising" }, { id: "coding", icon: "coding", label: "Coding help" }, { id: "agents", icon: "agents", label: "Agents & tool use" }, { id: "rag", icon: "rag", label: "Chat with my documents" }, { id: "translate", icon: "translate", label: "Translation" }, ]}, { icon: "cat-vision", name: "See & understand images", items: [ { id: "vlm", icon: "classify", label: "Chat about images (VLM)" }, { id: "detect", icon: "detect", label: "Object detection (YOLO)" }, { id: "segment", icon: "segment", label: "Image segmentation" }, { id: "pose", icon: "pose", label: "Pose / 6-DoF (FoundationPose)" }, { id: "classify",icon: "classify", label: "Image classification" }, { id: "depth", icon: "depth", label: "Depth estimation" }, { id: "ocr", icon: "ocr", label: "Read text from images (OCR)" }, ]}, { icon: "cat-gen", name: "Create images & video", items: [ { id: "imagegen", icon: "imagegen", label: "Generate images (SD / Flux)" }, { id: "inpaint", icon: "inpaint", label: "Edit / inpaint images" }, { id: "upscale", icon: "upscale", label: "Upscale / restore" }, { id: "videogen", icon: "videogen", label: "Generate video" }, { id: "bgremove", icon: "bgremove", label: "Remove backgrounds" }, ]}, { icon: "cat-audio", name: "Audio & speech", items: [ { id: "stt", icon: "stt", label: "Speech to text (Whisper)" }, { id: "tts", icon: "tts", label: "Text to speech / voice" }, { id: "music", icon: "music", label: "Generate music" }, ]}, { icon: "cat-data", name: "Data & search", items: [ { id: "embed", icon: "embed", label: "Semantic search / embeddings" }, { id: "forecast", icon: "forecast", label: "Time-series forecasting" }, { id: "tabular", icon: "tabular", label: "Predict from spreadsheets" }, ]}, { icon: "cat-custom", name: "Something else", items: [ { id: "custom", icon: "custom", label: "Custom: describe it" }, ]}, ]; // ---- GPU lists per provider ---------------------------------------------- const GPUS = { none: [], unsure: [], nvidia: [ "RTX 5090 (32 GB)","RTX 5080 (16 GB)","RTX 5070 Ti (16 GB)","RTX 5070 (12 GB)","RTX 5060 (8 GB)", "RTX 4090 (24 GB)","RTX 4080 (16 GB)","RTX 4070 (12 GB)","RTX 4060 (8 GB)", "RTX 3090 (24 GB)","RTX 3080 (10 GB)","RTX 3070 (8 GB)","RTX 3060 (12 GB)","RTX 3050 (8 GB)", "GTX 1660 (6 GB)","GTX 1650 (4 GB)", ], // Laptop (Mobile) NVIDIA GPUs are different chips: less VRAM and roughly half // the memory bandwidth of the desktop card with the same name (a laptop 5090 // is 24 GB, not 32). Shown when the computer is a laptop. VRAM in the label // feeds the engine; bandwidth comes from data/gpu_specs.json by name. nvidia_laptop: [ "RTX 5090 Laptop (24 GB)","RTX 5080 Laptop (16 GB)","RTX 5070 Ti Laptop (12 GB)", "RTX 5070 Laptop (8 GB)","RTX 5060 Laptop (8 GB)","RTX 5050 Laptop (8 GB)", "RTX 4090 Laptop (16 GB)","RTX 4080 Laptop (12 GB)","RTX 4070 Laptop (8 GB)", "RTX 4060 Laptop (8 GB)","RTX 4050 Laptop (6 GB)", "RTX 3080 Ti Laptop (16 GB)","RTX 3080 Laptop (16 GB)","RTX 3070 Ti Laptop (8 GB)", "RTX 3070 Laptop (8 GB)","RTX 3060 Laptop (6 GB)","RTX 3050 Ti Laptop (4 GB)", "RTX 3050 Laptop (4 GB)","Laptop RTX (not sure of model)", ], amd: ["RX 7900 XTX (24 GB)","RX 7800 XT (16 GB)","RX 7600 (8 GB)","RX 6700 XT (12 GB)","Built-in Radeon"], apple: ["M-series base","M-series Pro","M-series Max","M-series Ultra"], intel: ["Arc A770 (16 GB)","Arc A750 (8 GB)","Arc A380 (6 GB)","Built-in Intel graphics"], }; const $ = (s) => document.querySelector(s); // ---- XSS-safe rendering helpers ------------------------------------------- // Every dynamic value inserted via innerHTML must pass through one of these. // esc(): plain-text escape (user input, model output, backend errors, Hub // metadata). safeUrl(): only http(s) hrefs (blocks javascript:). sanitizeHtml(): // allowlist for the engine's intentionally-rich fields (detail/note/etc) so an // injected