{"version":3,"file":"render-helpers.d.ts","sourceRoot":"","sources":["../../../src/tui/render-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAsBvD,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1F,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,MAAM,GACX,CAAC,EAAE,CAeL;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAKxE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAU9E;AAED,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAInD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAKrE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAU9E","sourcesContent":["import type { Theme } from \"@lpb-work/pi-coding-agent\";\nimport { truncateToWidth, visibleWidth } from \"@lpb-work/pi-tui\";\n\nfunction fuzzyScore(query: string, text: string): number {\n\tconst lq = query.toLowerCase();\n\tconst lt = text.toLowerCase();\n\tif (lt.includes(lq)) return 100 + (lq.length / lt.length) * 50;\n\tlet score = 0;\n\tlet qi = 0;\n\tlet consecutive = 0;\n\tfor (let i = 0; i < lt.length && qi < lq.length; i++) {\n\t\tif (lt[i] === lq[qi]) {\n\t\t\tscore += 10 + consecutive;\n\t\t\tconsecutive += 5;\n\t\t\tqi++;\n\t\t} else {\n\t\t\tconsecutive = 0;\n\t\t}\n\t}\n\treturn qi === lq.length ? score : 0;\n}\n\nexport function fuzzyFilter<T extends { name: string; description: string; model?: string }>(\n\titems: T[],\n\tquery: string,\n): T[] {\n\tconst q = query.trim();\n\tif (!q) return items;\n\treturn items\n\t\t.map((item) => ({\n\t\t\titem,\n\t\t\tscore: Math.max(\n\t\t\t\tfuzzyScore(q, item.name),\n\t\t\t\tfuzzyScore(q, item.description) * 0.8,\n\t\t\t\tfuzzyScore(q, item.model ?? \"\") * 0.6,\n\t\t\t),\n\t\t}))\n\t\t.filter((x) => x.score > 0)\n\t\t.sort((a, b) => b.score - a.score)\n\t\t.map((x) => x.item);\n}\n\nexport function pad(s: string, len: number): string {\n\tconst vis = visibleWidth(s);\n\treturn s + \" \".repeat(Math.max(0, len - vis));\n}\n\nexport function row(content: string, width: number, theme: Theme): string {\n\tconst innerW = width - 2;\n\tconst singleLine = content.replace(/[\\r\\n]+/g, \" \").replace(/\\t/g, \"  \");\n\tconst clipped = truncateToWidth(singleLine, innerW);\n\treturn theme.fg(\"border\", \"│\") + pad(clipped, innerW) + theme.fg(\"border\", \"│\");\n}\n\nexport function renderHeader(text: string, width: number, theme: Theme): string {\n\tconst innerW = width - 2;\n\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\tconst padLeft = Math.floor(padLen / 2);\n\tconst padRight = padLen - padLeft;\n\treturn (\n\t\ttheme.fg(\"border\", `╭${\"─\".repeat(padLeft)}`) +\n\t\ttheme.fg(\"accent\", text) +\n\t\ttheme.fg(\"border\", `${\"─\".repeat(padRight)}╮`)\n\t);\n}\n\nexport function formatPath(filePath: string): string {\n\tconst home = process.env.HOME;\n\tif (home && filePath.startsWith(home)) return `~${filePath.slice(home.length)}`;\n\treturn filePath;\n}\n\nexport function formatScrollInfo(above: number, below: number): string {\n\tlet info = \"\";\n\tif (above > 0) info += `↑ ${above} more`;\n\tif (below > 0) info += `${info ? \"  \" : \"\"}↓ ${below} more`;\n\treturn info;\n}\n\nexport function renderFooter(text: string, width: number, theme: Theme): string {\n\tconst innerW = width - 2;\n\tconst padLen = Math.max(0, innerW - visibleWidth(text));\n\tconst padLeft = Math.floor(padLen / 2);\n\tconst padRight = padLen - padLeft;\n\treturn (\n\t\ttheme.fg(\"border\", `╰${\"─\".repeat(padLeft)}`) +\n\t\ttheme.fg(\"dim\", text) +\n\t\ttheme.fg(\"border\", `${\"─\".repeat(padRight)}╯`)\n\t);\n}\n"]}