SOURCE / PINNED RELEASE
Made of little things.
Profile
- Release
- 1c7fc467116f…
- Author-recorded commit
- Not provided
- License
- Check the original source
The hash-verified playable HTML, which may contain bundled or minified code. This view does not execute it.
<!doctype html>
<html lang="en">
<head><meta name="description" content="Look up any Nostr profile and inspect its kind-0 metadata, relay list, and cashu info">
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Profile</title>
<script type="module" crossorigin>function me(){const e=new Map;function t(a,o){if(e.has(a))throw new Error(`NAP domain "${a}" is already registered`);e.set(a,o)}function n(a){const o=a.type.indexOf(".");if(o<=0)return!1;const i=a.type.slice(0,o),u=e.get(i);return u?(u(a),!0):!1}function r(){return Array.from(e.keys())}return{registerNap:t,dispatch:n,getRegisteredDomains:r}}var pe=me(),fe=pe.registerNap,he="theme";function Y(){var t;const e=window;if(!((t=e.napplet)!=null&&t.theme))throw new Error("window.napplet.theme is unavailable -- runtime did not inject this domain");return e.napplet.theme}function ye(){return Y().get()}function ge(e){return Y().onChanged(e)}fe(he,e=>{});function we(){const e=window;if(!e.napplet)throw new Error("window.napplet is unavailable -- runtime did not inject the napplet namespace");return e.napplet}function s(e){const n=we()[e];if(!n)throw new Error(`window.napplet.${String(e)} is unavailable -- runtime did not inject this domain`);return n}var be={emit(e,t,n){s("inc").emit(e,t,n)},on(e,t){return s("inc").on(e,t)}},k={getItem(e){return s("storage").getItem(e)},setItem(e,t){return s("storage").setItem(e,t)},removeItem(e){return s("storage").removeItem(e)},keys(){return s("storage").keys()},instance:{getItem(e){return s("storage").instance.getItem(e)},setItem(e,t){return s("storage").instance.setItem(e,t)},removeItem(e){return s("storage").instance.removeItem(e)},keys(){return s("storage").instance.keys()}}},P={getPublicKey(){return s("identity").getPublicKey()},onChanged(e){return s("identity").onChanged(e)},getRelays(){return s("identity").getRelays()},getProfile(){return s("identity").getProfile()},getFollows(){return s("identity").getFollows()},getList(e){return s("identity").getList(e)},getZaps(){return s("identity").getZaps()},getMutes(){return s("identity").getMutes()},getBlocked(){return s("identity").getBlocked()},getBadges(){return s("identity").getBadges()}},Z={info(){return s("resource").info()},bytes(e,t){return s("resource").bytes(e,t)},bytesMany(e,t){return s("resource").bytesMany(e,t)},bytesAsObjectURL(e){return s("resource").bytesAsObjectURL(e)}},V={getEvent(e,t){return s("outbox").getEvent(e,t)},query(e,t){return s("outbox").query(e,t)},subscribe(e,t){return s("outbox").subscribe(e,t)},publish(e,t){return s("outbox").publish(e,t)},resolveRelays(e){return s("outbox").resolveRelays(e)}},M={invoke(e){return s("intent").invoke(e)},open(e,t,n){return s("intent").open(e,t,n)},available(e){return s("intent").available(e)},handlers(){return s("intent").handlers()},onChanged(e){return s("intent").onChanged(e)}},ve={open(e,t){return s("link").open(e,t)}},S={encodeNip19(e){return s("common").encodeNip19(e)},decodeNip19(e){return s("common").decodeNip19(e)},getProfile(e){return s("common").getProfile(e)},follows(){return s("common").follows()},follow(...e){return s("common").follow(...e)},unfollow(...e){return s("common").unfollow(...e)},react(e,t,n){return s("common").react(e,t,n)},report(e,t,n){return s("common").report(e,t,n)}};const l=e=>{var t;return!!((t=window.napplet)!=null&&t[e])},Q="profile:index",T="selected",Ce=500,K=50,Ee=100,f=document.getElementById("lookup-input"),C=document.getElementById("suggestions"),I=document.getElementById("update-btn"),A=document.getElementById("feed-btn"),ee=document.getElementById("status"),p=document.getElementById("profile");let m=null,g=null,x=0;const h=new Map;let v=new Set,_=[];const w=e=>{ee.textContent=e},D=()=>{ee.textContent=""};function q(e){const t=document.documentElement;t.style.setProperty("--bg",e.colors.background),t.style.setProperty("--text",e.colors.text),t.style.setProperty("--primary",e.colors.primary)}function ke(){l("theme")&&(ye().then(q).catch(()=>{}),ge(q))}let $;function te(e,t){if(m){if(e.pubkey===m)return-1;if(t.pubkey===m)return 1}const n=e.viewedAt||0,r=t.viewedAt||0;if(n!==r)return r-n;const a=v.has(e.pubkey)?1:0,o=v.has(t.pubkey)?1:0;return a!==o?o-a:J(e).localeCompare(J(t))}function ne(){l("storage")&&(window.clearTimeout($),$=window.setTimeout(()=>{const e=[...h.values()].sort(te).slice(0,Ce);k.setItem(Q,JSON.stringify(e)).catch(()=>{})},800))}async function Ne(){if(l("storage"))try{const e=await k.getItem(Q);if(!e)return;const t=JSON.parse(e);if(!Array.isArray(t))return;for(const n of t)n&&typeof n.pubkey=="string"&&h.set(n.pubkey,n)}catch{}}function F(e){if(!l("storage"))return;(e?k.instance.setItem(T,e):k.instance.removeItem(T)).catch(()=>{})}function re(e,t,n){const r=(t==null?void 0:t.display_name)||(t==null?void 0:t.name)||"";return{pubkey:e,name:r,handle:t!=null&&t.name&&t.name!==r?t.name:"",picture:(t==null?void 0:t.picture)||"",nip05:(t==null?void 0:t.nip05)||"",createdAt:n||0,viewedAt:0}}function O(e){if(!e)return null;try{return JSON.parse(e.content)}catch{return null}}function ae(e){let t=!1;for(const n of e){if(n.kind!==0||!n.pubkey)continue;const r=h.get(n.pubkey);if(r&&(r.createdAt||0)>=(n.created_at||0))continue;const a=re(n.pubkey,O(n),n.created_at);a.viewedAt=(r==null?void 0:r.viewedAt)||0,h.set(n.pubkey,a),t=!0}return t&&ne(),t}function xe(e,t){const n=h.get(e),r=re(e,t,(n==null?void 0:n.createdAt)||0);h.set(e,{...r,name:r.name||(n==null?void 0:n.name)||"",handle:r.handle||(n==null?void 0:n.handle)||"",picture:r.picture||(n==null?void 0:n.picture)||"",nip05:r.nip05||(n==null?void 0:n.nip05)||"",viewedAt:Date.now()}),ne()}async function Ie(){const e=[...v].filter(t=>!h.has(t));for(let t=0;t<e.length;t+=K){const n=e.slice(t,t+K);try{const r=await V.query([{kinds:[0],authors:n}],{authors:n,timeoutMs:8e3});ae(r.events.map(a=>a.event))&&j()}catch{}}}const oe=/^[0-9a-f]{64}$/i;async function H(e){var u;if(!l("resource"))throw new Error("nip05 lookup needs the resource domain");const[t,n]=e.split("@");if(!n)throw new Error("invalid nip05 address");const r=`https://${n}/.well-known/nostr.json?name=${encodeURIComponent(t)}`,a=await Z.bytes(r),i=(u=JSON.parse(await a.text()).names)==null?void 0:u[t];if(!i||!oe.test(i))throw new Error("nip05 name not found");return i.toLowerCase()}async function se(e){let t=String(e||"").trim();if(!t)throw new Error("empty input");if(t.startsWith("nostr:")&&(t=t.slice(6)),oe.test(t))return t.toLowerCase();if(/^(npub|nprofile)1/i.test(t)){if(!l("common"))throw new Error("nip-19 decoding unavailable (paste a hex pubkey)");const n=await S.decodeNip19(t),r=n.pubkey||n.hex;if(!n.ok||!r)throw new Error(n.error||"could not decode identifier");return r.toLowerCase()}if(t.includes("@"))return H(t);if(/^[a-z0-9-]+\.[a-z0-9.-]+$/i.test(t))return H(`_@${t}`);throw new Error("unrecognized identifier")}function Le(e){if(!e)return[];const t=[];for(const n of e.tags)if(n[0]==="r"&&n[1]){const r=n[2];t.push({url:n[1],read:!r||r==="read",write:!r||r==="write"})}return t}function Se(e){if(!e)return null;const t={p2pkPubkey:null,mints:[],relays:[]};for(const n of e.tags)n[0]==="pubkey"&&n[1]&&(t.p2pkPubkey=n[1]),n[0]==="mint"&&n[1]&&t.mints.push({url:n[1],unit:n[2]}),n[0]==="relay"&&n[1]&&t.relays.push(n[1]);return t}async function Ae(e){const t=await V.query([{authors:[e],kinds:[0,3,10002,10019]}],{authors:[e],timeoutMs:6e3}),n=new Map;for(const d of t.events){const y=d.event;if(y.pubkey!==e)continue;const c=n.get(y.kind);(!c||y.created_at>c.created_at)&&n.set(y.kind,y)}if(!n.size&&t.error)throw new Error(t.error);const r=n.get(0)??null,a=n.get(3)??null,o=n.get(10002)??null,i=n.get(10019)??null,u=O(r);return ae(r?[r]:[]),{pubkey:e,metadata:u,relays:Le(o),cashu:Se(i),followsCount:a?a.tags.filter(d=>d[0]==="p"&&d[1]).length:null,metadataCreatedAt:(r==null?void 0:r.created_at)??null,relaysCreatedAt:(o==null?void 0:o.created_at)??null,cashuCreatedAt:(i==null?void 0:i.created_at)??null,hasMetadata:!!u,hasRelays:!!o,hasCashu:!!i,partial:!1}}function ie(e,t){if(!t)return!0;const n=t.toLowerCase();return[e.pubkey,e.name,e.handle,e.nip05].filter(Boolean).some(r=>String(r).toLowerCase().includes(n))}function J(e){return(e.name||"").toLowerCase()}function Re(){const e=f.value.trim(),t=[...h.values()],n=e?t.filter(r=>ie(r,e)):t.filter(r=>(r.viewedAt||0)>0||r.pubkey===m);return n.sort(te),n.slice(0,Ee)}function Pe(e){return(e.name||e.handle||e.nip05||e.pubkey).slice(0,2)}function B(){C.innerHTML="";for(const e of Re()){const t=document.createElement("div");t.className="suggestion";const n=document.createElement("div");n.className="sugg-avatar",n.textContent=Pe(e),t.appendChild(n);const r=document.createElement("div");r.className="sugg-text";const a=document.createElement("span");a.className="sugg-name",a.textContent=e.name||"(no name)";const o=document.createElement("span");if(o.className="sugg-sub",o.textContent=e.nip05||e.pubkey.slice(0,16)+"…",r.append(a,o),t.appendChild(r),e.pubkey===m){const i=document.createElement("span");i.className="sugg-me",i.textContent="me",t.appendChild(i)}t.addEventListener("mousedown",i=>{i.preventDefault(),f.value="",N(),b(e.pubkey)}),C.appendChild(t)}}function j(){C.hidden||B()}function ce(){B(),C.hidden=!1}function N(){C.hidden=!0}function ue(){for(const e of _)URL.revokeObjectURL(e);_=[]}function z(e,t,n){if(!l("resource")){n();return}Z.bytes(t).then(r=>{const a=URL.createObjectURL(r);_.push(a),e.src=a}).catch(n)}function le(e,t){if(l("link")){const r=document.createElement("button");return r.type="button",r.className="link-btn",r.textContent=e,r.addEventListener("click",()=>{ve.open(e,{label:t}).catch(()=>w("could not open link"))}),r}const n=document.createElement("code");return n.textContent=e,n}function R(e){const t=document.createElement("details");e.open&&(t.open=!0);const n=document.createElement("summary"),r=document.createElement("span");if(r.textContent=e.title+(e.missing?" — not found":""),n.appendChild(r),e.dateText){const o=document.createElement("span");o.className="summary-date",o.textContent=e.dateText,n.appendChild(o)}t.appendChild(n);const a=document.createElement("div");return a.className="details-body",t.appendChild(a),{det:t,body:a}}function U(e){return e?new Date(e*1e3).toLocaleString():null}function de(e,t){const n=document.createElement("dt");n.textContent=e;const r=document.createElement("dd");return/^https?:\/\//i.test(t)?r.appendChild(le(t,e)):r.textContent=t,[n,r]}function L(e,t,n){const r=document.createElement("dt");r.textContent=t;const a=document.createElement("dd"),o=document.createElement("code");o.textContent=n,a.appendChild(o),e.append(r,a)}function X(e,t,n){const r=document.createElement("dt");r.textContent=t;const a=document.createElement("dd"),o=document.createElement("ul");o.className="flat";for(const i of n){const u=document.createElement("li"),d=document.createElement("code");d.textContent=i,u.appendChild(d),o.appendChild(u)}a.appendChild(o),e.append(r,a)}async function Me(e){const{det:t,body:n}=R({title:"Info",dateText:new Date().toLocaleString(),open:!0}),r=document.createElement("dl");if(r.className="fields",l("common"))try{const a=await S.encodeNip19({type:"npub",hex:e.pubkey});a.ok&&a.value&&L(r,"npub",a.value)}catch{}if(L(r,"pubkey",e.pubkey),l("common"))try{const a=e.relays.filter(i=>i.write).map(i=>i.url),o=await S.encodeNip19({type:"nprofile",pubkey:e.pubkey,relays:a});o.ok&&o.value&&L(r,"nprofile",o.value)}catch{}if(e.followsCount!=null){const[a,o]=de("follows",String(e.followsCount));r.append(a,o)}return n.appendChild(r),t}function Te(e){const{det:t,body:n}=R({title:"Metadata (kind-0)",dateText:U(e.metadataCreatedAt),open:!0,missing:!e.hasMetadata}),r=e.metadata;if(!r)return t;if(r.banner){const c=document.createElement("img");c.className="banner",z(c,r.banner,()=>c.remove()),t.insertBefore(c,n)}const a=document.createElement("div");a.className="header-row";const o=document.createElement("div");if(o.className="avatar",a.appendChild(o),r.picture){const c=document.createElement("img");c.className="avatar",z(c,r.picture,()=>c.remove()),c.addEventListener("load",()=>o.replaceWith(c))}const i=document.createElement("div");i.className="name-block";const u=document.createElement("h2");if(u.textContent=r.display_name||r.name||"(no name)",i.appendChild(u),r.name&&r.display_name&&r.name!==r.display_name){const c=document.createElement("div");c.className="handle",c.textContent="@"+r.name,i.appendChild(c)}if(r.nip05){const c=document.createElement("div");c.className="nip05",c.textContent=r.nip05,i.appendChild(c)}if(r.lud16){const c=document.createElement("div");c.className="lud16",c.textContent=r.lud16,i.appendChild(c)}if(r.website&&typeof r.website=="string"){const c=document.createElement("div");c.className="website",c.appendChild(le(r.website,"Open website")),i.appendChild(c)}if(r.about){const c=document.createElement("p");c.className="about",c.textContent=String(r.about),i.appendChild(c)}a.appendChild(i),t.insertBefore(a,n);const d=document.createElement("dl");d.className="fields";const y=new Set(["name","display_name","picture","banner","about","nip05","lud16","website"]);for(const[c,E]of Object.entries(r))y.has(c)||E==null||E===""||d.append(...de(c,typeof E=="string"?E:JSON.stringify(E)));return d.childNodes.length&&n.appendChild(d),t}function _e(e){const{det:t,body:n}=R({title:"Relays (kind-10002)",dateText:U(e.relaysCreatedAt),missing:!e.hasRelays});if(!e.relays.length)return t;const r=document.createElement("ul");r.className="flat";for(const a of e.relays){const o=document.createElement("li"),i=document.createElement("code");if(i.textContent=a.url,o.appendChild(i),a.read){const u=document.createElement("span");u.className="badge read",u.textContent="read",o.appendChild(u)}if(a.write){const u=document.createElement("span");u.className="badge write",u.textContent="write",o.appendChild(u)}r.appendChild(o)}return n.appendChild(r),t}function De(e){const{det:t,body:n}=R({title:"Cashu (kind-10019)",dateText:U(e.cashuCreatedAt),missing:!e.hasCashu});if(!e.cashu)return t;const r=document.createElement("dl");return r.className="fields",e.cashu.p2pkPubkey&&L(r,"p2pk",e.cashu.p2pkPubkey),e.cashu.mints.length&&X(r,"mints",e.cashu.mints.map(a=>a.url+(a.unit?` (${a.unit})`:""))),e.cashu.relays.length&&X(r,"relays",e.cashu.relays),r.childNodes.length&&n.appendChild(r),t}async function G(e){ue();const t=await Me(e);p.innerHTML="",p.appendChild(t),p.appendChild(Te(e)),p.appendChild(_e(e)),p.appendChild(De(e))}async function b(e){g=e;const t=++x;if(I.disabled=!e,A.disabled=!e,!e){ue(),p.innerHTML="";const r=document.createElement("p");r.className="empty",r.textContent="no profile selected",p.appendChild(r),F(null);return}F(e),D(),p.innerHTML='<p class="empty">loading…</p>';let n=!1;l("common")&&S.getProfile(e).then(r=>{var i;if(x!==t||n)return;const a=(i=r.result)==null?void 0:i.event,o=a?O(a):null;!r.ok||!o||G({pubkey:e,metadata:o,relays:[],cashu:null,followsCount:null,metadataCreatedAt:(a==null?void 0:a.created_at)??null,relaysCreatedAt:null,cashuCreatedAt:null,hasMetadata:!0,hasRelays:!1,hasCashu:!1,partial:!0})}).catch(()=>{});try{const r=await Ae(e);if(x!==t)return;n=!0,await G(r),xe(e,r.metadata),j()}catch(r){if(x!==t)return;w(r instanceof Error?r.message:String(r)),p.innerHTML=""}}async function Oe(){const e=f.value.trim();if(!e)return;const t=[...h.values()].filter(n=>ie(n,e));if(t.length===1&&e.length>1){f.value="",N(),await b(t[0].pubkey);return}try{D();const n=await se(e);f.value="",N(),await b(n)}catch(n){w(n instanceof Error?n.message:String(n))}}f.addEventListener("focus",ce);f.addEventListener("input",()=>{C.hidden?ce():B()});f.addEventListener("blur",()=>setTimeout(N,150));f.addEventListener("keydown",e=>{e.key==="Escape"&&N(),e.key==="Enter"&&(e.preventDefault(),Oe())});I.addEventListener("click",async()=>{if(g){I.disabled=!0,D();try{await b(g)}finally{I.disabled=!g}}});function Be(){if(l("intent")){M.available("feed").then(e=>{A.hidden=!e.available}).catch(()=>{});try{M.onChanged(e=>{e.archetype==="feed"&&(A.hidden=!e.available)})}catch{}}}A.addEventListener("click",()=>{g&&M.open("feed",{pubkey:g}).then(e=>{(!e.ok||!e.handled)&&w(e.error||"no feed napplet handled the request")}).catch(e=>w(`feed intent: ${e instanceof Error?e.message:e}`))});function je(){l("inc")&&be.on("profile:open",e=>{let t="";if(e&&typeof e=="object"){const n=e;t=typeof n.pubkey=="string"?n.pubkey:typeof n.npub=="string"?n.npub:""}else if(typeof e=="string")try{const n=JSON.parse(e);t=typeof(n==null?void 0:n.pubkey)=="string"?n.pubkey:e}catch{t=e}t&&se(t).then(n=>b(n)).catch(n=>w(n instanceof Error?n.message:String(n)))})}async function W(){if(!l("identity")||!m){v=new Set;return}try{v=new Set(await P.getFollows())}catch{v=new Set}}async function Ue(){if(ke(),je(),Be(),await Ne(),l("identity")){try{m=await P.getPublicKey()||null}catch{m=null}P.onChanged(n=>{m=n||null,W().then(()=>{j(),!g&&m&&b(m)})}),await W()}let e=null;if(l("storage"))try{e=await k.instance.getItem(T)}catch{e=null}const t=e||m;t?await b(t):p.innerHTML='<p class="empty">Click the input to see saved profiles, or paste an identifier.</p>',Ie()}Ue().catch(e=>w(e instanceof Error?e.message:String(e)));</script>
<style rel="stylesheet" crossorigin>:root{--bg: #ffffff;--text: #111111;--primary: #3b82f6;color-scheme:light dark}@media(prefers-color-scheme:dark){:root{--bg: #1b1b1f;--text: #ececec;color-scheme:dark}}:root{--border: color-mix(in srgb, var(--text) 25%, transparent);--border-soft: color-mix(in srgb, var(--text) 10%, transparent);--hover: color-mix(in srgb, var(--text) 10%, transparent);--placeholder: color-mix(in srgb, var(--text) 12%, transparent)}html,body{margin:0;height:100%;font-family:system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text)}body{display:flex;flex-direction:column}.bar{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;padding:.5rem .75rem;border-bottom:1px solid var(--border-soft)}.input-wrap{position:relative;flex:1;min-width:min(100%,12rem)}#lookup-input{width:100%;box-sizing:border-box;padding:.4rem .6rem;font:inherit;font-size:.875rem;border:1px solid var(--border);border-radius:6px;background:transparent;color:inherit}#suggestions{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:10;background:var(--bg);color:inherit;border:1px solid var(--border);border-radius:6px;box-shadow:0 6px 20px #0000002e;max-height:min(320px,55vh);overflow-y:auto}#suggestions:empty:after{content:"no recent profiles — type to search";display:block;padding:.5rem .6rem;font-size:.8rem;opacity:.6}.suggestion{display:flex;align-items:center;gap:.6rem;padding:.4rem .6rem;cursor:pointer;font-size:.85rem}.suggestion:hover{background:var(--hover)}.sugg-avatar{width:24px;height:24px;border-radius:50%;background:var(--placeholder);color:var(--text);flex-shrink:0;display:flex;align-items:center;justify-content:center;font-size:.7rem;font-weight:600;text-transform:uppercase}.sugg-text{flex:1;min-width:0;overflow:hidden}.sugg-name{display:block;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sugg-sub{display:block;font-family:ui-monospace,monospace;font-size:.72rem;opacity:.55;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sugg-me{background:var(--hover);border-radius:4px;padding:0 .35rem;font-size:.7rem;opacity:.75}button{padding:.4rem .9rem;font:inherit;font-size:.85rem;border:1px solid var(--border);border-radius:6px;background:transparent;color:inherit;cursor:pointer;flex-shrink:0}button:disabled{opacity:.5;cursor:default}#status{position:sticky;bottom:0;padding:.45rem .85rem;font-size:.75rem;font-family:ui-monospace,monospace;background:color-mix(in srgb,var(--bg) 88%,#e33);color:#c33;border-top:1px solid color-mix(in srgb,#c33 40%,transparent);z-index:10}#status:empty{display:none}main{flex:1;overflow-y:auto;width:100%;max-width:720px;margin:0 auto;box-sizing:border-box}.empty{padding:2rem;text-align:center;opacity:.6;font-size:.9rem}.banner{width:100%;max-height:160px;object-fit:cover;display:block}.header-row{display:flex;flex-wrap:wrap;align-items:flex-start;gap:1rem;padding:1rem 1rem .5rem}.avatar{width:clamp(56px,18vw,110px);flex-shrink:0;background:var(--placeholder);border-radius:4px}img.avatar{height:auto;display:block;object-fit:cover}div.avatar{aspect-ratio:1}.name-block{flex:1;min-width:min(100%,12rem)}h2{margin:0;font-size:1.2rem;line-height:1.2;overflow-wrap:anywhere}.handle{opacity:.65;font-size:.85rem;margin-top:.15rem;overflow-wrap:anywhere}.nip05{margin-top:.25rem;font-size:.8rem;font-family:ui-monospace,monospace;opacity:.75;overflow-wrap:anywhere}.lud16,.website{margin-top:.25rem;font-size:.8rem;overflow-wrap:anywhere}.about{margin:.5rem 0 0;line-height:1.4;white-space:pre-wrap;font-size:.9rem;overflow-wrap:anywhere}.link-btn{display:inline;padding:0;border:none;border-radius:0;background:none;color:var(--primary);text-decoration:underline;cursor:pointer;font-size:inherit;overflow-wrap:anywhere;text-align:left}.fields{margin:0;display:grid;grid-template-columns:auto 1fr;gap:.3rem .75rem;font-size:.82rem}.fields dt{margin:0;opacity:.55;text-transform:lowercase;font-family:ui-monospace,monospace;font-size:.78rem}.fields dd{margin:0;word-break:break-all;min-width:0}.fields dd code{font-family:ui-monospace,monospace;font-size:.78rem}details{border-top:1px solid var(--border-soft)}details summary{display:flex;align-items:baseline;gap:.5rem;padding:.6rem 1rem;cursor:pointer;font-size:.85rem;list-style:none;-webkit-user-select:none;user-select:none}details summary::-webkit-details-marker{display:none}details summary:before{content:"▸";opacity:.5;font-size:.7rem}details[open] summary:before{content:"▾"}details summary .summary-date{margin-left:auto;font-size:.7rem;opacity:.55;font-family:ui-monospace,monospace;flex-shrink:0}details .details-body{padding:0 1rem .75rem}.empty-block{margin:0;padding:.25rem 0;opacity:.55;font-size:.85rem}ul.flat{list-style:none;padding:0;margin:0;display:flex;flex-direction:column;gap:.2rem}ul.flat li{display:flex;align-items:center;gap:.5rem;font-size:.8rem}ul.flat code{flex:1;min-width:0;font-family:ui-monospace,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.badge{font-size:.7rem;padding:0 .4rem;border-radius:3px;border:1px solid currentColor;opacity:.7}.badge.read{color:#3b82f6}.badge.write{color:#10b981}@media(max-width:380px){.bar{padding:.4rem .5rem;gap:.35rem}.input-wrap{min-width:100%}button{padding:.3rem .6rem;font-size:.78rem}.header-row{padding:.75rem .75rem .4rem;gap:.75rem}details summary{padding:.5rem .75rem}details .details-body{padding:0 .75rem .6rem}}</style>
<meta name="napplet-type" content="profile">
<meta name="napplet-requires" content="outbox">
</head>
<body>
<div class="bar">
<div class="input-wrap">
<input
id="lookup-input"
placeholder="search profiles or paste npub / nprofile / pubkey / nip05"
autocomplete="off"
spellcheck="false"
/>
<div id="suggestions" hidden></div>
</div>
<button
type="button"
id="feed-btn"
hidden
disabled
title="Open this profile's feed in a feed napplet"
>
Feed
</button>
<button type="button" id="update-btn" disabled>Update</button>
</div>
<main id="profile">
<p class="empty">loading…</p>
</main>
<div id="status"></div>
</body>
</html>
