Siteβ―Builder
Editing:
play-jsonv2.php
writable 0666
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Ultimate Prompt Playground v4</title> <meta name="viewport" content="width=device-width,initial-scale=1"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"> <style> body { max-width: 900px; margin: 2rem auto; font-family: system-ui, sans-serif; } h1 { text-align: center; margin-bottom: 1.5rem; } .prompt-card { position: relative; background:#fff; border:1px solid #ddd; border-radius:8px; padding:1rem; margin-bottom:1.5rem; } .prompt-text { line-height:1.6; white-space:pre-wrap; } .token { display:inline-block; background:#e8e0ff; color:#5c3bff; padding:.2rem .5rem; border-radius:4px; cursor:pointer; margin:.2rem .2rem .2rem 0; } .token:hover { background:#d4c6ff; } .toolbar { position:absolute; background:#fff; border:1px solid #ccc; border-radius:6px; box-shadow:0 2px 8px rgba(0,0,0,0.1); padding:.6rem; z-index:10; display:flex; flex-direction:column; gap:.5rem; width:220px; } .toolbar label { font-size:.9rem; margin-bottom:.2rem; } .toolbar input[type="text"], .toolbar textarea, .toolbar select { width:100%; padding:.3rem; border:1px solid #999; border-radius:4px; font-size:1rem; } .toolbar textarea { resize:vertical; } .toolbar .checkbox-list { display:flex; flex-direction:column; gap:.3rem; max-height:150px; overflow:auto; } .toolbar .actions { display:flex; justify-content:flex-end; gap:.5rem; } .toolbar button { background:#6c48ff; color:#fff; border:none; padding:.4rem .8rem; border-radius:4px; cursor:pointer; font-size:.9rem; } .ai-btns { margin-top:1rem; display:flex; gap:.6rem; } .ai-btns a { flex:1; text-align:center; background:#6c48ff; color:#fff; padding:.6rem; border-radius:6px; text-decoration:none; font-weight:600; } .ai-btns a.perplexity { background:#1ca7ec; } .ai-btns a.copilot { background:#00c853; color:#173E22; } </style> </head> <body> <h1>Ultimate Prompt Playground v4</h1> <div id="app"></div> <script> (async () => { const SEP = ' β’ '; const RX = /\[(?:([A-DI]?)-)?([^~|\-\]]+)(?:-([^~\]]+))?(?:~([^~]+)~)?\]/g; const data = await fetch('prompts.json').then(r => r.json()); const app = document.getElementById('app'); function positionToolbar(toolbar, tok) { // position toolbar absolutely within its prompt-card container const card = tok.closest('.prompt-card'); const tokRect = tok.getBoundingClientRect(); const cardRect = card.getBoundingClientRect(); // compute coordinates relative to card const top = tokRect.bottom - cardRect.top; const left = tokRect.left - cardRect.left; toolbar.style.top = top + 'px'; toolbar.style.left = left + 'px'; } data.forEach((item, idx) => { const tpl = item.prompt; const meta = [], state = {}; // tokenize const tokenized = tpl.replace(RX, (m, cmd='', lab, ops='', def='') => { const opts = ops.split('|').map(s => s.trim()).filter(Boolean); let initial = def; if (cmd === 'C' && def) initial = def.split(',').map(s => s.trim()).join(SEP); meta.push({ cmd, lab, opts }); state[lab] = initial; return `<span class="token" data-i="${meta.length-1}">${initial}</span>`; }); // build card const card = document.createElement('div'); card.className = 'prompt-card'; card.innerHTML = ` <div class="prompt-text">${tokenized.replace(/\n/g,'<br>')}</div> <div class="ai-btns"> <a class="chatgpt" data-base="https://chatgpt.com/?prompt=">ChatGPT</a> <a class="perplexity" data-base="https://www.perplexity.ai/search?q=">Perplexity</a> <a class="copilot" data-base="https://copilot.microsoft.com/?q=">Copilot</a> </div> `; app.append(card); // toolbar const toolbar = document.createElement('div'); toolbar.className = 'toolbar'; toolbar.style.display = 'none'; card.append(toolbar); // rebuild AI URLs function rebuild() { let out = tpl.replace(RX, (_,__,lab) => state[lab] || ''); card.querySelectorAll('.ai-btns a').forEach(a => { a.href = a.dataset.base + encodeURIComponent(out); }); } rebuild(); // token click card.querySelectorAll('.token').forEach(tok => tok.addEventListener('click', e => { const mi = +tok.dataset.i; const { cmd, lab, opts } = meta[mi]; const cur = state[lab]; toolbar.innerHTML = ''; positionToolbar(toolbar, tok); toolbar.style.display = 'flex'; // label const lbl = document.createElement('label'); lbl.textContent = lab.replace(/_/g,' '); toolbar.append(lbl); // input UI if (cmd === 'A') { const ta = document.createElement('textarea'); ta.rows = 4; ta.value = cur; ta.addEventListener('input', () => { state[lab] = ta.value; tok.textContent = ta.value; rebuild(); }); toolbar.append(ta); } else if (cmd === 'B') { opts.forEach(o => { const labEl = document.createElement('label'); const r = document.createElement('input'); r.type='radio'; r.name=lab; r.value=o; r.checked=(o===cur); r.onchange = () => { state[lab]=o; tok.textContent=o; rebuild(); toolbar.style.display='none'; }; labEl.append(r,' ',o); toolbar.append(labEl); }); } else if (cmd === 'C') { const list = document.createElement('div'); list.className='checkbox-list'; opts.forEach(o => { const labEl = document.createElement('label'); const c = document.createElement('input'); c.type='checkbox'; c.value=o; c.checked = state[lab].split(SEP).includes(o); c.onchange = () => { const sel=[...list.querySelectorAll('input:checked')].map(i=>i.value); state[lab]=sel.join(SEP); tok.textContent=state[lab]; rebuild(); }; labEl.append(c,' ',o); list.append(labEl); }); toolbar.append(list); } else if (cmd === 'D') { const sel = document.createElement('select'); const isNum = opts.every(o=>/^\d+$/.test(o)); const list = isNum ? Array.from({length: Math.max(...opts.map(n=>+n))}, (_,i)=>''+(i+1)) : opts; list.forEach(o => { const op=document.createElement('option'); op.textContent=o; op.value=o; if(o===cur)op.selected=true; sel.append(op); }); sel.onchange = () => { state[lab]=sel.value; tok.textContent=sel.value; rebuild(); toolbar.style.display='none'; }; toolbar.append(sel); } else { const inp = document.createElement('input'); inp.type='text'; inp.value=cur; inp.oninput = () => { state[lab]=inp.value; tok.textContent=inp.value; rebuild(); }; toolbar.append(inp); } // close button const closeDiv = document.createElement('div'); closeDiv.className='actions'; const btn = document.createElement('button'); btn.textContent='Close'; btn.onclick = () => toolbar.style.display='none'; closeDiv.append(btn); toolbar.append(closeDiv); })); }); })(); </script> </body> </html>
Save changes
Create folder
writable 0777
Create
Cancel