1import React from 'react' 9const styles = baseStyles + markdownStyles + galleryStyles 11const EpTypeLabel = ({epType, epTypeHref}) => { 12 if (!epType) return null 13 const label = `# ${epType}` 15 ? <a href={epTypeHref} className="ep-type" onClick={e => e.stopPropagation()}>{label}</a> 16 : <span className="ep-type">{label}</span> 19const CardHeader = ({command, epType, epTypeHref, helpHref, locStats, cardIdx}) => ( 21 <div className="card-header"> 22 <div className="card-command"> 24 {helpHref ? <a href={helpHref} className="command-link">{command}</a> : <span>{command}</span>} 25 {locStats && <span className="app-loc" data-loc-idx={cardIdx}> # {locStats.appLocStr}</span>} 27 <EpTypeLabel epType={epType} epTypeHref={epTypeHref} /> 29 {locStats?.epTypeLocStr && <div className="eptype-loc" data-loc-idx={cardIdx} data-loc-type="eptype">{locStats.epTypeLocStr}</div>} 34const PkgStats = ({locStats}) => { 35 if (!locStats?.pkgsLine && !locStats?.dpkgsLine) return null 37 <div className="pkg-stats"> 38 {locStats.pkgsLine && <div className="pkgs-line">{locStats.pkgsLine}</div>} 39 {locStats.dpkgsLine && <div className="dpkgs-line">{locStats.dpkgsLine}</div>} 44const Description = ({description}) => ( 45 description && <div className="card-description" dangerouslySetInnerHTML={{__html: description}} /> 48const TileCard = ({cardId, path, href, command, epType, epTypeHref, description, helpHref, locStats, cardIdx}) => ( 49 <div id={cardId} className="card tile-card"> 50 <CardHeader command={command} epType={epType} epTypeHref={epTypeHref} helpHref={helpHref} locStats={locStats} cardIdx={cardIdx} /> 51 <div className="card-body"> 52 <div id={`tile-${path}`} className="tile-container" data-href={href}> 53 <button className="music-toggle" id="music-toggle">♫</button> 55 <Description description={description} /> 57 <PkgStats locStats={locStats} /> 61const ColorCard = ({cardId, href, bgStyle, command, epType, epTypeHref, description, helpHref, locStats, cardIdx}) => ( 62 <div id={cardId} className="card"> 63 <CardHeader command={command} epType={epType} epTypeHref={epTypeHref} helpHref={helpHref} locStats={locStats} cardIdx={cardIdx} /> 64 <div className="card-body"> 65 <a href={href}><div className="color-tile" style={{background: bgStyle}} /></a> 66 <Description description={description} /> 68 <PkgStats locStats={locStats} /> 72const LeanCard = ({cardId, command, epType, epTypeHref, description, helpHref, locStats, cardIdx}) => ( 73 <div id={cardId} className="card"> 74 <CardHeader command={command} epType={epType} epTypeHref={epTypeHref} helpHref={helpHref} locStats={locStats} cardIdx={cardIdx} /> 75 <div className="card-body-inline"> 76 <Description description={description} /> 77 <PkgStats locStats={locStats} /> 82const ImageCard = ({cardId, href, imageUrl, imageAlign, caption, rounds, command, epType, epTypeHref, description, helpHref, locStats, cardIdx}) => ( 83 <div id={cardId} className="card"> 84 <CardHeader command={command} epType={epType} epTypeHref={epTypeHref} helpHref={helpHref} locStats={locStats} cardIdx={cardIdx} /> 85 <div className="card-body"> 86 <div className="image-wrapper"> 87 {rounds ? rounds.map((r, i) => ( 88 <div key={i} className="round-item"> 89 {r.label && <div className="image-caption">{r.label}</div>} 90 {r.image && <a href={href}><img src={r.image} className="image-tile" alt="" /></a>} 93 {caption && <div className="image-caption">{caption}</div>} 94 <a href={href}><img src={imageUrl} className="image-tile" alt="" style={imageAlign ? {objectPosition: imageAlign} : undefined} /></a> 97 <Description description={description} /> 99 <PkgStats locStats={locStats} /> 103const MarkdownSection = ({html}) => html ? ( 104 <div className="markdown-content" dangerouslySetInnerHTML={{__html: html}} /> 107const tileScriptContent = ` 109const container = document.getElementById('tile-threerulecycle') 110const musicBtn = document.getElementById('music-toggle') 112 const tile = await createTile(container, { 114 audioBasePath: 'threerulecycle/', 115 precomputedUrl: 'threerulecycle/precomputed-states.json', 116 onActivate: () => { musicBtn.classList.add('playing') } 118 container.addEventListener('click', (e) => { 119 if (e.target.closest('.music-toggle')) return 120 if (e.metaKey || e.ctrlKey) { 122 window.open(container.dataset.href, '_blank') 125 if (tile.isPlaying()) { 127 window.location.href = container.dataset.href 130 musicBtn.addEventListener('click', () => { 132 musicBtn.classList.toggle('playing', tile.isPlaying()) 137const locModalScriptContent = ` 138const {locDataA = [], epNamesA = [], epPathsA = [], epScopeLegendA = [], srcBaseUrl: srcBase = '', sectionLocH = {}} = window.__locModalData || {} 139const clrHexH = {cyan: '#5fd7d7', magenta: '#d787d7', green: '#5fd7af', gray: '#888', yellow: '#d7af5f'} 140const mkLegendHtml = (epType) => { 141 const scopes = epType && epType !== 'eptNextjsApp' ? epScopeLegendA.filter(s => s.scope !== 'pubfejs') : epScopeLegendA 142 return scopes.map(s => \`<span style="color:\${clrHexH[s.clr]}">\${s.clr}</span>=\${s.scope}\`).join(' ') 144const fmtLoc = (n) => n >= 1000 ? \`# \${(n / 1000).toFixed(1)}k loc\` : \`# \${n}loc\` 145const sumLoc = (filesA) => filesA.reduce((s, f) => s + f.loc, 0) 146const sectionHdr = (label, filesA) => \`<div class="loc-section-header"><span>\${label}</span><span class="loc-section-total"># total \${fmtLoc(sumLoc(filesA)).slice(2)}</span></div>\` 147const renderFile = (f) => \`<div class="loc-modal-file clr-\${f.clr || 'gray'}"><a href="\${srcBase}\${f.path}">\${f.path}</a><span class="loc-cnt">\${fmtLoc(f.loc)}</span></div>\` 148const renderGroupedFiles = (filesA, thisLabel, namesA) => { 149 namesA = namesA || epNamesA 150 const thisF = filesA.filter(f => f.scope === 'this') 151 const someF = filesA.filter(f => f.scope === 'some') 152 const allF = filesA.filter(f => f.scope === 'all') 155 html += sectionHdr(thisLabel || 'ep-specific', thisF) + thisF.map(renderFile).join('') 158 const groups = new Map() 159 for (const f of someF) { 160 const key = (f.globalEpIndices || f.epIndices).join(',') 161 if (!groups.has(key)) groups.set(key, []) 162 groups.get(key).push(f) 164 const sorted = [...groups.entries()].sort((a, b) => { 165 const aIdx = a[1][0].globalEpIndices || a[1][0].epIndices 166 const bIdx = b[1][0].globalEpIndices || b[1][0].epIndices 167 return aIdx.length - bIdx.length 169 for (const [, files] of sorted) { 170 const indices = files[0].globalEpIndices || files[0].epIndices 171 const names = indices.map(i => namesA[i]).filter(Boolean) 172 const label = names.length <= 5 ? names.join(', ') : \`shared by \${names.length} eps\` 173 html += sectionHdr(label, files) + files.map(renderFile).join('') 176 if (allF.length) html += sectionHdr('used-basically-everywhere', allF) + allF.map(renderFile).join('') 179document.body.addEventListener('click', (e) => { 180 const locEl = e.target.closest('[data-loc-key], .app-loc, .eptype-loc') 184 let filesA, thisLabel, namesA, epType 185 const sectionKey = locEl.dataset.locKey 187 const section = sectionLocH[sectionKey] 189 filesA = section.filesA 190 namesA = section.namesA 191 epType = '__section__' 192 } else if (locEl.dataset.locIdx) { 193 const idx = parseInt(locEl.dataset.locIdx, 10) 194 const isEptype = locEl.dataset.locType === 'eptype' 195 const data = locDataA[idx] 196 filesA = isEptype ? data?.epTypeFilesA : data?.appFilesA 198 ? \`\${data.epTypeName} (\${data.epTypeDefPath})\` 199 : \`\${epNamesA[idx]} (\${epPathsA[idx]})\` 200 epType = data?.epTypeName 202 if (!filesA?.length) return 203 document.querySelector('.loc-modal-overlay')?.remove() 204 document.body.classList.add('modal-open') 205 const presentClrs = new Set(filesA.map(f => f.clr)) 206 const legendHtml = epType === '__section__' 207 ? epScopeLegendA.filter(s => presentClrs.has(s.clr)).map(s => \`<span style="color:\${clrHexH[s.clr]}">\${s.clr}</span>=\${s.scope}\`).join(' ') 208 : mkLegendHtml(epType) 209 const epFileObjs = epType === '__section__' ? (sectionLocH[sectionKey]?.epFileObjs || []) : [] 210 const epListHtml = epFileObjs.length ? sectionHdr('entrypoints', epFileObjs) + epFileObjs.map(renderFile).join('') : '' 211 const overlay = document.createElement('div') 212 overlay.className = 'loc-modal-overlay' 213 overlay.innerHTML = \` 214 <div class="loc-modal"> 215 <div class="loc-modal-header"> 216 <span class="loc-legend">\${legendHtml}</span> 217 <button class="loc-modal-close">×</button> 219 <div class="loc-modal-body">\${epListHtml}\${renderGroupedFiles(filesA, thisLabel, namesA)}</div> 222 document.body.appendChild(overlay) 223 const esc = (e) => { if (e.key === 'Escape') close() } 224 const close = () => { overlay.remove(); document.body.classList.remove('modal-open'); document.removeEventListener('keydown', esc) } 225 overlay.querySelector('.loc-modal-close').onclick = close 226 overlay.onclick = (e) => { if (e.target === overlay) close() } 227 document.addEventListener('keydown', esc) 231export const GalleryIndex = ({cards, hasTile, markdownBeforeHtml, markdownAfterHtml, srcBaseUrl, totalLocStr, allAppFilesA, globalEpNamesA, epNamesA, epPathsA, epScopeLegendA, sectionLocH}) => { 232 const locDataA = cards.map(c => c.locStats ? {appFilesA: c.locStats.appFilesA, epTypeFilesA: c.locStats.epTypeFilesA, epTypeName: c.locStats.epTypeName, epTypeDefPath: c.locStats.epTypeDefPath} : null) 236 <meta charSet="UTF-8" /> 237 <meta name="viewport" content={viewportContent} /> 238 <title>peatSymposium</title> 239 <style dangerouslySetInnerHTML={{__html: styles}} /> 242 <div dangerouslySetInnerHTML={{__html: hostBannerHtml}} /> 243 <a href="/" className="home-link">🌳</a> 244 <div className="page-content"> 245 <MarkdownSection html={markdownBeforeHtml} /> 246 <h2>demos / made w peat:</h2> 247 <div className="grid"> 249 const renderCard = (card, i) => 250 card.noTile ? <LeanCard key={i} {...card} cardIdx={i} /> 251 : card.isTile ? <TileCard key={i} {...card} cardIdx={i} /> 252 : card.isImage ? <ImageCard key={i} {...card} cardIdx={i} /> 253 : <ColorCard key={i} {...card} cardIdx={i} /> 255 for (let i = 0; i < cards.length; i++) { 256 const grp = cards[i].collapsedGroup 259 while (i < cards.length && cards[i].collapsedGroup === grp) i++ 261 for (let j = start; j < i; j++) grpCards.push({card: cards[j], idx: j}) 263 <details key={`grp-${start}`} className="gallery-group"> 264 <summary>{grp} <span className="gallery-group-cnt">({grpCards.length})</span></summary> 265 <div className="gallery-group-body"> 266 {grpCards.map(({card, idx}) => renderCard(card, idx))} 272 out.push(renderCard(cards[i], i)) 278 <MarkdownSection html={markdownAfterHtml} /> 280 <script dangerouslySetInnerHTML={{__html: `window.__locModalData = ${JSON.stringify({locDataA, epNamesA, epPathsA, epScopeLegendA, srcBaseUrl, sectionLocH})}`}} /> 281 <script dangerouslySetInnerHTML={{__html: locModalScriptContent}} /> 282 {hasTile && <script type="module" dangerouslySetInnerHTML={{__html: tileScriptContent}} />} 283 <script type="module" src="./cheetaNekoAI.js" /> 284 <script type="module" dangerouslySetInnerHTML={{__html: beHereNowShadowScript}} /> 285 <script dangerouslySetInnerHTML={{__html: hamsaFlutterScript}} />