mirror of
https://github.com/falsycat/ar.falsy.cat.git
synced 2025-09-21 11:21:05 +00:00
deploy: 5cbc22f4a490dadddf2d9d85372b3b3cd53cb4c9
This commit is contained in:
1
js/callouts.7723cac461d613d118ee8bb8216b9838.min.js
vendored
Normal file
1
js/callouts.7723cac461d613d118ee8bb8216b9838.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
const addCollapsibleCallouts=()=>{const e=document.querySelectorAll("blockquote.callout-collapsible");e.forEach(e=>e.addEventListener("click",e=>{e.currentTarget.classList.toggle("callout-collapsed")}))}
|
1
js/clipboard.2913da76d3cb21c5deaa4bae7da38c9f.min.js
vendored
Normal file
1
js/clipboard.2913da76d3cb21c5deaa4bae7da38c9f.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
const svgCopy='<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 010 1.5h-1.5a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-1.5a.75.75 0 011.5 0v1.5A1.75 1.75 0 019.25 16h-7.5A1.75 1.75 0 010 14.25v-7.5z"></path><path fill-rule="evenodd" d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0114.25 11h-7.5A1.75 1.75 0 015 9.25v-7.5zm1.75-.25a.25.25 0 00-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 00.25-.25v-7.5a.25.25 0 00-.25-.25h-7.5z"></path></svg>',svgCheck='<svg aria-hidden="true" height="16" viewBox="0 0 16 16" version="1.1" width="16" data-view-component="true"><path fill-rule="evenodd" fill="rgb(63, 185, 80)" d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"></path></svg>',addCopyButtons=()=>{let e=document.getElementsByClassName("highlight");for(let t=0;t<e.length;t++)try{if(e[t].getElementsByClassName("clipboard-button").length)continue;let s=e[t].getElementsByTagName("code"),o=s[s.length-1];const n=document.createElement("button");n.className="clipboard-button",n.type="button",n.innerHTML=svgCopy,n.ariaLabel="opy the shown code",n.addEventListener("click",()=>{navigator.clipboard.writeText(o.innerText.replace(/\n\n/g,"\n")).then(()=>{n.blur(),n.innerHTML=svgCheck,setTimeout(()=>{n.innerHTML=svgCopy,n.style.borderColor=""},2e3)},e=>n.innerHTML="Error")});let i=e[t].getElementsByClassName("chroma")[0];e[t].insertBefore(n,i)}catch(e){console.debug(e)}}
|
1
js/code-title.ce4a43f09239a9efb48fee342e8ef2df.min.js
vendored
Normal file
1
js/code-title.ce4a43f09239a9efb48fee342e8ef2df.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
function addTitleToCodeBlocks(){const e=document.getElementsByClassName("highlight");for(let t=0;t<e.length;t++)try{if(e[t].title.length){let n=document.createElement("div");if(e[t].getElementsByClassName("code-title").length)continue;n.textContent=e[t].title,n.classList.add("code-title"),e[t].insertBefore(n,e[t].firstChild)}}catch(e){console.debug(e)}}
|
1
js/darkmode.99648ef714ed1ed9c3633d3858f3741d.min.js
vendored
Normal file
1
js/darkmode.99648ef714ed1ed9c3633d3858f3741d.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
const userPref=window.matchMedia("(prefers-color-scheme: light)").matches?"light":"dark",currentTheme=localStorage.getItem("theme")??userPref,syntaxTheme=document.querySelector("#theme-link");currentTheme&&(document.documentElement.setAttribute("saved-theme",currentTheme),syntaxTheme.href=currentTheme==="dark"?"https://falsy.cat/styles/_dark_syntax.bec558461529f0dd343a0b008c343934.min.css":"https://falsy.cat/styles/_light_syntax.86a48a52faebeaaf42158b72922b1c90.min.css");const switchTheme=e=>{e.target.checked?(document.documentElement.setAttribute("saved-theme","dark"),localStorage.setItem("theme","dark"),syntaxTheme.href="https://falsy.cat/styles/_dark_syntax.bec558461529f0dd343a0b008c343934.min.css"):(document.documentElement.setAttribute("saved-theme","light"),localStorage.setItem("theme","light"),syntaxTheme.href="https://falsy.cat/styles/_light_syntax.86a48a52faebeaaf42158b72922b1c90.min.css")};window.addEventListener("DOMContentLoaded",()=>{const e=document.querySelector("#darkmode-toggle");e.addEventListener("change",switchTheme,!1),currentTheme==="dark"&&(e.checked=!0)})
|
1
js/full-text-search.e6e2e0c213187ca0c703d6e2c7a77fcd.min.js
vendored
Normal file
1
js/full-text-search.e6e2e0c213187ca0c703d6e2c7a77fcd.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
(async function(){const t=e=>e.toLowerCase().split(/([^a-z]|[^\x00-\x7F])/),n=new FlexSearch.Document({cache:!0,charset:"latin:extra",optimize:!0,index:[{field:"content",tokenize:"reverse",encode:t},{field:"title",tokenize:"forward",encode:t}]}),{content:e}=await fetchData;for(const[s,t]of Object.entries(e))n.add({id:s,title:t.title,content:removeMarkdown(t.content)});const s=t=>({id:t,url:t,title:e[t].title,content:e[t].content});registerHandlers(o=>{const e=o.target.value,i=n.search(e,[{field:"content",limit:10},{field:"title",limit:5}]),t=t=>{const e=i.filter(e=>e.field===t);return e.length===0?[]:[...e[0].result]},a=new Set([...t("title"),...t("content")]),r=[...a].map(s);displayResults(e,r,!0)})})()
|
279
js/graph.6579af7b10c818dbd2ca038702db0224.js
Normal file
279
js/graph.6579af7b10c818dbd2ca038702db0224.js
Normal file
@@ -0,0 +1,279 @@
|
||||
async function drawGraph(baseUrl, isHome, pathColors, graphConfig) {
|
||||
|
||||
let {
|
||||
depth,
|
||||
enableDrag,
|
||||
enableLegend,
|
||||
enableZoom,
|
||||
opacityScale,
|
||||
scale,
|
||||
repelForce,
|
||||
fontSize } = graphConfig;
|
||||
|
||||
const container = document.getElementById("graph-container")
|
||||
const { index, links, content } = await fetchData
|
||||
|
||||
// Use .pathname to remove hashes / searchParams / text fragments
|
||||
const cleanUrl = window.location.origin + window.location.pathname
|
||||
|
||||
const curPage = cleanUrl.replace(/\/$/g, "").replace(baseUrl, "")
|
||||
|
||||
const parseIdsFromLinks = (links) => [
|
||||
...new Set(links.flatMap((link) => [link.source, link.target])),
|
||||
]
|
||||
|
||||
// Links is mutated by d3. We want to use links later on, so we make a copy and pass that one to d3
|
||||
// Note: shallow cloning does not work because it copies over references from the original array
|
||||
const copyLinks = JSON.parse(JSON.stringify(links))
|
||||
|
||||
const neighbours = new Set()
|
||||
const wl = [curPage || "/", "__SENTINEL"]
|
||||
if (depth >= 0) {
|
||||
while (depth >= 0 && wl.length > 0) {
|
||||
// compute neighbours
|
||||
const cur = wl.shift()
|
||||
if (cur === "__SENTINEL") {
|
||||
depth--
|
||||
wl.push("__SENTINEL")
|
||||
} else {
|
||||
neighbours.add(cur)
|
||||
const outgoing = index.links[cur] || []
|
||||
const incoming = index.backlinks[cur] || []
|
||||
wl.push(...outgoing.map((l) => l.target), ...incoming.map((l) => l.source))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parseIdsFromLinks(copyLinks).forEach((id) => neighbours.add(id))
|
||||
}
|
||||
|
||||
const data = {
|
||||
nodes: [...neighbours].map((id) => ({ id })),
|
||||
links: copyLinks.filter((l) => neighbours.has(l.source) && neighbours.has(l.target)),
|
||||
}
|
||||
|
||||
const color = (d) => {
|
||||
if (d.id === curPage || (d.id === "/" && curPage === "")) {
|
||||
return "var(--g-node-active)"
|
||||
}
|
||||
|
||||
for (const pathColor of pathColors) {
|
||||
const path = Object.keys(pathColor)[0]
|
||||
const colour = pathColor[path]
|
||||
if (d.id.startsWith(path)) {
|
||||
return colour
|
||||
}
|
||||
}
|
||||
|
||||
return "var(--g-node)"
|
||||
}
|
||||
|
||||
const drag = (simulation) => {
|
||||
function dragstarted(event, d) {
|
||||
if (!event.active) simulation.alphaTarget(1).restart()
|
||||
d.fx = d.x
|
||||
d.fy = d.y
|
||||
}
|
||||
|
||||
function dragged(event, d) {
|
||||
d.fx = event.x
|
||||
d.fy = event.y
|
||||
}
|
||||
|
||||
function dragended(event, d) {
|
||||
if (!event.active) simulation.alphaTarget(0)
|
||||
d.fx = null
|
||||
d.fy = null
|
||||
}
|
||||
|
||||
const noop = () => { }
|
||||
return d3
|
||||
.drag()
|
||||
.on("start", enableDrag ? dragstarted : noop)
|
||||
.on("drag", enableDrag ? dragged : noop)
|
||||
.on("end", enableDrag ? dragended : noop)
|
||||
}
|
||||
|
||||
const height = Math.max(container.offsetHeight, isHome ? 500 : 250)
|
||||
const width = container.offsetWidth
|
||||
|
||||
const simulation = d3
|
||||
.forceSimulation(data.nodes)
|
||||
.force("charge", d3.forceManyBody().strength(-100 * repelForce))
|
||||
.force(
|
||||
"link",
|
||||
d3
|
||||
.forceLink(data.links)
|
||||
.id((d) => d.id)
|
||||
.distance(40),
|
||||
)
|
||||
.force("center", d3.forceCenter())
|
||||
|
||||
const svg = d3
|
||||
.select("#graph-container")
|
||||
.append("svg")
|
||||
.attr("width", width)
|
||||
.attr("height", height)
|
||||
.attr('viewBox', [-width / 2 / scale, -height / 2 / scale, width / scale, height / scale])
|
||||
|
||||
if (enableLegend) {
|
||||
const legend = [{ Current: "var(--g-node-active)" }, { Note: "var(--g-node)" }, ...pathColors]
|
||||
legend.forEach((legendEntry, i) => {
|
||||
const key = Object.keys(legendEntry)[0]
|
||||
const colour = legendEntry[key]
|
||||
svg
|
||||
.append("circle")
|
||||
.attr("cx", -width / 2 + 20)
|
||||
.attr("cy", height / 2 - 30 * (i + 1))
|
||||
.attr("r", 6)
|
||||
.style("fill", colour)
|
||||
svg
|
||||
.append("text")
|
||||
.attr("x", -width / 2 + 40)
|
||||
.attr("y", height / 2 - 30 * (i + 1))
|
||||
.text(key)
|
||||
.style("font-size", "15px")
|
||||
.attr("alignment-baseline", "middle")
|
||||
})
|
||||
}
|
||||
|
||||
// draw links between nodes
|
||||
const link = svg
|
||||
.append("g")
|
||||
.selectAll("line")
|
||||
.data(data.links)
|
||||
.join("line")
|
||||
.attr("class", "link")
|
||||
.attr("stroke", "var(--g-link)")
|
||||
.attr("stroke-width", 2)
|
||||
.attr("data-source", (d) => d.source.id)
|
||||
.attr("data-target", (d) => d.target.id)
|
||||
|
||||
// svg groups
|
||||
const graphNode = svg.append("g").selectAll("g").data(data.nodes).enter().append("g")
|
||||
|
||||
// calculate radius
|
||||
const nodeRadius = (d) => {
|
||||
const numOut = index.links[d.id]?.length || 0
|
||||
const numIn = index.backlinks[d.id]?.length || 0
|
||||
return 2 + Math.sqrt(numOut + numIn)
|
||||
}
|
||||
|
||||
// draw individual nodes
|
||||
const node = graphNode
|
||||
.append("circle")
|
||||
.attr("class", "node")
|
||||
.attr("id", (d) => d.id)
|
||||
.attr("r", nodeRadius)
|
||||
.attr("fill", color)
|
||||
.style("cursor", "pointer")
|
||||
.on("click", (_, d) => {
|
||||
// SPA navigation
|
||||
const targ = `${baseUrl}${decodeURI(d.id).replace(/\s+/g, "-")}/`
|
||||
window.Million.navigate(new URL(targ), ".singlePage")
|
||||
plausible("Link Click", {
|
||||
props: {
|
||||
href: targ,
|
||||
broken: false,
|
||||
internal: true,
|
||||
graph: true,
|
||||
}
|
||||
})
|
||||
})
|
||||
.on("mouseover", function(_, d) {
|
||||
d3.selectAll(".node").transition().duration(100).attr("fill", "var(--g-node-inactive)")
|
||||
|
||||
const neighbours = parseIdsFromLinks([
|
||||
...(index.links[d.id] || []),
|
||||
...(index.backlinks[d.id] || []),
|
||||
])
|
||||
const neighbourNodes = d3.selectAll(".node").filter((d) => neighbours.includes(d.id))
|
||||
const currentId = d.id
|
||||
window.Million.prefetch(new URL(`${baseUrl}${decodeURI(d.id).replace(/\s+/g, "-")}/`))
|
||||
const linkNodes = d3
|
||||
.selectAll(".link")
|
||||
.filter((d) => d.source.id === currentId || d.target.id === currentId)
|
||||
|
||||
// highlight neighbour nodes
|
||||
neighbourNodes.transition().duration(200).attr("fill", color)
|
||||
|
||||
// highlight links
|
||||
linkNodes.transition().duration(200).attr("stroke", "var(--g-link-active)")
|
||||
|
||||
const bigFont = fontSize * 1.5
|
||||
|
||||
// show text for self
|
||||
d3.select(this.parentNode)
|
||||
.raise()
|
||||
.select("text")
|
||||
.transition()
|
||||
.duration(200)
|
||||
.attr('opacityOld', d3.select(this.parentNode).select('text').style("opacity"))
|
||||
.style('opacity', 1)
|
||||
.style('font-size', bigFont + 'em')
|
||||
.attr('dy', d => nodeRadius(d) + 20 + 'px') // radius is in px
|
||||
})
|
||||
.on("mouseleave", function(_, d) {
|
||||
d3.selectAll(".node").transition().duration(200).attr("fill", color)
|
||||
|
||||
const currentId = d.id
|
||||
const linkNodes = d3
|
||||
.selectAll(".link")
|
||||
.filter((d) => d.source.id === currentId || d.target.id === currentId)
|
||||
|
||||
linkNodes.transition().duration(200).attr("stroke", "var(--g-link)")
|
||||
|
||||
d3.select(this.parentNode)
|
||||
.select("text")
|
||||
.transition()
|
||||
.duration(200)
|
||||
.style('opacity', d3.select(this.parentNode).select('text').attr("opacityOld"))
|
||||
.style('font-size', fontSize + 'em')
|
||||
.attr('dy', d => nodeRadius(d) + 8 + 'px') // radius is in px
|
||||
})
|
||||
.call(drag(simulation))
|
||||
|
||||
// draw labels
|
||||
const labels = graphNode
|
||||
.append("text")
|
||||
.attr("dx", 0)
|
||||
.attr("dy", (d) => nodeRadius(d) + 8 + "px")
|
||||
.attr("text-anchor", "middle")
|
||||
.text((d) => content[d.id]?.title || (d.id.charAt(1).toUpperCase() + d.id.slice(2)).replace("-", " "))
|
||||
.style('opacity', (opacityScale - 1) / 3.75)
|
||||
.style("pointer-events", "none")
|
||||
.style('font-size', fontSize + 'em')
|
||||
.raise()
|
||||
.call(drag(simulation))
|
||||
|
||||
// set panning
|
||||
|
||||
if (enableZoom) {
|
||||
svg.call(
|
||||
d3
|
||||
.zoom()
|
||||
.extent([
|
||||
[0, 0],
|
||||
[width, height],
|
||||
])
|
||||
.scaleExtent([0.25, 4])
|
||||
.on("zoom", ({ transform }) => {
|
||||
link.attr("transform", transform)
|
||||
node.attr("transform", transform)
|
||||
const scale = transform.k * opacityScale;
|
||||
const scaledOpacity = Math.max((scale - 1) / 3.75, 0)
|
||||
labels.attr("transform", transform).style("opacity", scaledOpacity)
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
// progress the simulation
|
||||
simulation.on("tick", () => {
|
||||
link
|
||||
.attr("x1", (d) => d.source.x)
|
||||
.attr("y1", (d) => d.source.y)
|
||||
.attr("x2", (d) => d.target.x)
|
||||
.attr("y2", (d) => d.target.y)
|
||||
node.attr("cx", (d) => d.x).attr("cy", (d) => d.y)
|
||||
labels.attr("x", (d) => d.x).attr("y", (d) => d.y)
|
||||
})
|
||||
}
|
9
js/popover.aa9bc99c7c38d3ae9538f218f1416adb.min.js
vendored
Normal file
9
js/popover.aa9bc99c7c38d3ae9538f218f1416adb.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
function htmlToElement(e){const t=document.createElement("template");return e=e.trim(),t.innerHTML=e,t.content.firstChild}function initPopover(e,t){const n=e.replace(window.location.origin,"");fetchData.then(({content:e})=>{const s=[...document.getElementsByClassName("internal-link")];s.filter(e=>e.dataset.src||e.dataset.idx&&t).forEach(t=>{let s;if(t.dataset.ctx){const n=e[t.dataset.src],o=`<div class="popover">
|
||||
<h3>${n.title}</h3>
|
||||
<p>${highlight(removeMarkdown(n.content),t.dataset.ctx)}...</p>
|
||||
<p class="meta">${new Date(n.lastmodified).toLocaleDateString()}</p>
|
||||
</div>`;s=htmlToElement(o)}else{const o=e[t.dataset.src.replace(/\/$/g,"").replace(n,"")];if(o){let n=t.href.split("#"),e=removeMarkdown(o.content);if(n.length>1){let t=decodeURIComponent(n[1]).replace(/-/g," "),s=e.toLowerCase().indexOf("<b>"+t+"</b>");e=e.substring(s,e.length)}const i=`<div class="popover">
|
||||
<h3>${o.title}</h3>
|
||||
<p>${e.split(" ",20).join(" ")}...</p>
|
||||
<p class="meta">${new Date(o.lastmodified).toLocaleDateString()}</p>
|
||||
</div>`;s=htmlToElement(i)}}s&&(t.appendChild(s),LATEX_ENABLED&&renderMathInElement(s,{delimiters:[{left:"$$",right:"$$",display:!1},{left:"$",right:"$",display:!1}],throwOnError:!1}),t.addEventListener("mouseover",()=>{window.FloatingUIDOM.computePosition(t,s,{middleware:[window.FloatingUIDOM.offset(10),window.FloatingUIDOM.inline(),window.FloatingUIDOM.shift()]}).then(({x:e,y:t})=>{Object.assign(s.style,{left:`${e}px`,top:`${t}px`})}),s.classList.add("visible"),plausible("Popover Hover",{props:{href:t.dataset.src}})}),t.addEventListener("mouseout",()=>{s.classList.remove("visible")}))})})}
|
1
js/router.d6fe6bd821db9ea97f9aeefae814d8e7.min.js
vendored
Normal file
1
js/router.d6fe6bd821db9ea97f9aeefae814d8e7.min.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
import{apply,navigate,prefetch,router,}from"https://unpkg.com/million@1.11.5/dist/router.mjs";export const attachSPARouting=(e,n)=>{window.Million={apply,navigate,prefetch,router};const t=()=>requestAnimationFrame(n);window.addEventListener("DOMContentLoaded",()=>{apply(t=>e(t)),e(),router(".singlePage"),t()}),window.addEventListener("million:navigate",t)}
|
7
js/util.a0ccf91e1937fe761a74da4946452710.min.js
vendored
Normal file
7
js/util.a0ccf91e1937fe761a74da4946452710.min.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
const removeMarkdown=(n,t={listUnicodeChar:!1,stripListLeaders:!0,gfm:!0,useImgAltText:!1,preserveLinks:!1})=>{let e=n||"";e=e.replace(/^(-\s*?|\*\s*?|_\s*?){3,}\s*$/gm,"");try{t.stripListLeaders&&(t.listUnicodeChar?e=e.replace(/^([\s\t]*)([*\-+]|\d+\.)\s+/gm,t.listUnicodeChar+" $1"):e=e.replace(/^([\s\t]*)([*\-+]|\d+\.)\s+/gm,"$1")),t.gfm&&(e=e.replace(/\n={2,}/g,"\n").replace(/~{3}.*\n/g,"").replace(/~~/g,"").replace(/`{3}.*\n/g,"")),t.preserveLinks&&(e=e.replace(/\[(.*?)\][[(](.*?)[\])]/g,"$1 ($2)")),e=e.replace(/<[^>]*>/g,"").replace(/^[=-]{2,}\s*$/g,"").replace(/\[\^.+?\](: .*?$)?/g,"").replace(/(#{1,6})\s+(.+)\1?/g,"<b>$2</b>").replace(/\s{0,2}\[.*?\]: .*?$/g,"").replace(/!\[(.*?)\][[(].*?[\])]/g,t.useImgAltText?"$1":"").replace(/\[(.*?)\][[(].*?[\])]/g,"<a>$1</a>").replace(/!?\[\[\S[^[\]|]*(?:\|([^[\]]*))?\S\]\]/g,"<a>$1</a>").replace(/^\s{0,3}>\s?/g,"").replace(/(^|\n)\s{0,3}>\s?/g,"\n\n").replace(/^\s{1,2}\[(.*?)\]: (\S+)( ".*?")?\s*$/g,"").replace(/([*_]{1,3})(\S.*?\S?)\1/g,"$2").replace(/([*_]{1,3})(\S.*?\S?)\1/g,"$2").replace(/(`{3,})(.*?)\1/gm,"$2").replace(/`(.+?)`/g,"$1").replace(/\n{2,}/g,"\n\n").replace(/\[![a-zA-Z]+\][-+]? /g,"")}catch(e){return console.error(e),n}return e},highlight=(e,n)=>{const t=20,o=e.indexOf(n);if(o!==-1){const s=t,i=e.substring(0,o).split(" ").slice(-s),a=e.substring(o+n.length,e.length-2).split(" ").slice(0,s);return(i.length===s?`...${i.join(" ")}`:i.join(" "))+`<span class="search-highlight">${n}</span>`+a.join(" ")}const u=n.split(/\s+/).filter(e=>e!==""),s=e.split(/\s+/).filter(e=>e!==""),a=e=>u.some(t=>e.toLowerCase().startsWith(t.toLowerCase())),r=s.map(a);let c=0,l=0;for(let e=0;e<Math.max(r.length-t,0);e++){const s=r.slice(e,e+t),n=s.reduce((e,t)=>e+t,0);n>=c&&(c=n,l=e)}const i=Math.max(l-t,0),d=Math.min(i+2*t,s.length),h=s.slice(i,d).map(e=>a(e)?`<span class="search-highlight">${e}</span>`:e).join(" ").replaceAll('</span> <span class="search-highlight">'," ");return`${i===0?"":"..."}${h}${d===s.length?"":"..."}`},resultToHTML=({url:e,title:t,content:n})=>`<button class="result-card" id="${e}">
|
||||
<h3>${t}</h3>
|
||||
<p>${n}</p>
|
||||
</button>`,redir=(t,e)=>{const n=PRODUCTION&&SEARCH_ENABLED,s=n?"":BASE_URL.replace(/\/$/g,""),o=`${s}${t}#:~:text=${encodeURIComponent(e)}/`;window.Million.navigate(new URL(o),".singlePage"),closeSearch(),plausible("Search",{props:{term:e}})};function openSearch(){const t=document.getElementById("search-bar"),n=document.getElementById("results-container"),e=document.getElementById("search-container");e.style.display==="none"||e.style.display===""?(t.value="",n.innerHTML="",e.style.display="block",t.focus()):e.style.display="none"}function closeSearch(){const e=document.getElementById("search-container");e.style.display="none"}const registerHandlers=n=>{const e=document.getElementById("search-bar"),s=document.getElementById("search-container");let o;e.addEventListener("keyup",e=>{if(e.key==="Enter"){const e=document.getElementsByClassName("result-card")[0];redir(e.id,o)}}),e.addEventListener("input",n),document.addEventListener("keydown",e=>{e.key==="k"&&(e.ctrlKey||e.metaKey)&&(e.preventDefault(),openSearch()),e.key==="Escape"&&(e.preventDefault(),closeSearch())});const t=document.getElementById("search-icon");t.addEventListener("click",e=>{openSearch()}),t.addEventListener("keydown",e=>{openSearch()}),s.addEventListener("click",e=>{closeSearch()}),document.getElementById("search-space").addEventListener("click",e=>{e.stopPropagation()})},displayResults=(e,n,s=!1)=>{const t=document.getElementById("results-container");if(n.length===0)t.innerHTML=`<button class="result-card">
|
||||
<h3>No results.</h3>
|
||||
<p>Try another search term?</p>
|
||||
</button>`;else{t.innerHTML=n.map(t=>s?resultToHTML({url:t.url,title:highlight(t.title,e),content:highlight(removeMarkdown(t.content),e)}):resultToHTML(t)).join("\n"),LATEX_ENABLED&&renderMathInElement(t,{delimiters:[{left:"$$",right:"$$",display:!1},{left:"$",right:"$",display:!1}],throwOnError:!1});const o=[...document.getElementsByClassName("result-card")];o.forEach(t=>{t.onclick=()=>redir(t.id,e)})}}
|
Reference in New Issue
Block a user