import React, { useState } from "react"; import CodeBlock from "@theme/CodeBlock"; import ConfigTabs from "@site/src/components/ConfigTabs"; import TabItem from "@theme/TabItem"; import { marked } from "marked"; import styles from "./styles.module.css"; marked.setOptions({ gfm: true }); /** * @typedef {Object} Model * @property {string} key * @property {string} label * @property {boolean} recommended * @property {string} download Markdown for the "download the model" step. * @property {string} ui Markdown for the Frigate UI configuration step. * @property {string} yaml Raw YAML for the configuration step. */ // Render a markdown string to React nodes. Fenced code blocks become Docusaurus // CodeBlock components (so they get syntax highlighting and a copy button); // everything else is marked-parsed to HTML. function renderBlocks(md, keyPrefix) { if (!md.trim()) return []; const tokens = marked.lexer(md); const nodes = []; let buffer = []; let idx = 0; const flush = () => { if (buffer.length) { buffer.links = tokens.links; nodes.push(
, ); buffer = []; } }; tokens.forEach((token) => { if (token.type === "code") { flush(); const language = (token.lang || "text").split(/\s+/)[0]; nodes.push( {token.text} , ); } else { buffer.push(token); } }); flush(); return nodes; } // marked does not understand Docusaurus admonitions (:::warning ... :::), so // render those blocks ourselves and render everything around them normally. function renderMarkdown(md) { if (!md) return null; const admonition = /:::(\w+)[ \t]*([^\n]*)\n([\s\S]*?)\n:::/g; const nodes = []; let lastIndex = 0; let match; let k = 0; while ((match = admonition.exec(md)) !== null) { nodes.push(...renderBlocks(md.slice(lastIndex, match.index), `seg${k}`)); const [, type, title, body] = match; const heading = (title || type).trim(); nodes.push(
{heading}
{renderBlocks(body, `adm${k}`)}
, ); lastIndex = admonition.lastIndex; k++; } nodes.push(...renderBlocks(md.slice(lastIndex), `seg${k}`)); return nodes; } function Markdown({ children }) { return
{renderMarkdown(children)}
; } function RecommendedBadge() { return Recommended; } /** * @param {{ models: Model[] }} props */ export default function ModelConfigDropdown({ models }) { const [selectedModelIndex, setSelectedModelIndex] = useState(0); const [isOpen, setIsOpen] = useState(false); const selectedModel = models[selectedModelIndex]; const hasChoices = models.length > 1; const handleModelSelect = (index) => { setSelectedModelIndex(index); setIsOpen(false); }; return (

Step 1 — Choose a model

setIsOpen(!isOpen) : undefined} >
{selectedModel.label} {selectedModel.recommended && } {hasChoices && ( {isOpen ? "▲" : "▼"} )}
{isOpen && hasChoices && (
{models.map((model, index) => (
handleModelSelect(index)} > {model.label} {model.recommended && }
))}
)}

Step 2 — Download the model

{selectedModel.download}

Step 3 — Configure the detector

{selectedModel.ui} {selectedModel.yaml}
); }