@napplet/conformance-cli 0.2.17 → 0.2.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  var NappletConformanceHostBundle = (() => {
3
3
  // ../core/dist/index.js
4
- var NAP_DOMAINS = ["relay", "identity", "storage", "inc", "theme", "keys", "media", "notify", "config", "resource", "cvm", "outbox", "upload", "intent", "ble", "webrtc", "link", "count", "lists", "serial", "common", "dm"];
4
+ var NAP_DOMAINS = ["relay", "identity", "storage", "inc", "theme", "keys", "media", "notify", "config", "resource", "cvm", "outbox", "upload", "intent", "ble", "webrtc", "link", "count", "lists", "serial", "fs", "common", "dm"];
5
5
  function createDispatch() {
6
6
  const handlers = /* @__PURE__ */ new Map();
7
7
  function registerNap2(domain, handler) {
@@ -251,6 +251,36 @@ var NappletConformanceHostBundle = (() => {
251
251
  "serial.write.result": { dir: "in" },
252
252
  "serial.close.result": { dir: "in" },
253
253
  "serial.event": { dir: "in" },
254
+ // ── fs ───────────────────────────────────────────────────────────────────
255
+ "fs.info": { dir: "out", fields: { ...ID } },
256
+ "fs.pickFile": { dir: "out", fields: { ...ID } },
257
+ "fs.pickFiles": { dir: "out", fields: { ...ID } },
258
+ "fs.pickDirectory": { dir: "out", fields: { ...ID } },
259
+ "fs.pickSaveFile": { dir: "out", fields: { ...ID } },
260
+ "fs.stat": { dir: "out", fields: { ...ID, path: "string" } },
261
+ "fs.list": { dir: "out", fields: { ...ID, path: "string" } },
262
+ "fs.read": { dir: "out", fields: { ...ID, path: "string" } },
263
+ "fs.write": { dir: "out", fields: { ...ID, path: "string", data: "string" } },
264
+ "fs.mkdir": { dir: "out", fields: { ...ID, path: "string" } },
265
+ "fs.remove": { dir: "out", fields: { ...ID, path: "string" } },
266
+ "fs.move": { dir: "out", fields: { ...ID, fromPath: "string", toPath: "string" } },
267
+ "fs.watch": { dir: "out", fields: { ...ID, path: "string" } },
268
+ "fs.unwatch": { dir: "out", fields: { ...ID, watchId: "string" } },
269
+ "fs.info.result": { dir: "in" },
270
+ "fs.pickFile.result": { dir: "in" },
271
+ "fs.pickFiles.result": { dir: "in" },
272
+ "fs.pickDirectory.result": { dir: "in" },
273
+ "fs.pickSaveFile.result": { dir: "in" },
274
+ "fs.stat.result": { dir: "in" },
275
+ "fs.list.result": { dir: "in" },
276
+ "fs.read.result": { dir: "in" },
277
+ "fs.write.result": { dir: "in" },
278
+ "fs.mkdir.result": { dir: "in" },
279
+ "fs.remove.result": { dir: "in" },
280
+ "fs.move.result": { dir: "in" },
281
+ "fs.watch.result": { dir: "in" },
282
+ "fs.unwatch.result": { dir: "in" },
283
+ "fs.changed": { dir: "in" },
254
284
  // ── dm ───────────────────────────────────────────────────────────────────
255
285
  "dm.status": { dir: "out", fields: { ...ID } },
256
286
  "dm.conversations": { dir: "out", fields: { ...ID } },
@@ -464,6 +494,9 @@ var NappletConformanceHostBundle = (() => {
464
494
  var REFERENCE_HANDLER = "reference-handler";
465
495
  var REFERENCE_SUBSCRIBER = "reference-subscriber";
466
496
  var REFERENCE_CONVENTION = "napplet:note/open";
497
+ function pickResult(type, id, entry) {
498
+ return ok({ type, id, result: { entries: [entry] } });
499
+ }
467
500
  var ok = (v) => [v];
468
501
  var none = () => [];
469
502
  function dataUrlToBlob(url) {
@@ -648,7 +681,62 @@ var NappletConformanceHostBundle = (() => {
648
681
  // serial
649
682
  "serial.open": (e) => ok({ type: "serial.open.result", id: e.id, session: { id: `serial-${String(e.id)}`, state: "open" } }),
650
683
  "serial.write": (e) => ok({ type: "serial.write.result", id: e.id }),
651
- "serial.close": (e) => ok({ type: "serial.close.result", id: e.id })
684
+ "serial.close": (e) => ok({ type: "serial.close.result", id: e.id }),
685
+ // fs -- virtual paths and curated labels only; never a host path, username,
686
+ // device name, volume, or storage-provider string (NAP-FS info() disclosure rules)
687
+ "fs.info": (e) => ok({
688
+ type: "fs.info.result",
689
+ id: e.id,
690
+ info: {
691
+ roots: [{ path: "/shared", name: "Shared files", permissions: ["read", "list", "write", "create", "delete", "watch"] }],
692
+ limits: { maxReadBytes: 1048576, maxWriteBytes: 1048576, maxWatchCount: 16 }
693
+ }
694
+ }),
695
+ "fs.pickFile": (e) => pickResult("fs.pickFile.result", e.id, {
696
+ path: "/picked/file.txt",
697
+ kind: "file",
698
+ name: "file.txt",
699
+ permissions: ["read"]
700
+ }),
701
+ "fs.pickFiles": (e) => pickResult("fs.pickFiles.result", e.id, {
702
+ path: "/picked/file.txt",
703
+ kind: "file",
704
+ name: "file.txt",
705
+ permissions: ["read"]
706
+ }),
707
+ "fs.pickDirectory": (e) => pickResult("fs.pickDirectory.result", e.id, {
708
+ path: "/picked",
709
+ kind: "directory",
710
+ name: "picked",
711
+ permissions: ["read", "list"]
712
+ }),
713
+ "fs.pickSaveFile": (e) => pickResult("fs.pickSaveFile.result", e.id, {
714
+ path: "/picked/export.json",
715
+ kind: "file",
716
+ name: "export.json",
717
+ permissions: ["write", "create"]
718
+ }),
719
+ "fs.stat": (e) => ok({
720
+ type: "fs.stat.result",
721
+ id: e.id,
722
+ metadata: { path: e.path, kind: "file", size: 0 }
723
+ }),
724
+ "fs.list": (e) => ok({ type: "fs.list.result", id: e.id, entries: [] }),
725
+ "fs.read": (e) => ok({
726
+ type: "fs.read.result",
727
+ id: e.id,
728
+ result: { data: "", offset: 0, bytesRead: 0, eof: true, size: 0 }
729
+ }),
730
+ "fs.write": (e) => ok({
731
+ type: "fs.write.result",
732
+ id: e.id,
733
+ result: { bytesWritten: 0, size: 0 }
734
+ }),
735
+ "fs.mkdir": (e) => ok({ type: "fs.mkdir.result", id: e.id }),
736
+ "fs.remove": (e) => ok({ type: "fs.remove.result", id: e.id }),
737
+ "fs.move": (e) => ok({ type: "fs.move.result", id: e.id }),
738
+ "fs.watch": (e) => ok({ type: "fs.watch.result", id: e.id, watchId: `watch-${String(e.id)}` }),
739
+ "fs.unwatch": (e) => ok({ type: "fs.unwatch.result", id: e.id })
652
740
  };
653
741
  function createReferenceShell(options = {}) {
654
742
  const now = options.now ?? (() => Date.now());
@@ -0,0 +1,113 @@
1
+ (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function n(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var ot=["relay","identity","storage","inc","theme","keys","media","notify","config","resource","cvm","outbox","upload","intent","ble","webrtc","link","count","lists","serial","fs","common","dm"],d={id:"string"},In={"relay.subscribe":{dir:"out",fields:{...d,subId:"string",filters:"array"}},"relay.close":{dir:"out",fields:{...d,subId:"string"}},"relay.publish":{dir:"out",fields:{...d,event:"object"}},"relay.publishEncrypted":{dir:"out",fields:{...d,event:"object",recipient:"string"}},"relay.query":{dir:"out",fields:{...d,filters:"array"}},"relay.event":{dir:"in"},"relay.eose":{dir:"in"},"relay.closed":{dir:"in"},"relay.publish.result":{dir:"in"},"relay.publishEncrypted.result":{dir:"in"},"relay.query.result":{dir:"in"},"identity.getPublicKey":{dir:"out",fields:{...d}},"identity.getRelays":{dir:"out",fields:{...d}},"identity.getProfile":{dir:"out",fields:{...d}},"identity.getFollows":{dir:"out",fields:{...d}},"identity.getList":{dir:"out",fields:{...d,listType:"string"}},"identity.getZaps":{dir:"out",fields:{...d}},"identity.getMutes":{dir:"out",fields:{...d}},"identity.getBlocked":{dir:"out",fields:{...d}},"identity.getBadges":{dir:"out",fields:{...d}},"identity.changed":{dir:"in"},"identity.getPublicKey.result":{dir:"in"},"identity.getRelays.result":{dir:"in"},"identity.getProfile.result":{dir:"in"},"identity.getFollows.result":{dir:"in"},"identity.getList.result":{dir:"in"},"identity.getZaps.result":{dir:"in"},"identity.getMutes.result":{dir:"in"},"identity.getBlocked.result":{dir:"in"},"identity.getBadges.result":{dir:"in"},"storage.get":{dir:"out",fields:{...d,key:"string"}},"storage.set":{dir:"out",fields:{...d,key:"string",value:"string"}},"storage.remove":{dir:"out",fields:{...d,key:"string"}},"storage.keys":{dir:"out",fields:{...d}},"storage.get.result":{dir:"in"},"storage.set.result":{dir:"in"},"storage.remove.result":{dir:"in"},"storage.keys.result":{dir:"in"},"inc.emit":{dir:"out",fields:{topic:"string"},forbiddenFields:["sender"]},"inc.subscribe":{dir:"out",fields:{...d,topic:"string"}},"inc.unsubscribe":{dir:"out",fields:{topic:"string"}},"inc.channel.open":{dir:"out",fields:{...d,target:"string"}},"inc.channel.emit":{dir:"out",fields:{channelId:"string"}},"inc.channel.broadcast":{dir:"out"},"inc.channel.list":{dir:"out",fields:{...d}},"inc.channel.close":{dir:"out",fields:{channelId:"string"}},"inc.subscribe.result":{dir:"in"},"inc.event":{dir:"in",fields:{topic:"string",sender:"string"}},"inc.channel.open.result":{dir:"in"},"inc.channel.opened":{dir:"in",fields:{channelId:"string",peer:"string"}},"inc.channel.event":{dir:"in"},"inc.channel.list.result":{dir:"in"},"inc.channel.closed":{dir:"in"},"theme.get":{dir:"out",fields:{...d}},"theme.get.result":{dir:"in"},"theme.changed":{dir:"in"},"keys.forward":{dir:"out",fields:{key:"string",code:"string",ctrl:"boolean",alt:"boolean",shift:"boolean",meta:"boolean"}},"keys.registerAction":{dir:"out",fields:{...d,action:"object"}},"keys.unregisterAction":{dir:"out",fields:{actionId:"string"}},"keys.registerAction.result":{dir:"in"},"keys.bindings":{dir:"in"},"keys.action":{dir:"in"},"media.session.create":{dir:"out",fields:{...d,owner:"object"}},"media.session.update":{dir:"out",fields:{sessionId:"string",metadata:"object"}},"media.session.destroy":{dir:"out",fields:{sessionId:"string"}},"media.state":{dir:"out",fields:{sessionId:"string",status:"string"}},"media.capabilities":{dir:"out",fields:{sessionId:"string",actions:"array"}},"media.session.create.result":{dir:"in"},"media.command":{dir:"in"},"media.controls":{dir:"in"},"notify.send":{dir:"out",fields:{...d,title:"string"}},"notify.dismiss":{dir:"out",fields:{notificationId:"string"}},"notify.badge":{dir:"out",fields:{count:"number"}},"notify.channel.register":{dir:"out",fields:{channelId:"string",label:"string"}},"notify.permission.request":{dir:"out",fields:{...d}},"notify.send.result":{dir:"in"},"notify.permission.result":{dir:"in"},"notify.action":{dir:"in"},"notify.clicked":{dir:"in"},"notify.dismissed":{dir:"in"},"notify.controls":{dir:"in"},"config.registerSchema":{dir:"out",fields:{...d,schema:"object"}},"config.get":{dir:"out",fields:{...d}},"config.subscribe":{dir:"out"},"config.unsubscribe":{dir:"out"},"config.openSettings":{dir:"out"},"config.registerSchema.result":{dir:"in"},"config.values":{dir:"in"},"config.schemaError":{dir:"in"},"resource.info":{dir:"out",fields:{...d}},"resource.bytes":{dir:"out",fields:{...d,url:"string"}},"resource.bytesMany":{dir:"out",fields:{...d,urls:"array"}},"resource.cancel":{dir:"out",fields:{...d}},"resource.info.result":{dir:"in"},"resource.info.error":{dir:"in"},"resource.bytes.result":{dir:"in"},"resource.bytes.error":{dir:"in"},"resource.bytesMany.result":{dir:"in"},"resource.bytesMany.error":{dir:"in"},"cvm.discover":{dir:"out",fields:{...d}},"cvm.request":{dir:"out",fields:{...d,server:"object",message:"object"}},"cvm.close":{dir:"out",fields:{...d,server:"object"}},"cvm.registry.list":{dir:"out",fields:{...d}},"cvm.registry.has":{dir:"out",fields:{...d,family:"string"}},"cvm.registry.describe":{dir:"out",fields:{...d,family:"string"}},"cvm.registry.call":{dir:"out",fields:{...d,family:"string",tool:"string"}},"cvm.discover.result":{dir:"in"},"cvm.request.result":{dir:"in"},"cvm.close.result":{dir:"in"},"cvm.event":{dir:"in"},"cvm.registry.list.result":{dir:"in"},"cvm.registry.has.result":{dir:"in"},"cvm.registry.describe.result":{dir:"in"},"cvm.registry.call.result":{dir:"in"},"outbox.getEvent":{dir:"out",fields:{...d,eventId:"string"}},"outbox.query":{dir:"out",fields:{...d,filters:"present"}},"outbox.subscribe":{dir:"out",fields:{...d,subId:"string",filters:"present"}},"outbox.close":{dir:"out",fields:{...d,subId:"string"}},"outbox.publish":{dir:"out",fields:{...d,event:"object"}},"outbox.resolveRelays":{dir:"out",fields:{...d,target:"present"}},"outbox.getEvent.result":{dir:"in"},"outbox.query.result":{dir:"in"},"outbox.event":{dir:"in"},"outbox.closed":{dir:"in"},"outbox.publish.result":{dir:"in"},"outbox.resolveRelays.result":{dir:"in"},"upload.info":{dir:"out",fields:{...d}},"upload.upload":{dir:"out",fields:{...d,request:"object"}},"upload.status":{dir:"out",fields:{...d,uploadId:"string"}},"upload.info.result":{dir:"in"},"upload.upload.result":{dir:"in"},"upload.status.result":{dir:"in"},"upload.status.changed":{dir:"in"},"intent.invoke":{dir:"out",fields:{...d,request:"object"}},"intent.available":{dir:"out",fields:{...d,archetype:"string"}},"intent.handlers":{dir:"out",fields:{...d}},"intent.invoke.result":{dir:"in"},"intent.available.result":{dir:"in"},"intent.handlers.result":{dir:"in"},"intent.changed":{dir:"in"},"ble.open":{dir:"out",fields:{...d,request:"object"}},"ble.services":{dir:"out",fields:{...d,sessionId:"string"}},"ble.read":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.write":{dir:"out",fields:{...d,sessionId:"string",target:"object",data:"array"}},"ble.subscribe":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.unsubscribe":{dir:"out",fields:{...d,sessionId:"string",target:"object"}},"ble.close":{dir:"out",fields:{...d,sessionId:"string"}},"ble.open.result":{dir:"in"},"ble.services.result":{dir:"in"},"ble.read.result":{dir:"in"},"ble.write.result":{dir:"in"},"ble.subscribe.result":{dir:"in"},"ble.unsubscribe.result":{dir:"in"},"ble.close.result":{dir:"in"},"ble.event":{dir:"in"},"common.encodeNip19":{dir:"out",fields:{...d,input:"object"}},"common.decodeNip19":{dir:"out",fields:{...d,value:"string"}},"common.getProfile":{dir:"out",fields:{...d,target:"string"}},"common.follows":{dir:"out",fields:{...d}},"common.follow":{dir:"out",fields:{...d,pubkeys:"array"}},"common.unfollow":{dir:"out",fields:{...d,pubkeys:"array"}},"common.react":{dir:"out",fields:{...d,targetEventId:"string",reaction:"string"}},"common.report":{dir:"out",fields:{...d,target:"object",reason:"string",text:"string"}},"common.encodeNip19.result":{dir:"in"},"common.decodeNip19.result":{dir:"in"},"common.getProfile.result":{dir:"in"},"common.follows.result":{dir:"in"},"common.follow.result":{dir:"in"},"common.unfollow.result":{dir:"in"},"common.react.result":{dir:"in"},"common.report.result":{dir:"in"},"webrtc.open":{dir:"out",fields:{...d,request:"object"}},"webrtc.send":{dir:"out",fields:{...d,sessionId:"string",payload:"present"}},"webrtc.close":{dir:"out",fields:{...d,sessionId:"string"}},"webrtc.open.result":{dir:"in"},"webrtc.send.result":{dir:"in"},"webrtc.close.result":{dir:"in"},"webrtc.event":{dir:"in"},"link.open":{dir:"out",fields:{...d,url:"string"}},"link.open.result":{dir:"in"},"count.query":{dir:"out",fields:{...d,filters:"array"}},"count.query.result":{dir:"in"},"lists.supported":{dir:"out",fields:{...d}},"lists.add":{dir:"out",fields:{...d,list:"object",items:"array"}},"lists.remove":{dir:"out",fields:{...d,list:"object",items:"array"}},"lists.supported.result":{dir:"in"},"lists.add.result":{dir:"in"},"lists.remove.result":{dir:"in"},"serial.open":{dir:"out",fields:{...d,request:"object"}},"serial.write":{dir:"out",fields:{...d,sessionId:"string",data:"array"}},"serial.close":{dir:"out",fields:{...d,sessionId:"string"}},"serial.open.result":{dir:"in"},"serial.write.result":{dir:"in"},"serial.close.result":{dir:"in"},"serial.event":{dir:"in"},"fs.info":{dir:"out",fields:{...d}},"fs.pickFile":{dir:"out",fields:{...d}},"fs.pickFiles":{dir:"out",fields:{...d}},"fs.pickDirectory":{dir:"out",fields:{...d}},"fs.pickSaveFile":{dir:"out",fields:{...d}},"fs.stat":{dir:"out",fields:{...d,path:"string"}},"fs.list":{dir:"out",fields:{...d,path:"string"}},"fs.read":{dir:"out",fields:{...d,path:"string"}},"fs.write":{dir:"out",fields:{...d,path:"string",data:"string"}},"fs.mkdir":{dir:"out",fields:{...d,path:"string"}},"fs.remove":{dir:"out",fields:{...d,path:"string"}},"fs.move":{dir:"out",fields:{...d,fromPath:"string",toPath:"string"}},"fs.watch":{dir:"out",fields:{...d,path:"string"}},"fs.unwatch":{dir:"out",fields:{...d,watchId:"string"}},"fs.info.result":{dir:"in"},"fs.pickFile.result":{dir:"in"},"fs.pickFiles.result":{dir:"in"},"fs.pickDirectory.result":{dir:"in"},"fs.pickSaveFile.result":{dir:"in"},"fs.stat.result":{dir:"in"},"fs.list.result":{dir:"in"},"fs.read.result":{dir:"in"},"fs.write.result":{dir:"in"},"fs.mkdir.result":{dir:"in"},"fs.remove.result":{dir:"in"},"fs.move.result":{dir:"in"},"fs.watch.result":{dir:"in"},"fs.unwatch.result":{dir:"in"},"fs.changed":{dir:"in"},"dm.status":{dir:"out",fields:{...d}},"dm.conversations":{dir:"out",fields:{...d}},"dm.messages":{dir:"out",fields:{...d,conversationId:"string"}},"dm.send":{dir:"out",fields:{...d,recipients:"array",content:"string"}},"dm.subscribe":{dir:"out",fields:{...d}},"dm.unsubscribe":{dir:"out",fields:{...d,subscriptionId:"string"}},"dm.status.result":{dir:"in"},"dm.conversations.result":{dir:"in"},"dm.messages.result":{dir:"in"},"dm.send.result":{dir:"in"},"dm.subscribe.result":{dir:"in"},"dm.unsubscribe.result":{dir:"in"},"dm.message":{dir:"in"}};function Ht(e){if(e===void 0)return"undefined";if(e===null)return"null";if(Array.isArray(e))return"array";const t=typeof e;return t==="string"||t==="number"||t==="boolean"?t:t==="object"?"object":"present"}function $n(e,t){return t==="present"?e!=null:Ht(e)===t}function Tn(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return;const r=e;typeof r.archetype!="string"&&t.push({code:r.archetype===void 0?"missing-field":"wrong-type",message:'Intent request requires a string "archetype" field',field:"request.archetype"});for(const n of["action","convention"])r[n]!==void 0&&typeof r[n]!="string"&&t.push({code:"wrong-type",message:`Intent request field "${n}" must be a string`,field:`request.${n}`});"sender"in r&&t.push({code:"forbidden-field",message:"Intent request does not define a caller-supplied sender field",field:"request.sender"})}function Bn(e){const t=[];if(typeof e!="object"||e===null||Array.isArray(e))return{ok:!1,errors:[{code:"not-an-object",message:"Envelope must be a non-null object"}]};const r=e,n=r.type;if(typeof n!="string")return{ok:!1,errors:[{code:"missing-type",message:"Envelope is missing a string `type` field"}]};const i=n.indexOf(".");if(i<=0)return{ok:!1,type:n,errors:[{code:"malformed-type",message:`Envelope type "${n}" is not in domain.action form`}]};const s=n.slice(0,i);if(!ot.includes(s))return{ok:!1,type:n,domain:s,errors:[{code:"unknown-domain",message:`"${s}" is not a known NAP domain`}]};const c=In[n];if(!c)return{ok:!1,type:n,domain:s,errors:[{code:"unknown-type",message:`"${n}" is not a known ${s} message type`}]};for(const[a,l]of Object.entries(c.fields??{})){if(!(a in r)||r[a]===void 0){t.push({code:"missing-field",message:`Required field "${a}" is missing`,field:a});continue}$n(r[a],l)||t.push({code:"wrong-type",message:`Field "${a}" should be ${l} but is ${Ht(r[a])}`,field:a})}if(c.dir==="in")return{ok:!1,type:n,domain:s,direction:"in",errors:[{code:"inbound-type-emitted",message:`"${n}" is a shell→napplet message; a napplet must not emit it`},...t]};for(const a of c.forbiddenFields??[])a in r&&t.push({code:"forbidden-field",message:`Field "${a}" must be runtime-derived and cannot be emitted by a napplet`,field:a});return n==="intent.invoke"&&Tn(r.request,t),{ok:t.length===0,type:n,domain:s,direction:"out",errors:t}}var Dt=5129,jt=15129,ge=35129,at=[Dt,jt,ge];function Mt(e,t){return e.tags.find(r=>r[0]===t)}function An(e){return at.includes(e)}function On(e){return typeof e=="string"&&/^[0-9a-f]{64}$/i.test(e)}function Ft(e){return Mt(e,"d")?.[1]?.trim()||void 0}function Nn(e){return e.tags.filter(t=>t[0]==="requires").map(t=>t[1]?.trim()??"").filter(Boolean)}function Wt(e){return Ft(e)??Mt(e,"title")?.[1]??e.id}function ct(e){const t=[],r=[];if(!e)return{ok:!1,requires:[],errors:[{code:"missing-manifest-event",message:"No NIP-5D manifest event was resolved"}],warnings:r};const n=Ft(e),i=Nn(e);An(e.kind)||t.push({code:"invalid-napplet-kind",message:`Manifest event kind ${e.kind} is not a NIP-5D napplet kind`}),e.kind===ge&&!n?t.push({code:"missing-d-tag",message:"Named napplet manifest kind 35129 must include a non-empty d tag"}):(e.kind===jt||e.kind===Dt)&&n&&t.push({code:"unexpected-d-tag",message:`Napplet manifest kind ${e.kind} must not include a d tag`});const s=e.tags.find(o=>o[0]==="path"&&o[1]==="/index.html");s?On(s[2])||t.push({code:"invalid-index-html-hash",message:"The /index.html path tag must carry a 64-character sha256 hash"}):t.push({code:"missing-index-html",message:"Napplet manifest must include a path tag for /index.html"});for(const o of i){if(o.startsWith("nap:")||o.startsWith("NAP-")){t.push({code:"invalid-required-nap",message:`requires tag "${o}" must be a bare NAP domain such as "relay"`});continue}ot.includes(o)||t.push({code:"unknown-required-nap",message:`requires tag "${o}" is not a known NAP domain`})}return{ok:t.length===0,kind:e.kind,dTag:n,requires:i,errors:t,warnings:r}}var xe="f".repeat(64),qn={dTag:"reference-source"},Ln="https://reference.invalid/blob",bt="reference-handler",Pn="reference-subscriber",ke="napplet:note/open";function Se(e,t,r){return h({type:e,id:t,result:{entries:[r]}})}var h=e=>[e],L=()=>[];function wt(e){if(typeof e!="string"||!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return{blob:new Blob([],{type:"text/plain"}),mime:"text/plain"};const r=e.slice(5,t),n=e.slice(t+1),i=r.split(";").filter(Boolean),s=i.includes("base64"),o=i.find(c=>c.includes("/"))??"text/plain";try{if(s){const c=globalThis.atob(n),a=Uint8Array.from(c,l=>l.charCodeAt(0));return{blob:new Blob([a],{type:o}),mime:o}}return{blob:new Blob([decodeURIComponent(n)],{type:o}),mime:o}}catch{return null}}var _n={"relay.subscribe":e=>h({type:"relay.eose",subId:e.subId}),"relay.close":L,"relay.publish":e=>h({type:"relay.publish.result",id:e.id,ok:!0,event:e.event}),"relay.publishEncrypted":e=>h({type:"relay.publishEncrypted.result",id:e.id,ok:!0,event:e.event}),"relay.query":e=>h({type:"relay.query.result",id:e.id,events:[]}),"identity.getPublicKey":e=>h({type:"identity.getPublicKey.result",id:e.id,pubkey:xe}),"identity.getRelays":e=>h({type:"identity.getRelays.result",id:e.id,relays:{}}),"identity.getProfile":e=>h({type:"identity.getProfile.result",id:e.id,profile:null}),"identity.getFollows":e=>h({type:"identity.getFollows.result",id:e.id,pubkeys:[]}),"identity.getList":e=>h({type:"identity.getList.result",id:e.id,entries:[]}),"identity.getZaps":e=>h({type:"identity.getZaps.result",id:e.id,zaps:[]}),"identity.getMutes":e=>h({type:"identity.getMutes.result",id:e.id,pubkeys:[]}),"identity.getBlocked":e=>h({type:"identity.getBlocked.result",id:e.id,pubkeys:[]}),"identity.getBadges":e=>h({type:"identity.getBadges.result",id:e.id,badges:[]}),"storage.get":e=>h({type:"storage.get.result",id:e.id,value:null}),"storage.set":e=>h({type:"storage.set.result",id:e.id}),"storage.remove":e=>h({type:"storage.remove.result",id:e.id}),"storage.keys":e=>h({type:"storage.keys.result",id:e.id,keys:[]}),"inc.emit":L,"inc.subscribe":e=>h({type:"inc.subscribe.result",id:e.id}),"inc.unsubscribe":L,"inc.channel.open":e=>h({type:"inc.channel.open.result",id:e.id,channelId:`chan-${String(e.id)}`,peer:"reference-peer"}),"inc.channel.emit":L,"inc.channel.broadcast":L,"inc.channel.list":e=>h({type:"inc.channel.list.result",id:e.id,channels:[]}),"inc.channel.close":L,"theme.get":e=>h({type:"theme.get.result",id:e.id,theme:{colors:{},mode:"dark"}}),"keys.forward":L,"keys.registerAction":e=>h({type:"keys.registerAction.result",id:e.id,actionId:`action-${String(e.id)}`}),"keys.unregisterAction":L,"media.session.create":e=>h({type:"media.session.create.result",id:e.id,sessionId:`session-${String(e.id)}`,owner:e.owner}),"media.session.update":L,"media.session.destroy":L,"media.state":L,"media.capabilities":L,"notify.send":e=>h({type:"notify.send.result",id:e.id,notificationId:`notif-${String(e.id)}`}),"notify.dismiss":L,"notify.badge":L,"notify.channel.register":L,"notify.permission.request":e=>h({type:"notify.permission.result",id:e.id,granted:!0}),"config.registerSchema":e=>h({type:"config.registerSchema.result",id:e.id,ok:!0}),"config.get":e=>h({type:"config.values",id:e.id,values:{}}),"config.subscribe":()=>h({type:"config.values",values:{}}),"config.unsubscribe":L,"config.openSettings":L,"resource.bytes":e=>{const t=wt(e.url);return h(t?{type:"resource.bytes.result",id:e.id,blob:t.blob,mime:t.mime}:{type:"resource.bytes.result",id:e.id,blob:new Blob([]),mime:"application/octet-stream"})},"resource.bytesMany":e=>h({type:"resource.bytesMany.result",id:e.id,items:Array.isArray(e.urls)?e.urls.map(t=>{const r=wt(t);return{url:t,ok:!0,blob:r?.blob??new Blob([]),mime:r?.mime??"application/octet-stream"}}):[]}),"resource.info":e=>h({type:"resource.info.result",id:e.id,info:{schemes:[{scheme:"data",enabled:!0},{scheme:"https",enabled:!0}]}}),"resource.cancel":L,"cvm.discover":e=>h({type:"cvm.discover.result",id:e.id,servers:[]}),"cvm.request":e=>h({type:"cvm.request.result",id:e.id,message:{}}),"cvm.close":e=>h({type:"cvm.close.result",id:e.id}),"outbox.getEvent":e=>h({type:"outbox.getEvent.result",id:e.id}),"outbox.query":e=>h({type:"outbox.query.result",id:e.id,events:[]}),"outbox.subscribe":e=>h({type:"outbox.closed",subId:e.subId,reason:"reference shell complete"}),"outbox.close":L,"outbox.publish":e=>h({type:"outbox.publish.result",id:e.id,ok:!0}),"outbox.resolveRelays":e=>h({type:"outbox.resolveRelays.result",id:e.id,plan:{}}),"upload.info":e=>h({type:"upload.info.result",id:e.id,info:{rails:[{rail:"nip96",enabled:!0,returns:["https"]},{rail:"blossom",enabled:!0,returns:["https","blossom"]}]}}),"upload.upload":e=>h({type:"upload.upload.result",id:e.id,result:{url:Ln}}),"upload.status":e=>h({type:"upload.status.result",id:e.id,status:{}}),"ble.open":e=>h({type:"ble.open.result",id:e.id,session:{id:"ble-reference",state:"open",device:{id:"reference-device",name:"Reference BLE"}}}),"ble.services":e=>h({type:"ble.services.result",id:e.id,services:[]}),"ble.read":e=>h({type:"ble.read.result",id:e.id,data:[]}),"ble.write":e=>h({type:"ble.write.result",id:e.id}),"ble.subscribe":e=>h({type:"ble.subscribe.result",id:e.id}),"ble.unsubscribe":e=>h({type:"ble.unsubscribe.result",id:e.id}),"ble.close":e=>h({type:"ble.close.result",id:e.id}),"common.encodeNip19":e=>h({type:"common.encodeNip19.result",id:e.id,ok:!0,value:"npub1reference",nip19Type:"npub"}),"common.decodeNip19":e=>h({type:"common.decodeNip19.result",id:e.id,ok:!0,nip19Type:"npub",hex:xe}),"common.getProfile":e=>h({type:"common.getProfile.result",id:e.id,ok:!0,pubkey:xe,profile:null}),"common.follows":e=>h({type:"common.follows.result",id:e.id,ok:!0,pubkeys:[]}),"common.follow":e=>h({type:"common.follow.result",id:e.id,ok:!0}),"common.unfollow":e=>h({type:"common.unfollow.result",id:e.id,ok:!0}),"common.react":e=>h({type:"common.react.result",id:e.id,ok:!0,eventId:"0".repeat(64)}),"common.report":e=>h({type:"common.report.result",id:e.id,ok:!0,eventId:"1".repeat(64)}),"webrtc.open":e=>h({type:"webrtc.open.result",id:e.id,session:{id:"webrtc-reference",scope:{type:"direct",pubkey:xe},channel:"default",state:"connecting"}}),"webrtc.send":e=>h({type:"webrtc.send.result",id:e.id}),"webrtc.close":e=>h({type:"webrtc.close.result",id:e.id}),"link.open":e=>h({type:"link.open.result",id:e.id,status:"opened"}),"count.query":e=>h({type:"count.query.result",id:e.id,ok:!0,count:0}),"lists.supported":e=>h({type:"lists.supported.result",id:e.id,lists:[]}),"lists.add":e=>h({type:"lists.add.result",id:e.id,ok:!0,added:0,skipped:0}),"lists.remove":e=>h({type:"lists.remove.result",id:e.id,ok:!0,removed:0,skipped:0}),"serial.open":e=>h({type:"serial.open.result",id:e.id,session:{id:`serial-${String(e.id)}`,state:"open"}}),"serial.write":e=>h({type:"serial.write.result",id:e.id}),"serial.close":e=>h({type:"serial.close.result",id:e.id}),"fs.info":e=>h({type:"fs.info.result",id:e.id,info:{roots:[{path:"/shared",name:"Shared files",permissions:["read","list","write","create","delete","watch"]}],limits:{maxReadBytes:1048576,maxWriteBytes:1048576,maxWatchCount:16}}}),"fs.pickFile":e=>Se("fs.pickFile.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickFiles":e=>Se("fs.pickFiles.result",e.id,{path:"/picked/file.txt",kind:"file",name:"file.txt",permissions:["read"]}),"fs.pickDirectory":e=>Se("fs.pickDirectory.result",e.id,{path:"/picked",kind:"directory",name:"picked",permissions:["read","list"]}),"fs.pickSaveFile":e=>Se("fs.pickSaveFile.result",e.id,{path:"/picked/export.json",kind:"file",name:"export.json",permissions:["write","create"]}),"fs.stat":e=>h({type:"fs.stat.result",id:e.id,metadata:{path:e.path,kind:"file",size:0}}),"fs.list":e=>h({type:"fs.list.result",id:e.id,entries:[]}),"fs.read":e=>h({type:"fs.read.result",id:e.id,result:{data:"",offset:0,bytesRead:0,eof:!0,size:0}}),"fs.write":e=>h({type:"fs.write.result",id:e.id,result:{bytesWritten:0,size:0}}),"fs.mkdir":e=>h({type:"fs.mkdir.result",id:e.id}),"fs.remove":e=>h({type:"fs.remove.result",id:e.id}),"fs.move":e=>h({type:"fs.move.result",id:e.id}),"fs.watch":e=>h({type:"fs.watch.result",id:e.id,watchId:`watch-${String(e.id)}`}),"fs.unwatch":e=>h({type:"fs.unwatch.result",id:e.id})};function Cn(e={}){const t=e.now??(()=>Date.now()),r=[],n=new Map;function i(u,f){const p=n.get(u);if(p){p.push(f);return}n.set(u,[f])}function s(u){const f=n.get(u)??[];return n.delete(u),f}function o(u,f,p,y){return h({type:"intent.invoke.result",id:u,result:{ok:!1,archetype:f,action:p,handled:!1,error:y}})}function c(u,f){const p=f.request;if(typeof p!="object"||p===null||Array.isArray(p))return o(f.id,"","open","invalid intent request");const y=p,w=typeof y.archetype=="string"?y.archetype:"",$=typeof y.action=="string"?y.action:"open";return w?w!=="note"?o(f.id,w,$,"no handler"):y.convention!==void 0&&y.convention!==ke?o(f.id,w,$,"unsupported convention"):h({type:"intent.invoke.result",id:f.id,result:{ok:!0,archetype:w,action:$,handled:!0,handler:bt,windowId:"reference-window",convention:typeof y.convention=="string"?y.convention:ke}}):o(f.id,w,$,"intent request requires an archetype")}function a(u){return u!=="note"?{archetype:u,available:!1,candidates:[],hasDefault:!1}:{archetype:u,available:!0,candidates:[{dTag:bt,actions:["open"],conventions:[ke],isDefault:!0}],hasDefault:!0}}function l(u,f){const p=f&&typeof f=="object"&&typeof f.type=="string"?f.type:void 0,y=Bn(f);if(r.push({envelope:f,verdict:y,timestamp:t()}),!p||!y.ok)return[];const w=f;if(p==="intent.invoke")return c(u,w);if(p==="intent.available")return h({type:"intent.available.result",id:w.id,availability:a(w.archetype)});if(p==="intent.handlers")return h({type:"intent.handlers.result",id:w.id,handlers:[a("note")]});if(p==="inc.emit"){if(w.topic===ke){const N={type:"inc.event",topic:w.topic,sender:u.dTag};"payload"in w&&(N.payload=w.payload),i(Pn,N)}return[]}const $=_n[p];return $?$(w):[]}function g(u){return l(qn,u)}return{get records(){return r},handle:g,handleFrom:l,takeDeliveries:s,reset(){r.length=0,n.clear()}}}function Un(e){return{manifestHtml:e.manifestHtml,manifestEvent:e.manifestEvent??null,sandbox:e.sandbox??{allowScripts:!0,allowSameOrigin:!1},installedGlobal:e.boot.installedGlobal,bootError:e.boot.bootError,emitted:e.boot.emitted,forbiddenGlobals:e.forbiddenGlobals??[],degraded:e.boot.degraded,lifecycle:e.lifecycle??null}}var Zt="__nappletConformance.error";function vt(e){return new Promise(t=>setTimeout(t,e))}function Hn(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Dn(e){return`
2
+ (() => {
3
+ const domains = ${JSON.stringify(e)};
4
+ const napplet = {};
5
+ for (const domain of domains) napplet[domain] = {};
6
+ const pending = new Map();
7
+ let seq = 0;
8
+ const nextId = () => {
9
+ try {
10
+ if (window.crypto && typeof window.crypto.randomUUID === 'function') return window.crypto.randomUUID();
11
+ } catch {}
12
+ seq += 1;
13
+ return 'conformance-' + Date.now().toString(36) + '-' + seq.toString(36);
14
+ };
15
+ const request = (message, resultType, errorType) => new Promise((resolve, reject) => {
16
+ const id = message.id || nextId();
17
+ const timeout = window.setTimeout(() => {
18
+ pending.delete(id);
19
+ reject(new Error(message.type + ' timed out'));
20
+ }, 5000);
21
+ pending.set(id, { resolve, reject, resultType, errorType, timeout });
22
+ window.parent.postMessage({ ...message, id }, '*');
23
+ });
24
+ window.addEventListener('message', (event) => {
25
+ const msg = event.data;
26
+ if (!msg || typeof msg !== 'object' || typeof msg.id !== 'string') return;
27
+ const slot = pending.get(msg.id);
28
+ if (!slot) return;
29
+ if (msg.type !== slot.resultType && msg.type !== slot.errorType) return;
30
+ pending.delete(msg.id);
31
+ window.clearTimeout(slot.timeout);
32
+ if (msg.type === slot.errorType) {
33
+ slot.reject(new Error(msg.message ? msg.error + ': ' + msg.message : String(msg.error || 'request failed')));
34
+ return;
35
+ }
36
+ slot.resolve(msg);
37
+ });
38
+ if (napplet.resource) {
39
+ napplet.resource.info = () =>
40
+ request({ type: 'resource.info' }, 'resource.info.result', 'resource.info.error')
41
+ .then((msg) => msg.info);
42
+ napplet.resource.bytes = (url) =>
43
+ request({ type: 'resource.bytes', url: String(url) }, 'resource.bytes.result', 'resource.bytes.error')
44
+ .then((msg) => msg.blob);
45
+ napplet.resource.bytesMany = (urls) =>
46
+ request({ type: 'resource.bytesMany', urls: Array.from(urls || []) }, 'resource.bytesMany.result', 'resource.bytesMany.error')
47
+ .then((msg) => msg.items);
48
+ napplet.resource.bytesAsObjectURL = (url) => {
49
+ const handle = { url: '', revoke: () => {} };
50
+ let objectUrl = '';
51
+ let revoked = false;
52
+ const ready = napplet.resource.bytes(url).then((blob) => {
53
+ if (revoked) return;
54
+ objectUrl = URL.createObjectURL(blob);
55
+ handle.url = objectUrl;
56
+ return objectUrl;
57
+ });
58
+ handle.revoke = () => {
59
+ if (revoked) return;
60
+ revoked = true;
61
+ if (objectUrl) URL.revokeObjectURL(objectUrl);
62
+ };
63
+ Object.defineProperty(handle, 'ready', { value: ready, enumerable: false });
64
+ return handle;
65
+ };
66
+ }
67
+ window.napplet = napplet;
68
+ const report = (reason) => {
69
+ try {
70
+ window.parent.postMessage({ type: '${Zt}', reason: String(reason && reason.message || reason) }, '*');
71
+ } catch {}
72
+ };
73
+ window.addEventListener('error', (event) => report(event.error || event.message));
74
+ window.addEventListener('unhandledrejection', (event) => report(event.reason));
75
+ })();
76
+ `}function jn(e,t,r){const n=`<base href="${Hn(t)}">`,i=`<script>${Dn(r)}<\/script>`,s=/<head(?:\s[^>]*)?>/i.exec(e);if(s){const o=s.index+s[0].length;return`${e.slice(0,o)}${n}${i}${e.slice(o)}`}return`${n}${i}${e}`}function Mn(e){if(!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return"";const r=e.slice(0,t),n=e.slice(t+1);return r.endsWith(";base64")?atob(n):decodeURIComponent(n)}async function Fn(e){if(e==="about:blank")return"<!doctype html><html><head></head><body></body></html>";const t=Mn(e);if(t!==null)return t;const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch napplet HTML: ${r.status} ${r.statusText}`);return r.text()}async function Et(e,t,r,n){const i=Cn(),s=r.createElement("iframe");s.setAttribute("sandbox",t.allowSameOrigin?"allow-scripts allow-same-origin":"allow-scripts"),s.setAttribute("aria-hidden","true"),s.style.position="absolute",s.style.width="1px",s.style.height="1px",s.style.left="-9999px";let o=null;const c=g=>{if(g.source!==s.contentWindow)return;const u=g.data;if(u&&typeof u=="object"&&u.type===Zt){o=`napplet boot error: ${String(u.reason??"unknown error")}`;return}const f=i.handle(g.data),p=g.source;for(const y of f)p?.postMessage(y,"*")};let a=!1;const l=new Promise(g=>{s.addEventListener("load",()=>{a=!0,g()},{once:!0})});n.addEventListener("message",c),(r.body??r.documentElement).appendChild(s);try{const g=await Fn(t.url);s.srcdoc=jn(g,t.url,e)}catch(g){o=g instanceof Error?g.message:String(g)}if(!o){const g=Symbol("timeout");await Promise.race([l.then(()=>"loaded"),vt(t.readyTimeoutMs).then(()=>g)])===g||!a?o=`napplet did not boot (iframe did not load within ${t.readyTimeoutMs}ms; a conformant napplet must run under sandbox="allow-scripts" without allow-same-origin)`:await vt(t.settleMs)}n.removeEventListener("message",c);try{s.remove()}catch{}return{installedGlobal:o===null,bootError:o,emitted:[...i.records]}}async function Wn(e){const t=e.document??document,r=e.window??window,n={url:e.url,readyTimeoutMs:e.readyTimeoutMs??5e3,settleMs:e.settleMs,allowSameOrigin:e.allowSameOrigin??!1},i=await Et(ot,n,t,r);let s=null;{const o=await Et([],n,t,r);s={bootError:o.bootError,emitted:o.emitted}}return{installedGlobal:i.installedGlobal,bootError:i.bootError,emitted:i.emitted,degraded:s}}var Zn=e=>({status:"pass",detail:e}),Vn=(e,t)=>({status:"fail",detail:e,diagnostics:t}),Kn=e=>({status:"skip",detail:e}),q={pass:Zn,fail:Vn,skip:Kn};function Yn(e,t){return ct(e.manifestEvent).errors.filter(r=>t.includes(r.code))}function je(e,t,r){return{id:e,area:"manifest",severity:"error",title:t,run:n=>{if(!n.manifestEvent)return q.skip("No NIP-5D manifest event was resolved");const i=Yn(n,r);return i.length?q.fail(i[0].message,i):q.pass()}}}var zn=[je("manifest/event-kind","Resolved event is a NIP-5D napplet manifest",["invalid-napplet-kind","missing-d-tag","unexpected-d-tag"]),je("manifest/index-html","Manifest declares a hashed /index.html",["missing-index-html","invalid-index-html-hash"]),je("manifest/requires","requires tags are bare known NAP domains",["invalid-required-nap","unknown-required-nap"]),{id:"boot/sandbox-allow-scripts",area:"boot",severity:"error",title:"Runs under allow-scripts without allow-same-origin",run:e=>e.sandbox.allowScripts?e.sandbox.allowSameOrigin?q.fail("Napplet relied on allow-same-origin, which a shell must not grant"):q.pass():q.fail("Napplet was not loaded with allow-scripts")},{id:"boot/installs-global",area:"boot",severity:"error",title:"Runs after runtime-injected window.napplet is installed",run:e=>e.installedGlobal?q.pass():q.fail("runtime did not inject window.napplet before load")},{id:"boot/no-boot-error",area:"boot",severity:"error",title:"Boots without an uncaught error",run:e=>e.bootError?q.fail(e.bootError):q.pass()},{id:"boot/no-forbidden-globals",area:"boot",severity:"error",title:"Does not access forbidden browser authority surfaces",run:e=>e.forbiddenGlobals.length?q.fail(`Accessed forbidden surface(s): ${e.forbiddenGlobals.join(", ")}`,e.forbiddenGlobals):q.pass()},{id:"wire/envelope-well-formed",area:"wire",severity:"error",title:"Every emitted envelope is well-formed",run:e=>{if(e.emitted.length===0)return q.skip("Napplet emitted no envelopes");const t=e.emitted.filter(n=>!n.verdict.ok);if(t.length===0)return q.pass(`${e.emitted.length} envelope(s) valid`);const r=t.map(n=>({envelope:n.envelope,errors:n.verdict.errors}));return q.fail(`${t.length}/${e.emitted.length} emitted envelope(s) invalid`,r)}},{id:"degrade/domain-absence",area:"degradation",severity:"error",title:"Does not crash when no NAP domains are injected",run:e=>e.degraded?e.degraded.bootError?q.fail(`Crashed with no injected domains: ${e.degraded.bootError}`):q.pass():q.skip("Host did not run the degraded (no-capabilities) pass")},{id:"lifecycle/clean-teardown",area:"lifecycle",severity:"warning",title:"Tears down listeners on unload",run:e=>e.lifecycle?e.lifecycle.listenerLeak?q.fail("Message listeners remained after unload"):q.pass():q.skip("Lifecycle not measured")}];function Gn(e,t={}){const r=t.now??(()=>Date.now()),n=t.checks??zn,i=r(),s=n.map(a=>{const l=a.run(e);return{id:a.id,area:a.area,severity:a.severity,title:a.title,status:l.status,detail:l.detail,diagnostics:l.diagnostics}}),o={total:s.length,passed:s.filter(a=>a.status==="pass").length,failed:s.filter(a=>a.status==="fail").length,skipped:s.filter(a=>a.status==="skip").length,errors:s.filter(a=>a.status==="fail"&&a.severity==="error").length,warnings:s.filter(a=>a.status==="fail"&&a.severity==="warning").length};return{napplet:e.manifestEvent?Wt(e.manifestEvent):void 0,startedAt:i,finishedAt:r(),checks:s,summary:o,ok:o.errors===0}}/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Xn(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function lt(e,t=""){if(!Number.isSafeInteger(e)||e<0){const r=t&&`"${t}" `;throw new Error(`${r}expected integer >= 0, got ${e}`)}}function j(e,t,r=""){const n=Xn(e),i=e?.length,s=t!==void 0;if(!n||s&&i!==t){const o=r&&`"${r}" `,c=s?` of length ${t}`:"",a=n?`length=${i}`:`type=${typeof e}`;throw new Error(o+"expected Uint8Array"+c+", got "+a)}return e}function xt(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Jn(e,t){j(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function Xe(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function Me(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function z(e,t){return e<<32-t|e>>>t}const Vt=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Qn=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function _(e){if(j(e),Vt)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=Qn[e[r]];return t}const J={_0:48,_9:57,A:65,F:70,a:97,f:102};function kt(e){if(e>=J._0&&e<=J._9)return e-J._0;if(e>=J.A&&e<=J.F)return e-(J.A-10);if(e>=J.a&&e<=J.f)return e-(J.a-10)}function X(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(Vt)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,s=0;i<r;i++,s+=2){const o=kt(e.charCodeAt(s)),c=kt(e.charCodeAt(s+1));if(o===void 0||c===void 0){const a=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+a+'" at index '+s)}n[i]=o*16+c}return n}function Ae(...e){let t=0;for(let n=0;n<e.length;n++){const i=e[n];j(i),t+=i.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const s=e[n];r.set(s,i),i+=s.length}return r}function er(e,t={}){const r=(i,s)=>e(s).update(i).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=i=>e(i),Object.assign(r,t),Object.freeze(r)}function Kt(e=32){const t=typeof globalThis=="object"?globalThis.crypto:null;if(typeof t?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const tr=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Yt(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function zt(e,t){return Array.isArray(t)?t.length===0?!0:e?t.every(r=>typeof r=="string"):t.every(r=>Number.isSafeInteger(r)):!1}function nr(e){if(typeof e!="function")throw new Error("function expected");return!0}function ye(e,t){if(typeof t!="string")throw new Error(`${e}: string expected`);return!0}function Gt(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function Je(e){if(!Array.isArray(e))throw new Error("array expected")}function Xt(e,t){if(!zt(!0,t))throw new Error(`${e}: array of strings expected`)}function Jt(e,t){if(!zt(!1,t))throw new Error(`${e}: array of numbers expected`)}function rr(...e){const t=s=>s,r=(s,o)=>c=>s(o(c)),n=e.map(s=>s.encode).reduceRight(r,t),i=e.map(s=>s.decode).reduce(r,t);return{encode:n,decode:i}}function ir(e){const t=typeof e=="string"?e.split(""):e,r=t.length;Xt("alphabet",t);const n=new Map(t.map((i,s)=>[i,s]));return{encode:i=>(Je(i),i.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${e}`);return t[s]})),decode:i=>(Je(i),i.map(s=>{ye("alphabet.decode",s);const o=n.get(s);if(o===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${e}`);return o}))}}function sr(e=""){return ye("join",e),{encode:t=>(Xt("join.decode",t),t.join(e)),decode:t=>(ye("join.decode",t),t.split(e))}}const Qt=(e,t)=>t===0?e:Qt(t,e%t),Oe=(e,t)=>e+(t-Qt(e,t)),Te=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function Qe(e,t,r,n){if(Je(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(Oe(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${Oe(t,r)}`);let i=0,s=0;const o=Te[t],c=Te[r]-1,a=[];for(const l of e){if(Gt(l),l>=o)throw new Error(`convertRadix2: invalid data word=${l} from=${t}`);if(i=i<<t|l,s+t>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${t}`);for(s+=t;s>=r;s-=r)a.push((i>>s-r&c)>>>0);const g=Te[s];if(g===void 0)throw new Error("invalid carry");i&=g-1}if(i=i<<r-s&c,!n&&s>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&s>0&&a.push(i>>>0),a}function or(e,t=!1){if(Gt(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(Oe(8,e)>32||Oe(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!Yt(r))throw new Error("radix2.encode input should be Uint8Array");return Qe(Array.from(r),8,e,!t)},decode:r=>(Jt("radix2.decode",r),Uint8Array.from(Qe(r,e,8,t)))}}function St(e){return nr(e),function(...t){try{return e.apply(null,t)}catch{}}}const et=rr(ir("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),sr("")),Rt=[996825010,642813549,513874426,1027748829,705979059];function fe(e){const t=e>>25;let r=(e&33554431)<<5;for(let n=0;n<Rt.length;n++)(t>>n&1)===1&&(r^=Rt[n]);return r}function It(e,t,r=1){const n=e.length;let i=1;for(let s=0;s<n;s++){const o=e.charCodeAt(s);if(o<33||o>126)throw new Error(`Invalid prefix (${e})`);i=fe(i)^o>>5}i=fe(i);for(let s=0;s<n;s++)i=fe(i)^e.charCodeAt(s)&31;for(let s of t)i=fe(i)^s;for(let s=0;s<6;s++)i=fe(i);return i^=r,et.encode(Qe([i%Te[30]],30,5,!1))}function ar(e){const t=e==="bech32"?1:734539939,r=or(5),n=r.decode,i=r.encode,s=St(n);function o(u,f,p=90){ye("bech32.encode prefix",u),Yt(f)&&(f=Array.from(f)),Jt("bech32.encode",f);const y=u.length;if(y===0)throw new TypeError(`Invalid prefix length ${y}`);const w=y+7+f.length;if(p!==!1&&w>p)throw new TypeError(`Length ${w} exceeds limit ${p}`);const $=u.toLowerCase(),N=It($,f,t);return`${$}1${et.encode(f)}${N}`}function c(u,f=90){ye("bech32.decode input",u);const p=u.length;if(p<8||f!==!1&&p>f)throw new TypeError(`invalid string length: ${p} (${u}). Expected (8..${f})`);const y=u.toLowerCase();if(u!==y&&u!==u.toUpperCase())throw new Error("String must be lowercase or uppercase");const w=y.lastIndexOf("1");if(w===0||w===-1)throw new Error('Letter "1" must be present between prefix and data only');const $=y.slice(0,w),N=y.slice(w+1);if(N.length<6)throw new Error("Data must be at least 6 characters long");const K=et.decode(N).slice(0,-6),Q=It($,K,t);if(!N.endsWith(Q))throw new Error(`Invalid checksum in ${u}: expected "${Q}"`);return{prefix:$,words:K}}const a=St(c);function l(u){const{prefix:f,words:p}=c(u,!1);return{prefix:f,words:p,bytes:n(p)}}function g(u,f){return o(u,i(f))}return{encode:o,decode:c,encodeFromBytes:g,decodeToBytes:l,decodeUnsafe:a,fromWords:n,fromWordsUnsafe:s,toWords:i}}const $t=ar("bech32");var Re=new TextDecoder("utf-8");new TextEncoder;var cr=5e3;function lr(e){try{return e.startsWith("nostr:")&&(e=e.substring(6)),dr(e)}catch{return{type:"invalid",data:null}}}function dr(e){let{prefix:t,words:r}=$t.decode(e,cr),n=new Uint8Array($t.fromWords(r));switch(t){case"nprofile":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nprofile");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");return{type:"nprofile",data:{pubkey:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nevent":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nevent");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");if(i[2]&&i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(i[3]&&i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:_(i[0][0]),relays:i[1]?i[1].map(s=>Re.decode(s)):[],author:i[2]?.[0]?_(i[2][0]):void 0,kind:i[3]?.[0]?parseInt(_(i[3][0]),16):void 0}}}case"naddr":{let i=Fe(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!i[2]?.[0])throw new Error("missing TLV 2 for naddr");if(i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(!i[3]?.[0])throw new Error("missing TLV 3 for naddr");if(i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:Re.decode(i[0][0]),pubkey:_(i[2][0]),kind:parseInt(_(i[3][0]),16),relays:i[1]?i[1].map(s=>Re.decode(s)):[]}}}case"nsec":return{type:t,data:n};case"npub":case"note":return{type:t,data:_(n)};default:throw new Error(`unknown prefix ${t}`)}}function Fe(e){let t={},r=e;for(;r.length>0;){let n=r[0],i=r[1],s=r.slice(2,2+i);if(r=r.slice(2+i),s.length<i)throw new Error(`not enough data to read on TLV ${n}`);t[n]=t[n]||[],t[n].push(s)}return t}function ur(e,t,r){return e&t^~e&r}function fr(e,t,r){return e&t^e&r^t&r}class hr{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(t,r,n,i){this.blockLen=t,this.outputLen=r,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(t),this.view=Me(this.buffer)}update(t){xt(this),j(t);const{view:r,buffer:n,blockLen:i}=this,s=t.length;for(let o=0;o<s;){const c=Math.min(i-this.pos,s-o);if(c===i){const a=Me(t);for(;i<=s-o;o+=i)this.process(a,o);continue}n.set(t.subarray(o,o+c),this.pos),this.pos+=c,o+=c,this.pos===i&&(this.process(r,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){xt(this),Jn(t,this),this.finished=!0;const{buffer:r,view:n,blockLen:i,isLE:s}=this;let{pos:o}=this;r[o++]=128,Xe(this.buffer.subarray(o)),this.padOffset>i-o&&(this.process(n,0),o=0);for(let u=o;u<i;u++)r[u]=0;n.setBigUint64(i-8,BigInt(this.length*8),s),this.process(n,0);const c=Me(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const l=a/4,g=this.get();if(l>g.length)throw new Error("_sha2: outputLen bigger than state");for(let u=0;u<l;u++)c.setUint32(4*u,g[u],s)}digest(){const{buffer:t,outputLen:r}=this;this.digestInto(t);const n=t.slice(0,r);return this.destroy(),n}_cloneInto(t){t||=new this.constructor,t.set(...this.get());const{blockLen:r,buffer:n,length:i,finished:s,destroyed:o,pos:c}=this;return t.destroyed=o,t.finished=s,t.length=i,t.pos=c,i%r&&t.buffer.set(n),t}clone(){return this._cloneInto()}}const ee=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),pr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),te=new Uint32Array(64);class gr extends hr{constructor(t){super(64,t,8,!1)}get(){const{A:t,B:r,C:n,D:i,E:s,F:o,G:c,H:a}=this;return[t,r,n,i,s,o,c,a]}set(t,r,n,i,s,o,c,a){this.A=t|0,this.B=r|0,this.C=n|0,this.D=i|0,this.E=s|0,this.F=o|0,this.G=c|0,this.H=a|0}process(t,r){for(let u=0;u<16;u++,r+=4)te[u]=t.getUint32(r,!1);for(let u=16;u<64;u++){const f=te[u-15],p=te[u-2],y=z(f,7)^z(f,18)^f>>>3,w=z(p,17)^z(p,19)^p>>>10;te[u]=w+te[u-7]+y+te[u-16]|0}let{A:n,B:i,C:s,D:o,E:c,F:a,G:l,H:g}=this;for(let u=0;u<64;u++){const f=z(c,6)^z(c,11)^z(c,25),p=g+f+ur(c,a,l)+pr[u]+te[u]|0,w=(z(n,2)^z(n,13)^z(n,22))+fr(n,i,s)|0;g=l,l=a,a=c,c=o+p|0,o=s,s=i,i=n,n=p+w|0}n=n+this.A|0,i=i+this.B|0,s=s+this.C|0,o=o+this.D|0,c=c+this.E|0,a=a+this.F|0,l=l+this.G|0,g=g+this.H|0,this.set(n,i,s,o,c,a,l,g)}roundClean(){Xe(te)}destroy(){this.set(0,0,0,0,0,0,0,0),Xe(this.buffer)}}class mr extends gr{A=ee[0]|0;B=ee[1]|0;C=ee[2]|0;D=ee[3]|0;E=ee[4]|0;F=ee[5]|0;G=ee[6]|0;H=ee[7]|0;constructor(){super(32)}}const Ne=er(()=>new mr,tr(1));/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const dt=BigInt(0),tt=BigInt(1);function Tt(e,t=""){if(typeof e!="boolean"){const r=t&&`"${t}" `;throw new Error(r+"expected boolean, got type="+typeof e)}return e}function yr(e){if(typeof e=="bigint"){if(!vr(e))throw new Error("positive bigint expected, got "+e)}else lt(e);return e}function en(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);return e===""?dt:BigInt("0x"+e)}function ut(e){return en(_(e))}function tn(e){return en(_(br(j(e)).reverse()))}function ft(e,t){lt(t),e=yr(e);const r=X(e.toString(16).padStart(t*2,"0"));if(r.length!==t)throw new Error("number too large");return r}function nn(e,t){return ft(e,t).reverse()}function br(e){return Uint8Array.from(e)}function wr(e){return Uint8Array.from(e,(t,r)=>{const n=t.charCodeAt(0);if(t.length!==1||n>127)throw new Error(`string contains non-ASCII character "${e[r]}" with code ${n} at position ${r}`);return n})}const vr=e=>typeof e=="bigint"&&dt<=e;function Er(e){let t;for(t=0;e>dt;e>>=tt,t+=1);return t}const rn=e=>(tt<<BigInt(e))-tt;function sn(e,t={},r={}){if(!e||typeof e!="object")throw new Error("expected valid options object");function n(s,o,c){const a=e[s];if(c&&a===void 0)return;const l=typeof a;if(l!==o||a===null)throw new Error(`param "${s}" is invalid: expected ${o}, got ${l}`)}const i=(s,o)=>Object.entries(s).forEach(([c,a])=>n(c,a,o));i(t,!1),i(r,!0)}function Bt(e){const t=new WeakMap;return(r,...n)=>{const i=t.get(r);if(i!==void 0)return i;const s=e(r,...n);return t.set(r,s),s}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const D=BigInt(0),H=BigInt(1),se=BigInt(2),on=BigInt(3),an=BigInt(4),cn=BigInt(5),xr=BigInt(7),ln=BigInt(8),kr=BigInt(9),dn=BigInt(16);function V(e,t){const r=e%t;return r>=D?r:t+r}function F(e,t,r){let n=e;for(;t-- >D;)n*=n,n%=r;return n}function At(e,t){if(e===D)throw new Error("invert: expected non-zero number");if(t<=D)throw new Error("invert: expected positive modulus, got "+t);let r=V(e,t),n=t,i=D,s=H;for(;r!==D;){const c=n/r,a=n%r,l=i-s*c;n=r,r=a,i=s,s=l}if(n!==H)throw new Error("invert: does not exist");return V(i,t)}function ht(e,t,r){if(!e.eql(e.sqr(t),r))throw new Error("Cannot find square root")}function un(e,t){const r=(e.ORDER+H)/an,n=e.pow(t,r);return ht(e,n,t),n}function Sr(e,t){const r=(e.ORDER-cn)/ln,n=e.mul(t,se),i=e.pow(n,r),s=e.mul(t,i),o=e.mul(e.mul(s,se),i),c=e.mul(s,e.sub(o,e.ONE));return ht(e,c,t),c}function Rr(e){const t=_e(e),r=fn(e),n=r(t,t.neg(t.ONE)),i=r(t,n),s=r(t,t.neg(n)),o=(e+xr)/dn;return(c,a)=>{let l=c.pow(a,o),g=c.mul(l,n);const u=c.mul(l,i),f=c.mul(l,s),p=c.eql(c.sqr(g),a),y=c.eql(c.sqr(u),a);l=c.cmov(l,g,p),g=c.cmov(f,u,y);const w=c.eql(c.sqr(g),a),$=c.cmov(l,g,w);return ht(c,$,a),$}}function fn(e){if(e<on)throw new Error("sqrt is not defined for small field");let t=e-H,r=0;for(;t%se===D;)t/=se,r++;let n=se;const i=_e(e);for(;Ot(i,n)===1;)if(n++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(r===1)return un;let s=i.pow(n,t);const o=(t+H)/se;return function(a,l){if(a.is0(l))return l;if(Ot(a,l)!==1)throw new Error("Cannot find square root");let g=r,u=a.mul(a.ONE,s),f=a.pow(l,t),p=a.pow(l,o);for(;!a.eql(f,a.ONE);){if(a.is0(f))return a.ZERO;let y=1,w=a.sqr(f);for(;!a.eql(w,a.ONE);)if(y++,w=a.sqr(w),y===g)throw new Error("Cannot find square root");const $=H<<BigInt(g-y-1),N=a.pow(u,$);g=y,u=a.sqr(N),f=a.mul(f,u),p=a.mul(p,N)}return p}}function Ir(e){return e%an===on?un:e%ln===cn?Sr:e%dn===kr?Rr(e):fn(e)}const $r=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function Tr(e){const t={ORDER:"bigint",BYTES:"number",BITS:"number"},r=$r.reduce((n,i)=>(n[i]="function",n),t);return sn(e,r),e}function Br(e,t,r){if(r<D)throw new Error("invalid exponent, negatives unsupported");if(r===D)return e.ONE;if(r===H)return t;let n=e.ONE,i=t;for(;r>D;)r&H&&(n=e.mul(n,i)),i=e.sqr(i),r>>=H;return n}function hn(e,t,r=!1){const n=new Array(t.length).fill(r?e.ZERO:void 0),i=t.reduce((o,c,a)=>e.is0(c)?o:(n[a]=o,e.mul(o,c)),e.ONE),s=e.inv(i);return t.reduceRight((o,c,a)=>e.is0(c)?o:(n[a]=e.mul(o,n[a]),e.mul(o,c)),s),n}function Ot(e,t){const r=(e.ORDER-H)/se,n=e.pow(t,r),i=e.eql(n,e.ONE),s=e.eql(n,e.ZERO),o=e.eql(n,e.neg(e.ONE));if(!i&&!s&&!o)throw new Error("invalid Legendre symbol result");return i?1:s?0:-1}function Ar(e,t){t!==void 0&&lt(t);const r=t!==void 0?t:e.toString(2).length,n=Math.ceil(r/8);return{nBitLength:r,nByteLength:n}}class Or{ORDER;BITS;BYTES;isLE;ZERO=D;ONE=H;_lengths;_sqrt;_mod;constructor(t,r={}){if(t<=D)throw new Error("invalid field: expected ORDER > 0, got "+t);let n;this.isLE=!1,r!=null&&typeof r=="object"&&(typeof r.BITS=="number"&&(n=r.BITS),typeof r.sqrt=="function"&&(this.sqrt=r.sqrt),typeof r.isLE=="boolean"&&(this.isLE=r.isLE),r.allowedLengths&&(this._lengths=r.allowedLengths?.slice()),typeof r.modFromBytes=="boolean"&&(this._mod=r.modFromBytes));const{nBitLength:i,nByteLength:s}=Ar(t,n);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=t,this.BITS=i,this.BYTES=s,this._sqrt=void 0,Object.preventExtensions(this)}create(t){return V(t,this.ORDER)}isValid(t){if(typeof t!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof t);return D<=t&&t<this.ORDER}is0(t){return t===D}isValidNot0(t){return!this.is0(t)&&this.isValid(t)}isOdd(t){return(t&H)===H}neg(t){return V(-t,this.ORDER)}eql(t,r){return t===r}sqr(t){return V(t*t,this.ORDER)}add(t,r){return V(t+r,this.ORDER)}sub(t,r){return V(t-r,this.ORDER)}mul(t,r){return V(t*r,this.ORDER)}pow(t,r){return Br(this,t,r)}div(t,r){return V(t*At(r,this.ORDER),this.ORDER)}sqrN(t){return t*t}addN(t,r){return t+r}subN(t,r){return t-r}mulN(t,r){return t*r}inv(t){return At(t,this.ORDER)}sqrt(t){return this._sqrt||(this._sqrt=Ir(this.ORDER)),this._sqrt(this,t)}toBytes(t){return this.isLE?nn(t,this.BYTES):ft(t,this.BYTES)}fromBytes(t,r=!1){j(t);const{_lengths:n,BYTES:i,isLE:s,ORDER:o,_mod:c}=this;if(n){if(!n.includes(t.length)||t.length>i)throw new Error("Field.fromBytes: expected "+n+" bytes, got "+t.length);const l=new Uint8Array(i);l.set(t,s?0:l.length-t.length),t=l}if(t.length!==i)throw new Error("Field.fromBytes: expected "+i+" bytes, got "+t.length);let a=s?tn(t):ut(t);if(c&&(a=V(a,o)),!r&&!this.isValid(a))throw new Error("invalid field element: outside of range 0..ORDER");return a}invertBatch(t){return hn(this,t)}cmov(t,r,n){return n?r:t}}function _e(e,t={}){return new Or(e,t)}function pn(e){if(typeof e!="bigint")throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function Nr(e){const t=pn(e);return t+Math.ceil(t/2)}function qr(e,t,r=!1){j(e);const n=e.length,i=pn(t),s=Nr(t);if(n<16||n<s||n>1024)throw new Error("expected "+s+"-1024 bytes of input, got "+n);const o=r?tn(e):ut(e),c=V(o,t-H)+H;return r?nn(c,i):ft(c,i)}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const le=BigInt(0),oe=BigInt(1);function qe(e,t){const r=t.negate();return e?r:t}function Nt(e,t){const r=hn(e.Fp,t.map(n=>n.Z));return t.map((n,i)=>e.fromAffine(n.toAffine(r[i])))}function gn(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new Error("invalid window size, expected [1.."+t+"], got W="+e)}function We(e,t){gn(e,t);const r=Math.ceil(t/e)+1,n=2**(e-1),i=2**e,s=rn(e),o=BigInt(e);return{windows:r,windowSize:n,mask:s,maxNumber:i,shiftBy:o}}function qt(e,t,r){const{windowSize:n,mask:i,maxNumber:s,shiftBy:o}=r;let c=Number(e&i),a=e>>o;c>n&&(c-=s,a+=oe);const l=t*n,g=l+Math.abs(c)-1,u=c===0,f=c<0,p=t%2!==0;return{nextN:a,offset:g,isZero:u,isNeg:f,isNegF:p,offsetF:l}}const Ze=new WeakMap,mn=new WeakMap;function Ve(e){return mn.get(e)||1}function Lt(e){if(e!==le)throw new Error("invalid wNAF")}class Lr{BASE;ZERO;Fn;bits;constructor(t,r){this.BASE=t.BASE,this.ZERO=t.ZERO,this.Fn=t.Fn,this.bits=r}_unsafeLadder(t,r,n=this.ZERO){let i=t;for(;r>le;)r&oe&&(n=n.add(i)),i=i.double(),r>>=oe;return n}precomputeWindow(t,r){const{windows:n,windowSize:i}=We(r,this.bits),s=[];let o=t,c=o;for(let a=0;a<n;a++){c=o,s.push(c);for(let l=1;l<i;l++)c=c.add(o),s.push(c);o=c.double()}return s}wNAF(t,r,n){if(!this.Fn.isValid(n))throw new Error("invalid scalar");let i=this.ZERO,s=this.BASE;const o=We(t,this.bits);for(let c=0;c<o.windows;c++){const{nextN:a,offset:l,isZero:g,isNeg:u,isNegF:f,offsetF:p}=qt(n,c,o);n=a,g?s=s.add(qe(f,r[p])):i=i.add(qe(u,r[l]))}return Lt(n),{p:i,f:s}}wNAFUnsafe(t,r,n,i=this.ZERO){const s=We(t,this.bits);for(let o=0;o<s.windows&&n!==le;o++){const{nextN:c,offset:a,isZero:l,isNeg:g}=qt(n,o,s);if(n=c,!l){const u=r[a];i=i.add(g?u.negate():u)}}return Lt(n),i}getPrecomputes(t,r,n){let i=Ze.get(r);return i||(i=this.precomputeWindow(r,t),t!==1&&(typeof n=="function"&&(i=n(i)),Ze.set(r,i))),i}cached(t,r,n){const i=Ve(t);return this.wNAF(i,this.getPrecomputes(i,t,n),r)}unsafe(t,r,n,i){const s=Ve(t);return s===1?this._unsafeLadder(t,r,i):this.wNAFUnsafe(s,this.getPrecomputes(s,t,n),r,i)}createCache(t,r){gn(r,this.bits),mn.set(t,r),Ze.delete(t)}hasCache(t){return Ve(t)!==1}}function Pr(e,t,r,n){let i=t,s=e.ZERO,o=e.ZERO;for(;r>le||n>le;)r&oe&&(s=s.add(i)),n&oe&&(o=o.add(i)),i=i.double(),r>>=oe,n>>=oe;return{p1:s,p2:o}}function Pt(e,t,r){if(t){if(t.ORDER!==e)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return Tr(t),t}else return _e(e,{isLE:r})}function _r(e,t,r={},n){if(n===void 0&&(n=e==="edwards"),!t||typeof t!="object")throw new Error(`expected valid ${e} CURVE object`);for(const a of["p","n","h"]){const l=t[a];if(!(typeof l=="bigint"&&l>le))throw new Error(`CURVE.${a} must be positive bigint`)}const i=Pt(t.p,r.Fp,n),s=Pt(t.n,r.Fn,n),c=["Gx","Gy","a","b"];for(const a of c)if(!i.isValid(t[a]))throw new Error(`CURVE.${a} must be valid field element of CURVE.Fp`);return t=Object.freeze(Object.assign({},t)),{CURVE:t,Fp:i,Fn:s}}function Cr(e,t){return function(n){const i=e(n);return{secretKey:i,publicKey:t(i)}}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const _t=(e,t)=>(e+(e>=0?t:-t)/Hr)/t;function Ur(e,t,r){const[[n,i],[s,o]]=t,c=_t(o*e,r),a=_t(-i*e,r);let l=e-c*n-a*s,g=-c*i-a*o;const u=l<he,f=g<he;u&&(l=-l),f&&(g=-g);const p=rn(Math.ceil(Er(r)/2))+Be;if(l<he||l>=p||g<he||g>=p)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:u,k1:l,k2neg:f,k2:g}}const he=BigInt(0),Be=BigInt(1),Hr=BigInt(2),Ie=BigInt(3),Dr=BigInt(4);function jr(e,t={}){const r=_r("weierstrass",e,t),{Fp:n,Fn:i}=r;let s=r.CURVE;const{h:o,n:c}=s;sn(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:a}=t;if(a&&(!n.is0(s.a)||typeof a.beta!="bigint"||!Array.isArray(a.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const l=Fr(n,i);function g(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}function u(T,m,b){const{x:E,y:x}=m.toAffine(),B=n.toBytes(E);if(Tt(b,"isCompressed"),b){g();const R=!n.isOdd(x);return Ae(Mr(R),B)}else return Ae(Uint8Array.of(4),B,n.toBytes(x))}function f(T){j(T,void 0,"Point");const{publicKey:m,publicKeyUncompressed:b}=l,E=T.length,x=T[0],B=T.subarray(1);if(E===m&&(x===2||x===3)){const R=n.fromBytes(B);if(!n.isValid(R))throw new Error("bad point: is not on curve, wrong x");const k=w(R);let v;try{v=n.sqrt(k)}catch(M){const P=M instanceof Error?": "+M.message:"";throw new Error("bad point: is not on curve, sqrt error"+P)}g();const S=n.isOdd(v);return(x&1)===1!==S&&(v=n.neg(v)),{x:R,y:v}}else if(E===b&&x===4){const R=n.BYTES,k=n.fromBytes(B.subarray(0,R)),v=n.fromBytes(B.subarray(R,R*2));if(!$(k,v))throw new Error("bad point: is not on curve");return{x:k,y:v}}else throw new Error(`bad point: got length ${E}, expected compressed=${m} or uncompressed=${b}`)}const p=t.toBytes||u,y=t.fromBytes||f;function w(T){const m=n.sqr(T),b=n.mul(m,T);return n.add(n.add(b,n.mul(T,s.a)),s.b)}function $(T,m){const b=n.sqr(m),E=w(T);return n.eql(b,E)}if(!$(s.Gx,s.Gy))throw new Error("bad curve params: generator point");const N=n.mul(n.pow(s.a,Ie),Dr),K=n.mul(n.sqr(s.b),BigInt(27));if(n.is0(n.add(N,K)))throw new Error("bad curve params: a or b");function Q(T,m,b=!1){if(!n.isValid(m)||b&&n.is0(m))throw new Error(`bad point coordinate ${T}`);return m}function we(T){if(!(T instanceof O))throw new Error("Weierstrass Point expected")}function ve(T){if(!a||!a.basises)throw new Error("no endo");return Ur(T,a.basises,i.ORDER)}const Ee=Bt((T,m)=>{const{X:b,Y:E,Z:x}=T;if(n.eql(x,n.ONE))return{x:b,y:E};const B=T.is0();m==null&&(m=B?n.ONE:n.inv(x));const R=n.mul(b,m),k=n.mul(E,m),v=n.mul(x,m);if(B)return{x:n.ZERO,y:n.ZERO};if(!n.eql(v,n.ONE))throw new Error("invZ was invalid");return{x:R,y:k}}),Rn=Bt(T=>{if(T.is0()){if(t.allowInfinityPoint&&!n.is0(T.Y))return;throw new Error("bad point: ZERO")}const{x:m,y:b}=T.toAffine();if(!n.isValid(m)||!n.isValid(b))throw new Error("bad point: x or y not field elements");if(!$(m,b))throw new Error("bad point: equation left != right");if(!T.isTorsionFree())throw new Error("bad point: not in prime-order subgroup");return!0});function mt(T,m,b,E,x){return b=new O(n.mul(b.X,T),b.Y,b.Z),m=qe(E,m),b=qe(x,b),m.add(b)}class O{static BASE=new O(s.Gx,s.Gy,n.ONE);static ZERO=new O(n.ZERO,n.ONE,n.ZERO);static Fp=n;static Fn=i;X;Y;Z;constructor(m,b,E){this.X=Q("x",m),this.Y=Q("y",b,!0),this.Z=Q("z",E),Object.freeze(this)}static CURVE(){return s}static fromAffine(m){const{x:b,y:E}=m||{};if(!m||!n.isValid(b)||!n.isValid(E))throw new Error("invalid affine point");if(m instanceof O)throw new Error("projective point not allowed");return n.is0(b)&&n.is0(E)?O.ZERO:new O(b,E,n.ONE)}static fromBytes(m){const b=O.fromAffine(y(j(m,void 0,"point")));return b.assertValidity(),b}static fromHex(m){return O.fromBytes(X(m))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(m=8,b=!0){return ue.createCache(this,m),b||this.multiply(Ie),this}assertValidity(){Rn(this)}hasEvenY(){const{y:m}=this.toAffine();if(!n.isOdd)throw new Error("Field doesn't support isOdd");return!n.isOdd(m)}equals(m){we(m);const{X:b,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=m,v=n.eql(n.mul(b,k),n.mul(B,x)),S=n.eql(n.mul(E,k),n.mul(R,x));return v&&S}negate(){return new O(this.X,n.neg(this.Y),this.Z)}double(){const{a:m,b}=s,E=n.mul(b,Ie),{X:x,Y:B,Z:R}=this;let k=n.ZERO,v=n.ZERO,S=n.ZERO,I=n.mul(x,x),M=n.mul(B,B),P=n.mul(R,R),A=n.mul(x,B);return A=n.add(A,A),S=n.mul(x,R),S=n.add(S,S),k=n.mul(m,S),v=n.mul(E,P),v=n.add(k,v),k=n.sub(M,v),v=n.add(M,v),v=n.mul(k,v),k=n.mul(A,k),S=n.mul(E,S),P=n.mul(m,P),A=n.sub(I,P),A=n.mul(m,A),A=n.add(A,S),S=n.add(I,I),I=n.add(S,I),I=n.add(I,P),I=n.mul(I,A),v=n.add(v,I),P=n.mul(B,R),P=n.add(P,P),I=n.mul(P,A),k=n.sub(k,I),S=n.mul(P,M),S=n.add(S,S),S=n.add(S,S),new O(k,v,S)}add(m){we(m);const{X:b,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=m;let v=n.ZERO,S=n.ZERO,I=n.ZERO;const M=s.a,P=n.mul(s.b,Ie);let A=n.mul(b,B),W=n.mul(E,R),Z=n.mul(x,k),ae=n.add(b,E),U=n.add(B,R);ae=n.mul(ae,U),U=n.add(A,W),ae=n.sub(ae,U),U=n.add(b,x);let Y=n.add(B,k);return U=n.mul(U,Y),Y=n.add(A,Z),U=n.sub(U,Y),Y=n.add(E,x),v=n.add(R,k),Y=n.mul(Y,v),v=n.add(W,Z),Y=n.sub(Y,v),I=n.mul(M,U),v=n.mul(P,Z),I=n.add(v,I),v=n.sub(W,I),I=n.add(W,I),S=n.mul(v,I),W=n.add(A,A),W=n.add(W,A),Z=n.mul(M,Z),U=n.mul(P,U),W=n.add(W,Z),Z=n.sub(A,Z),Z=n.mul(M,Z),U=n.add(U,Z),A=n.mul(W,U),S=n.add(S,A),A=n.mul(Y,U),v=n.mul(ae,v),v=n.sub(v,A),A=n.mul(ae,W),I=n.mul(Y,I),I=n.add(I,A),new O(v,S,I)}subtract(m){return this.add(m.negate())}is0(){return this.equals(O.ZERO)}multiply(m){const{endo:b}=t;if(!i.isValidNot0(m))throw new Error("invalid scalar: out of range");let E,x;const B=R=>ue.cached(this,R,k=>Nt(O,k));if(b){const{k1neg:R,k1:k,k2neg:v,k2:S}=ve(m),{p:I,f:M}=B(k),{p:P,f:A}=B(S);x=M.add(A),E=mt(b.beta,I,P,R,v)}else{const{p:R,f:k}=B(m);E=R,x=k}return Nt(O,[E,x])[0]}multiplyUnsafe(m){const{endo:b}=t,E=this;if(!i.isValid(m))throw new Error("invalid scalar: out of range");if(m===he||E.is0())return O.ZERO;if(m===Be)return E;if(ue.hasCache(this))return this.multiply(m);if(b){const{k1neg:x,k1:B,k2neg:R,k2:k}=ve(m),{p1:v,p2:S}=Pr(O,E,B,k);return mt(b.beta,v,S,x,R)}else return ue.unsafe(E,m)}toAffine(m){return Ee(this,m)}isTorsionFree(){const{isTorsionFree:m}=t;return o===Be?!0:m?m(O,this):ue.unsafe(this,c).is0()}clearCofactor(){const{clearCofactor:m}=t;return o===Be?this:m?m(O,this):this.multiplyUnsafe(o)}isSmallOrder(){return this.multiplyUnsafe(o).is0()}toBytes(m=!0){return Tt(m,"isCompressed"),this.assertValidity(),p(O,this,m)}toHex(m=!0){return _(this.toBytes(m))}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const yt=i.BITS,ue=new Lr(O,t.endo?Math.ceil(yt/2):yt);return O.BASE.precompute(8),O}function Mr(e){return Uint8Array.of(e?2:3)}function Fr(e,t){return{secretKey:t.BYTES,publicKey:1+e.BYTES,publicKeyUncompressed:1+2*e.BYTES,publicKeyHasPrefix:!0,signature:2*t.BYTES}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const Ce={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},Wr={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},Zr=BigInt(0),nt=BigInt(2);function Vr(e){const t=Ce.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),s=BigInt(22),o=BigInt(23),c=BigInt(44),a=BigInt(88),l=e*e*e%t,g=l*l*e%t,u=F(g,r,t)*g%t,f=F(u,r,t)*g%t,p=F(f,nt,t)*l%t,y=F(p,i,t)*p%t,w=F(y,s,t)*y%t,$=F(w,c,t)*w%t,N=F($,a,t)*$%t,K=F(N,c,t)*w%t,Q=F(K,r,t)*g%t,we=F(Q,o,t)*y%t,ve=F(we,n,t)*l%t,Ee=F(ve,nt,t);if(!Le.eql(Le.sqr(Ee),e))throw new Error("Cannot find square root");return Ee}const Le=_e(Ce.p,{sqrt:Vr}),de=jr(Ce,{Fp:Le,endo:Wr}),Ct={};function Pe(e,...t){let r=Ct[e];if(r===void 0){const n=Ne(wr(e));r=Ae(n,n),Ct[e]=r}return Ne(Ae(r,...t))}const pt=e=>e.toBytes(!0).slice(1),gt=e=>e%nt===Zr;function rt(e){const{Fn:t,BASE:r}=de,n=t.fromBytes(e),i=r.multiply(n);return{scalar:gt(i.y)?n:t.neg(n),bytes:pt(i)}}function yn(e){const t=Le;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);gt(i)||(i=t.neg(i));const s=de.fromAffine({x:e,y:i});return s.assertValidity(),s}const me=ut;function bn(...e){return de.Fn.create(me(Pe("BIP0340/challenge",...e)))}function Ut(e){return rt(e).bytes}function Kr(e,t,r=Kt(32)){const{Fn:n}=de,i=j(e,void 0,"message"),{bytes:s,scalar:o}=rt(t),c=j(r,32,"auxRand"),a=n.toBytes(o^me(Pe("BIP0340/aux",c))),l=Pe("BIP0340/nonce",a,s,i),{bytes:g,scalar:u}=rt(l),f=bn(g,s,i),p=new Uint8Array(64);if(p.set(g,0),p.set(n.toBytes(n.create(u+f*o)),32),!wn(p,i,s))throw new Error("sign: Invalid signature produced");return p}function wn(e,t,r){const{Fp:n,Fn:i,BASE:s}=de,o=j(e,64,"signature"),c=j(t,void 0,"message"),a=j(r,32,"publicKey");try{const l=yn(me(a)),g=me(o.subarray(0,32));if(!n.isValidNot0(g))return!1;const u=me(o.subarray(32,64));if(!i.isValidNot0(u))return!1;const f=bn(i.toBytes(g),pt(l),c),p=s.multiplyUnsafe(u).add(l.multiplyUnsafe(i.neg(f))),{x:y,y:w}=p.toAffine();return!(p.is0()||!gt(w)||y!==g)}catch{return!1}}const G=(()=>{const r=(n=Kt(48))=>qr(n,Ce.n);return{keygen:Cr(r,Ut),getPublicKey:Ut,sign:Kr,verify:wn,Point:de,utils:{randomSecretKey:r,taggedHash:Pe,lift_x:yn,pointToBytes:pt},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})();var ie=Symbol("verified"),Yr=e=>e instanceof Object;function zr(e){if(!Yr(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var Gr=new TextEncoder;function pe(e){try{e.indexOf("://")===-1&&(e="wss://"+e);let t=new URL(e);return t.protocol==="http:"?t.protocol="ws:":t.protocol==="https:"&&(t.protocol="wss:"),t.pathname=t.pathname.replace(/\/+/g,"/"),t.pathname.endsWith("/")&&(t.pathname=t.pathname.slice(0,-1)),(t.port==="80"&&t.protocol==="ws:"||t.port==="443"&&t.protocol==="wss:")&&(t.port=""),t.searchParams.sort(),t.hash="",t.toString()}catch{throw new Error(`Invalid URL: ${e}`)}}var Xr=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(t){return _(G.getPublicKey(t))}finalizeEvent(t,r){const n=t;return n.pubkey=_(G.getPublicKey(r)),n.id=Ke(n),n.sig=_(G.sign(X(Ke(n)),r)),n[ie]=!0,n}verifyEvent(t){if(typeof t[ie]=="boolean")return t[ie];try{const r=Ke(t);if(r!==t.id)return t[ie]=!1,!1;const n=G.verify(X(t.sig),X(r),X(t.pubkey));return t[ie]=n,n}catch{return t[ie]=!1,!1}}};function Jr(e){if(!zr(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ke(e){let t=Ne(Gr.encode(Jr(e)));return _(t)}var Ue=new Xr;Ue.generateSecretKey;Ue.getPublicKey;Ue.finalizeEvent;var Qr=Ue.verifyEvent,ei=22242;function ti(e,t){if(e.ids&&e.ids.indexOf(t.id)===-1||e.kinds&&e.kinds.indexOf(t.kind)===-1||e.authors&&e.authors.indexOf(t.pubkey)===-1)return!1;for(let r in e)if(r[0]==="#"){let n=r.slice(1),i=e[`#${n}`];if(i&&!t.tags.find(([s,o])=>s===r.slice(1)&&i.indexOf(o)!==-1))return!1}return!(e.since&&t.created_at<e.since||e.until&&t.created_at>e.until)}function ni(e,t){for(let r=0;r<e.length;r++)if(ti(e[r],t))return!0;return!1}function ri(e,t){let r=t.length+3,n=e.indexOf(`"${t}":`)+r,i=e.slice(n).indexOf('"')+n+1;return e.slice(i,i+64)}function ii(e){let t=e.slice(0,22).indexOf('"EVENT"');if(t===-1)return null;let r=e.slice(t+7+1).indexOf('"');if(r===-1)return null;let n=t+7+1+r,i=e.slice(n+1,80).indexOf('"');if(i===-1)return null;let s=n+1+i;return e.slice(n+1,s)}function si(e,t){return{kind:ei,created_at:Math.floor(Date.now()/1e3),tags:[["relay",e],["challenge",t]],content:""}}var vn=class extends Error{constructor(e,t){super(`Tried to send message '${e} on a closed connection to ${t}.`),this.name="SendingOnClosedConnection"}},En=class{url;_connected=!1;onclose=null;onnotice=e=>console.debug(`NOTICE from ${this.url}: ${e}`);onauth;baseEoseTimeout=4400;publishTimeout=4400;pingFrequency=29e3;pingTimeout=2e4;resubscribeBackoff=[1e4,1e4,1e4,2e4,2e4,3e4,6e4];openSubs=new Map;enablePing;enableReconnect;idleSince=Date.now();ongoingOperations=0;reconnectTimeoutHandle;pingIntervalHandle;reconnectAttempts=0;skipReconnection=!1;connectionPromise;openCountRequests=new Map;openEventPublishes=new Map;ws;challenge;authPromise;serial=0;verifyEvent;_WebSocket;constructor(e,t){this.url=pe(e),this.verifyEvent=t.verifyEvent,this._WebSocket=t.websocketImplementation||WebSocket,this.enablePing=t.enablePing,this.enableReconnect=t.enableReconnect||!1}static async connect(e,t){const r=new En(e,t);return await r.connect(t),r}closeAllSubscriptions(e){for(let[t,r]of this.openSubs)r.close(e);this.openSubs.clear();for(let[t,r]of this.openEventPublishes)r.reject(new Error(e));this.openEventPublishes.clear();for(let[t,r]of this.openCountRequests)r.reject(new Error(e));this.openCountRequests.clear()}get connected(){return this._connected}async reconnect(){const e=this.resubscribeBackoff[Math.min(this.reconnectAttempts,this.resubscribeBackoff.length-1)];this.reconnectAttempts++,this.reconnectTimeoutHandle=setTimeout(async()=>{try{await this.connect()}catch{}},e)}handleHardClose(e){this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this._connected=!1,this.connectionPromise=void 0,this.idleSince=void 0,this.enableReconnect&&!this.skipReconnection?this.reconnect():(this.onclose?.(),this.closeAllSubscriptions(e))}async connect(e){let t;return this.connectionPromise?this.connectionPromise:(this.challenge=void 0,this.authPromise=void 0,this.skipReconnection=!1,this.connectionPromise=new Promise((r,n)=>{e?.timeout&&(t=setTimeout(()=>{n("connection timed out"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection timed out")},e.timeout)),e?.abort&&(e.abort.onabort=n);try{this.ws=new this._WebSocket(this.url)}catch(i){clearTimeout(t),n(i);return}this.ws.onopen=()=>{this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),clearTimeout(t),this._connected=!0;const i=this.reconnectAttempts>0;this.reconnectAttempts=0;for(const s of this.openSubs.values()){if(s.eosed=!1,i)for(let o=0;o<s.filters.length;o++)s.lastEmitted&&(s.filters[o].since=s.lastEmitted+1);s.fire()}this.enablePing&&(this.pingIntervalHandle=setInterval(()=>this.pingpong(),this.pingFrequency)),r()},this.ws.onerror=()=>{clearTimeout(t),n("connection failed"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection failed")},this.ws.onclose=i=>{clearTimeout(t),n(i.message||"websocket closed"),this.handleHardClose("relay connection closed")},this.ws.onmessage=this._onmessage.bind(this)}),this.connectionPromise)}waitForPingPong(){return new Promise(e=>{this.ws.once("pong",()=>e(!0)),this.ws.ping()})}waitForDummyReq(){return new Promise((e,t)=>{if(!this.connectionPromise)return t(new Error(`no connection to ${this.url}, can't ping`));try{const r=this.subscribe([{ids:["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],limit:0}],{label:"<forced-ping>",oneose:()=>{e(!0),r.close()},onclose(){e(!0)},eoseTimeout:this.pingTimeout+1e3})}catch(r){t(r)}})}async pingpong(){this.ws?.readyState===1&&(await Promise.any([this.ws&&this.ws.ping&&this.ws.once?this.waitForPingPong():this.waitForDummyReq(),new Promise(t=>setTimeout(()=>t(!1),this.pingTimeout))])||this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close())}async send(e){if(!this.connectionPromise)throw new vn(e,this.url);this.connectionPromise.then(()=>{this.ws?.send(e)})}async auth(e){const t=this.challenge;if(!t)throw new Error("can't perform auth, no challenge was received");return this.authPromise?this.authPromise:(this.authPromise=new Promise(async(r,n)=>{try{let i=await e(si(this.url,t)),s=setTimeout(()=>{let o=this.openEventPublishes.get(i.id);o&&(o.reject(new Error("auth timed out")),this.openEventPublishes.delete(i.id))},this.publishTimeout);this.openEventPublishes.set(i.id,{resolve:r,reject:n,timeout:s}),this.send('["AUTH",'+JSON.stringify(i)+"]")}catch(i){console.warn("subscribe auth function failed:",i)}}),this.authPromise)}async publish(e){this.idleSince=void 0,this.ongoingOperations++;const t=new Promise((r,n)=>{const i=setTimeout(()=>{const s=this.openEventPublishes.get(e.id);s&&(s.reject(new Error("publish timed out")),this.openEventPublishes.delete(e.id))},this.publishTimeout);this.openEventPublishes.set(e.id,{resolve:r,reject:n,timeout:i})});return this.send('["EVENT",'+JSON.stringify(e)+"]"),this.ongoingOperations--,this.ongoingOperations===0&&(this.idleSince=Date.now()),t}async count(e,t){this.serial++;const r=t?.id||"count:"+this.serial,n=new Promise((i,s)=>{this.openCountRequests.set(r,{resolve:i,reject:s})});return this.send('["COUNT","'+r+'",'+JSON.stringify(e).substring(1)),n}subscribe(e,t){t.label!=="<forced-ping>"&&(this.idleSince=void 0,this.ongoingOperations++);const r=this.prepareSubscription(e,t);return r.fire(),t.abort&&(t.abort.onabort=()=>r.close(String(t.abort.reason||"<aborted>"))),r}prepareSubscription(e,t){this.serial++;const r=t.id||(t.label?t.label+":":"sub:")+this.serial,n=new oi(this,r,e,t);return this.openSubs.set(r,n),n}close(){this.skipReconnection=!0,this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this.closeAllSubscriptions("relay connection closed by us"),this._connected=!1,this.idleSince=void 0,this.onclose?.(),this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close()}_onmessage(e){const t=e.data;if(!t)return;const r=ii(t);if(r){const n=this.openSubs.get(r);if(!n)return;const i=ri(t,"id"),s=n.alreadyHaveEvent?.(i);if(n.receivedEvent?.(this,i),s)return}try{let n=JSON.parse(t);switch(n[0]){case"EVENT":{const i=this.openSubs.get(n[1]),s=n[2];this.verifyEvent(s)&&ni(i.filters,s)?i.onevent(s):i.oninvalidevent?.(s),(!i.lastEmitted||i.lastEmitted<s.created_at)&&(i.lastEmitted=s.created_at);return}case"COUNT":{const i=n[1],s=n[2],o=this.openCountRequests.get(i);o&&(o.resolve(s.count),this.openCountRequests.delete(i));return}case"EOSE":{const i=this.openSubs.get(n[1]);if(!i)return;i.receivedEose();return}case"OK":{const i=n[1],s=n[2],o=n[3],c=this.openEventPublishes.get(i);c&&(clearTimeout(c.timeout),s?c.resolve(o):c.reject(new Error(o)),this.openEventPublishes.delete(i));return}case"CLOSED":{const i=n[1],s=this.openSubs.get(i);if(!s)return;s.closed=!0,s.close(n[2]);return}case"NOTICE":{this.onnotice(n[1]);return}case"AUTH":{this.challenge=n[1],this.onauth&&this.auth(this.onauth);return}default:{this.openSubs.get(n[1])?.oncustom?.(n);return}}}catch(n){try{const[i,s,o]=JSON.parse(t);console.warn(`[nostr] relay ${this.url} error processing message:`,n,o)}catch{console.warn(`[nostr] relay ${this.url} error processing message:`,n)}return}}},oi=class{relay;id;lastEmitted;closed=!1;eosed=!1;filters;alreadyHaveEvent;receivedEvent;onevent;oninvalidevent;oneose;onclose;oncustom;eoseTimeout;eoseTimeoutHandle;constructor(e,t,r,n){if(r.length===0)throw new Error("subscription can't be created with zero filters");this.relay=e,this.filters=r,this.id=t,this.alreadyHaveEvent=n.alreadyHaveEvent,this.receivedEvent=n.receivedEvent,this.eoseTimeout=n.eoseTimeout||e.baseEoseTimeout,this.oneose=n.oneose,this.onclose=n.onclose,this.oninvalidevent=n.oninvalidevent,this.onevent=n.onevent||(i=>{console.warn(`onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,i)})}fire(){this.relay.send('["REQ","'+this.id+'",'+JSON.stringify(this.filters).substring(1)),this.eoseTimeoutHandle=setTimeout(this.receivedEose.bind(this),this.eoseTimeout)}receivedEose(){this.eosed||(clearTimeout(this.eoseTimeoutHandle),this.eosed=!0,this.oneose?.())}close(e="closed by caller"){if(!this.closed&&this.relay.connected){try{this.relay.send('["CLOSE",'+JSON.stringify(this.id)+"]")}catch(t){if(!(t instanceof vn))throw t}this.closed=!0}this.relay.openSubs.delete(this.id),this.relay.ongoingOperations--,this.relay.ongoingOperations===0&&(this.relay.idleSince=Date.now()),this.onclose?.(e)}},ai=e=>(e[ie]=!0,!0),ci=class{relays=new Map;seenOn=new Map;trackRelays=!1;verifyEvent;enablePing;enableReconnect;automaticallyAuth;trustedRelayURLs=new Set;onRelayConnectionFailure;onRelayConnectionSuccess;allowConnectingToRelay;maxWaitForConnection;_WebSocket;constructor(e){this.verifyEvent=e.verifyEvent,this._WebSocket=e.websocketImplementation,this.enablePing=e.enablePing,this.enableReconnect=e.enableReconnect||!1,this.automaticallyAuth=e.automaticallyAuth,this.onRelayConnectionFailure=e.onRelayConnectionFailure,this.onRelayConnectionSuccess=e.onRelayConnectionSuccess,this.allowConnectingToRelay=e.allowConnectingToRelay,this.maxWaitForConnection=e.maxWaitForConnection||3e3}async ensureRelay(e,t){e=pe(e);let r=this.relays.get(e);if(r||(r=new En(e,{verifyEvent:this.trustedRelayURLs.has(e)?ai:this.verifyEvent,websocketImplementation:this._WebSocket,enablePing:this.enablePing,enableReconnect:this.enableReconnect}),r.onclose=()=>{this.relays.delete(e)},this.relays.set(e,r)),this.automaticallyAuth){const n=this.automaticallyAuth(e);n&&(r.onauth=n)}try{await r.connect({timeout:t?.connectionTimeout,abort:t?.abort})}catch(n){throw this.relays.delete(e),n}return r}close(e){e.map(pe).forEach(t=>{this.relays.get(t)?.close(),this.relays.delete(t)})}subscribe(e,t,r){const n=[],i=[];for(let s=0;s<e.length;s++){const o=pe(e[s]);n.find(c=>c.url===o)||i.indexOf(o)===-1&&(i.push(o),n.push({url:o,filter:t}))}return this.subscribeMap(n,r)}subscribeMany(e,t,r){return this.subscribe(e,t,r)}subscribeMap(e,t){const r=new Map;for(const f of e){const{url:p,filter:y}=f;r.has(p)||r.set(p,[]),r.get(p).push(y)}const n=Array.from(r.entries()).map(([f,p])=>({url:f,filters:p}));this.trackRelays&&(t.receivedEvent=(f,p)=>{let y=this.seenOn.get(p);y||(y=new Set,this.seenOn.set(p,y)),y.add(f)});const i=new Set,s=[],o=[];let c=f=>{o[f]||(o[f]=!0,o.filter(p=>p).length===n.length&&(t.oneose?.(),c=()=>{}))};const a=[];let l=(f,p)=>{a[f]||(c(f),a[f]=p,a.filter(y=>y).length===n.length&&(t.onclose?.(a),l=()=>{}))};const g=f=>{if(t.alreadyHaveEvent?.(f))return!0;const p=i.has(f);return i.add(f),p},u=Promise.all(n.map(async({url:f,filters:p},y)=>{if(this.allowConnectingToRelay?.(f,["read",p])===!1){l(y,"connection skipped by allowConnectingToRelay");return}let w;try{w=await this.ensureRelay(f,{connectionTimeout:this.maxWaitForConnection<(t.maxWait||0)?Math.max(t.maxWait*.8,t.maxWait-1e3):this.maxWaitForConnection,abort:t.abort})}catch(N){this.onRelayConnectionFailure?.(f),l(y,N?.message||String(N));return}this.onRelayConnectionSuccess?.(f);let $=w.subscribe(p,{...t,oneose:()=>c(y),onclose:N=>{N.startsWith("auth-required: ")&&t.onauth?w.auth(t.onauth).then(()=>{w.subscribe(p,{...t,oneose:()=>c(y),onclose:K=>{l(y,K)},alreadyHaveEvent:g,eoseTimeout:t.maxWait,abort:t.abort})}).catch(K=>{l(y,`auth was required and attempted, but failed with: ${K}`)}):l(y,N)},alreadyHaveEvent:g,eoseTimeout:t.maxWait,abort:t.abort});s.push($)}));return{async close(f){await u,s.forEach(p=>{p.close(f)})}}}subscribeEose(e,t,r){let n;return n=this.subscribe(e,t,{...r,oneose(){const i="closed automatically on eose";n?n.close(i):r.onclose?.(e.map(s=>i))}}),n}subscribeManyEose(e,t,r){return this.subscribeEose(e,t,r)}async querySync(e,t,r){return new Promise(async n=>{const i=[];this.subscribeEose(e,t,{...r,onevent(s){i.push(s)},onclose(s){n(i)}})})}async get(e,t,r){t.limit=1;const n=await this.querySync(e,t,r);return n.sort((i,s)=>s.created_at-i.created_at),n[0]||null}publish(e,t,r){return e.map(pe).map(async(n,i,s)=>{if(s.indexOf(n)!==i)return Promise.reject("duplicate url");if(this.allowConnectingToRelay?.(n,["write",t])===!1)return Promise.reject("connection skipped by allowConnectingToRelay");let o;try{o=await this.ensureRelay(n,{connectionTimeout:this.maxWaitForConnection<(r?.maxWait||0)?Math.max(r.maxWait*.8,r.maxWait-1e3):this.maxWaitForConnection,abort:r?.abort})}catch(c){return this.onRelayConnectionFailure?.(n),"connection failure: "+String(c)}return o.publish(t).catch(async c=>{if(c instanceof Error&&c.message.startsWith("auth-required: ")&&r?.onauth)return await o.auth(r.onauth),o.publish(t);throw c}).then(c=>{if(this.trackRelays){let a=this.seenOn.get(t.id);a||(a=new Set,this.seenOn.set(t.id,a)),a.add(o)}return c})})}listConnectionStatus(){const e=new Map;return this.relays.forEach((t,r)=>e.set(r,t.connected)),e}destroy(){this.relays.forEach(e=>e.close()),this.relays=new Map}pruneIdleRelays(e=1e4){const t=[];for(const[r,n]of this.relays)n.idleSince&&Date.now()-n.idleSince>=e&&(this.relays.delete(r),t.push(r),n.close());return t}},xn;try{xn=WebSocket}catch{}var li=class extends ci{constructor(e){super({verifyEvent:Qr,websocketImplementation:xn,maxWaitForConnection:3e3,...e})}},ce=Symbol("verified"),di=e=>e instanceof Object;function ui(e){if(!di(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var fi=new TextEncoder,hi=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(e){return _(G.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=_(G.getPublicKey(t)),r.id=Ye(r),r.sig=_(G.sign(X(Ye(r)),t)),r[ce]=!0,r}verifyEvent(e){if(typeof e[ce]=="boolean")return e[ce];try{const t=Ye(e);if(t!==e.id)return e[ce]=!1,!1;const r=G.verify(X(e.sig),X(t),X(e.pubkey));return e[ce]=r,r}catch{return e[ce]=!1,!1}}};function pi(e){if(!ui(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ye(e){let t=Ne(fi.encode(pi(e)));return _(t)}var He=new hi;He.generateSecretKey;He.getPublicKey;He.finalizeEvent;var gi=He.verifyEvent;const mi=8e3;function yi(e){return typeof e=="number"&&at.includes(e)}function bi(e){try{const t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function wi(e){const t=[];for(const r of e??[])try{const n=new URL(r);if(n.protocol!=="ws:"&&n.protocol!=="wss:")continue;t.push(n.href)}catch{}return[...new Set(t)]}function vi(e){const t=lr(e.trim());if(t.type!=="nevent"&&t.type!=="naddr")throw new Error("Enter a NIP-19 nevent or naddr for a NIP-5D napplet manifest event");const r=wi(t.data.relays);if(r.length===0)throw new Error("The pointer does not include relay hints; include at least one relay in the nevent/naddr");if(t.type==="nevent"){if(t.data.kind!==void 0&&!yi(t.data.kind))throw new Error(`nevent points at kind ${t.data.kind}, not a NIP-5D napplet manifest kind`);return{type:"nevent",relays:r,filter:{ids:[t.data.id],kinds:t.data.kind===void 0?[...at]:[t.data.kind],authors:t.data.author?[t.data.author]:void 0,limit:1}}}if(t.data.kind!==ge)throw new Error(`naddr kind ${t.data.kind} is not the named napplet kind ${ge}`);return{type:"naddr",relays:r,filter:{kinds:[ge],authors:[t.data.pubkey],"#d":[t.data.identifier],limit:1}}}function Ei(e){return{id:e.id,pubkey:e.pubkey,kind:e.kind,tags:e.tags}}async function kn(e){const t=typeof e=="string"?new TextEncoder().encode(e):e,r=new Uint8Array(t.byteLength);r.set(t);const n=await crypto.subtle.digest("SHA-256",r.buffer);return[...new Uint8Array(n)].map(i=>i.toString(16).padStart(2,"0")).join("")}function xi(e){return e.tags.filter(t=>t[0]==="path"&&typeof t[1]=="string"&&typeof t[2]=="string")}async function ki(e){const t=xi(e).map(r=>`${r[2]} ${r[1]}
77
+ `).sort().join("");return kn(t)}async function Si(e){const t=await ki(e);for(const r of e.tags.filter(n=>n[0]==="x"))if(r[2]!==t)throw new Error(`Manifest x tag does not match recomputed aggregate hash ${t}`)}function Ri(e){return e.tags.find(t=>t[0]==="path"&&t[1]==="/index.html")}function Ii(e){const t=[];for(const r of e.tags)if(!(r[0]!=="server"||!r[1]))try{const n=new URL(r[1]);(n.protocol==="http:"||n.protocol==="https:")&&t.push(n.href)}catch{}return[...new Set(t)]}function $i(e,t){const r=e.endsWith("/")?e:`${e}/`;return new URL(t,r).href}async function Ti(e,t=fetch){const n=Ri(e)?.[2];if(!n)throw new Error("Manifest does not include a /index.html path hash");const i=Ii(e);if(i.length===0)throw new Error("Manifest does not include any usable Blossom server hints");const s=[];for(const o of i){const c=$i(o,n);try{const a=await t(c,{mode:"cors"});if(!a.ok){s.push(`${c}: HTTP ${a.status}`);continue}const l=new Uint8Array(await a.arrayBuffer()),g=await kn(l);if(g!==n){s.push(`${c}: sha256 ${g} did not match manifest ${n}`);continue}return new TextDecoder().decode(l)}catch(a){s.push(`${c}: ${a instanceof Error?a.message:String(a)}`)}}throw new Error(`Unable to fetch verified /index.html from Blossom servers: ${s.join("; ")}`)}async function Bi(e,t){try{const n=await(await t(e,{mode:"cors"})).text();return{source:"url",input:e,label:e,bootUrl:e,html:n,fetched:!0,manifestEvent:null}}catch{return{source:"url",input:e,label:e,bootUrl:e,html:"",fetched:!1,manifestEvent:null}}}async function Ai(e,t){const r=vi(e),n=!t.pool,i=t.pool??new li;try{const s=await i.get(r.relays,{...r.filter},{maxWait:t.maxRelayWaitMs??mi});if(!s)throw new Error("No matching napplet manifest event was found on the pointer relay hints");if(!gi(s))throw new Error("Resolved manifest event signature is invalid");const o=Ei(s),c=ct(o);if(!c.ok)throw new Error(`Resolved event is not a valid NIP-5D napplet manifest: ${c.errors[0]?.message}`);await Si(o);const a=await Ti(o,t.fetcher??fetch),l=(t.createObjectUrl??URL.createObjectURL)(new Blob([a],{type:"text/html;charset=utf-8"})),g=()=>(t.revokeObjectUrl??URL.revokeObjectURL)(l);return{source:"nostr",input:e,label:o.id??e,bootUrl:l,html:a,fetched:!0,manifestEvent:o,revoke:g}}finally{n&&i.destroy()}}async function Oi(e,t={}){const r=e.trim();if(!r)throw new Error("Enter a NIP-19 nevent/naddr, or an HTTP URL for local dev");return bi(r)?Bi(r,t.fetcher??fetch):Ai(r,t)}const Ni=/\bwindow\s*\.\s*nostr\b|\bglobalThis\s*\.\s*nostr\b/,qi="/__conformance__/events",it=new URLSearchParams(location.search),Sn=it.get("live")==="1";function ne(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const re=document.getElementById("app");function Li(){return re.innerHTML=`
78
+ <header class="masthead">
79
+ <h1>napplet conformance ${Sn?'<span class="live-badge" id="live-badge">● live</span>':""}</h1>
80
+ <p>Load a napplet by <code>nevent</code> or <code>naddr</code> and run NAP protocol conformance live. Same engine as <code>napplet-conformance</code> CI.</p>
81
+ </header>
82
+ <form id="run-form" class="runbar">
83
+ <input id="target" type="text" placeholder="naddr1… or nevent1… for a NIP-5D napplet manifest" autocomplete="off" spellcheck="false" />
84
+ <button id="run" type="submit">Run conformance</button>
85
+ <button id="rerun" type="button" class="secondary" hidden>Re-run</button>
86
+ </form>
87
+ <p id="status" class="status" role="status"></p>
88
+ <section id="output" class="output"></section>
89
+ `,{targetInput:re.querySelector("#target"),runButton:re.querySelector("#run"),rerunButton:re.querySelector("#rerun"),liveBadge:re.querySelector("#live-badge")??document.createElement("span"),status:re.querySelector("#status"),output:re.querySelector("#output")}}const C=Li();let be="",st=0;function $e(e,t="info"){C.status.textContent=e,C.status.dataset.kind=t}function ze(e){return String(e).padStart(2,"0")}function Pi(e){const t=new Date(e);return`${ze(t.getHours())}:${ze(t.getMinutes())}:${ze(t.getSeconds())}`}function _i(e){const t=e.ok?"conformant":"non-conformant",n=[...new Set(e.checks.map(o=>o.area))].map(o=>{const c=e.checks.filter(a=>a.area===o).map(a=>{const l=a.severity==="warning"&&a.status==="fail"?' <span class="tag warn">warning</span>':"",g=a.detail?`<span class="detail">${ne(a.detail)}</span>`:"";return`<li class="check ${a.status}"><span class="badge ${a.status}">${a.status}</span><span class="id">${ne(a.id)}</span>${l}${g}</li>`}).join("");return`<div class="area"><h3>${ne(o)}</h3><ul>${c}</ul></div>`}).join(""),i=e.summary,s=st>1?`<span class="run-stamp">run #${st} · ${Pi(e.finishedAt)}</span>`:"";return`
90
+ <div class="verdict ${t}">
91
+ <span class="result">${e.ok?"CONFORMANT":"NON-CONFORMANT"}</span>
92
+ <span class="counts">${i.passed} passed · ${i.failed} failed · ${i.skipped} skipped${i.warnings?` · ${i.warnings} warning(s)`:""}</span>
93
+ ${s}
94
+ </div>
95
+ <div class="checks">${n}</div>
96
+ `}function Ci(e){return e.length===0?'<p class="empty">No envelopes were emitted.</p>':`<ul class="envlog">${e.map(r=>{const n=r.verdict.ok?"ok":"bad",i=r.verdict.ok?"":`<div class="errs">${r.verdict.errors.map(s=>ne(`${s.code}: ${s.message}`)).join("<br>")}</div>`;return`<li class="env ${n}"><code>${ne(JSON.stringify(r.envelope))}</code>${i}</li>`}).join("")}</ul>`}function Ui(e){const t=(r,n)=>`<tr><th>${ne(r)}</th><td>${n?ne(String(n)):"<em>—</em>"}</td></tr>`;if(e.manifestEvent){const r=e.manifestEvent,n=ct(r),i=r.tags.find(c=>c[0]==="d")?.[1],s=r.tags.find(c=>c[0]==="path"&&c[1]==="/index.html"),o=r.tags.filter(c=>c[0]==="server").map(c=>c[1]).filter(Boolean);return`
97
+ <table class="manifest">
98
+ ${t("event",r.id)}
99
+ ${t("kind",r.kind)}
100
+ ${t("d",i)}
101
+ ${t("name",Wt(r))}
102
+ ${t("requires",n.requires.join(", "))}
103
+ ${t("/index.html",s?.[2])}
104
+ ${t("servers",o.join(", "))}
105
+ </table>
106
+ ${n.errors.length?`<div class="errs">${n.errors.map(c=>ne(`${c.code}: ${c.message}`)).join("<br>")}</div>`:""}
107
+ `}return e.fetched?'<p class="empty">Local URL mode booted raw HTML. It does not include a signed NIP-5D manifest event, so manifest-event checks are skipped.</p>':`<p class="empty">Couldn't fetch the local URL HTML, likely because of CORS. Use a NIP-19 <code>nevent</code>/<code>naddr</code> for authoritative manifest checks, or use the CLI for local URL runs.</p>`}function Hi(e,t,r){C.output.innerHTML=`
108
+ ${_i(e)}
109
+ <div class="panels">
110
+ <section class="panel"><h2>Emitted envelopes (${t.length})</h2>${Ci(t)}</section>
111
+ <section class="panel"><h2>Manifest</h2>${Ui(r)}</section>
112
+ </div>
113
+ `}async function De(e){be=e,C.runButton.disabled=!0,C.rerunButton.disabled=!0;let t=null;try{$e(`Resolving ${e} …`),t=await Oi(e);const r=Ni.test(t.html)?["window.nostr"]:[];$e("Booting napplet in a sandboxed iframe …");const n=await Wn({url:t.bootUrl,readyTimeoutMs:5e3,settleMs:800,runDegraded:!0}),i=Un({manifestHtml:t.html,manifestEvent:t.manifestEvent,boot:n,forbiddenGlobals:r}),s=Gn(i);st+=1,$e(s.ok?"Done — conformant.":"Done — non-conformant.",s.ok?"info":"error"),Hi(s,n.emitted,t),C.rerunButton.hidden=!1}catch(r){$e(`Error: ${r instanceof Error?r.message:String(r)}`,"error")}finally{t?.revoke?.(),C.runButton.disabled=!1,C.rerunButton.disabled=!1}}function Di(){if(!Sn||typeof EventSource>"u")return;let e=!1;const t=new EventSource(qi);t.addEventListener("rerun",()=>{!be||e||(e=!0,setTimeout(()=>{e=!1,De(be)},50))}),t.addEventListener("open",()=>{C.liveBadge&&(C.liveBadge.dataset.state="connected")}),t.addEventListener("error",()=>{C.liveBadge&&(C.liveBadge.dataset.state="disconnected")})}C.runButton.parentElement.addEventListener("submit",e=>{e.preventDefault();const t=C.targetInput.value.trim();if(t){const r=new URL(location.href);r.searchParams.set("target",t),r.searchParams.delete("url"),history.replaceState(null,"",r),De(t)}});C.rerunButton.addEventListener("click",()=>{be&&De(be)});Di();const Ge=it.get("target")??it.get("url");Ge&&(C.targetInput.value=Ge,De(Ge));
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>napplet conformance runtime</title>
7
7
  <meta name="description" content="Load a napplet and run NAP protocol conformance checks live in your browser." />
8
- <script type="module" crossorigin src="/assets/index-B_4r_ePr.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-BRWua2-f.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-D4WUxbBl.css">
10
10
  </head>
11
11
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@napplet/conformance-cli",
3
- "version": "0.2.17",
3
+ "version": "0.2.18",
4
4
  "description": "Headless CLI that runs @napplet/conformance against a napplet in real Chromium via Playwright — the `test:conformance` runner",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,14 +15,14 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "playwright": "^1.59.1",
18
- "@napplet/conformance": "^0.15.0"
18
+ "@napplet/conformance": "^0.16.0"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@types/node": "^22.15.0",
22
22
  "tsup": "^8.5.0",
23
23
  "typescript": "^5.9.3",
24
24
  "vitest": "^4.1.2",
25
- "@napplet/conformance-web": "0.0.16"
25
+ "@napplet/conformance-web": "0.0.17"
26
26
  },
27
27
  "license": "MIT",
28
28
  "repository": {
@@ -1,113 +0,0 @@
1
- (function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))n(i);new MutationObserver(i=>{for(const s of i)if(s.type==="childList")for(const o of s.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&n(o)}).observe(document,{childList:!0,subtree:!0});function r(i){const s={};return i.integrity&&(s.integrity=i.integrity),i.referrerPolicy&&(s.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?s.credentials="include":i.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function n(i){if(i.ep)return;i.ep=!0;const s=r(i);fetch(i.href,s)}})();var st=["relay","identity","storage","inc","theme","keys","media","notify","config","resource","cvm","outbox","upload","intent","ble","webrtc","link","count","lists","serial","common","dm"],h={id:"string"},Rn={"relay.subscribe":{dir:"out",fields:{...h,subId:"string",filters:"array"}},"relay.close":{dir:"out",fields:{...h,subId:"string"}},"relay.publish":{dir:"out",fields:{...h,event:"object"}},"relay.publishEncrypted":{dir:"out",fields:{...h,event:"object",recipient:"string"}},"relay.query":{dir:"out",fields:{...h,filters:"array"}},"relay.event":{dir:"in"},"relay.eose":{dir:"in"},"relay.closed":{dir:"in"},"relay.publish.result":{dir:"in"},"relay.publishEncrypted.result":{dir:"in"},"relay.query.result":{dir:"in"},"identity.getPublicKey":{dir:"out",fields:{...h}},"identity.getRelays":{dir:"out",fields:{...h}},"identity.getProfile":{dir:"out",fields:{...h}},"identity.getFollows":{dir:"out",fields:{...h}},"identity.getList":{dir:"out",fields:{...h,listType:"string"}},"identity.getZaps":{dir:"out",fields:{...h}},"identity.getMutes":{dir:"out",fields:{...h}},"identity.getBlocked":{dir:"out",fields:{...h}},"identity.getBadges":{dir:"out",fields:{...h}},"identity.changed":{dir:"in"},"identity.getPublicKey.result":{dir:"in"},"identity.getRelays.result":{dir:"in"},"identity.getProfile.result":{dir:"in"},"identity.getFollows.result":{dir:"in"},"identity.getList.result":{dir:"in"},"identity.getZaps.result":{dir:"in"},"identity.getMutes.result":{dir:"in"},"identity.getBlocked.result":{dir:"in"},"identity.getBadges.result":{dir:"in"},"storage.get":{dir:"out",fields:{...h,key:"string"}},"storage.set":{dir:"out",fields:{...h,key:"string",value:"string"}},"storage.remove":{dir:"out",fields:{...h,key:"string"}},"storage.keys":{dir:"out",fields:{...h}},"storage.get.result":{dir:"in"},"storage.set.result":{dir:"in"},"storage.remove.result":{dir:"in"},"storage.keys.result":{dir:"in"},"inc.emit":{dir:"out",fields:{topic:"string"},forbiddenFields:["sender"]},"inc.subscribe":{dir:"out",fields:{...h,topic:"string"}},"inc.unsubscribe":{dir:"out",fields:{topic:"string"}},"inc.channel.open":{dir:"out",fields:{...h,target:"string"}},"inc.channel.emit":{dir:"out",fields:{channelId:"string"}},"inc.channel.broadcast":{dir:"out"},"inc.channel.list":{dir:"out",fields:{...h}},"inc.channel.close":{dir:"out",fields:{channelId:"string"}},"inc.subscribe.result":{dir:"in"},"inc.event":{dir:"in",fields:{topic:"string",sender:"string"}},"inc.channel.open.result":{dir:"in"},"inc.channel.opened":{dir:"in",fields:{channelId:"string",peer:"string"}},"inc.channel.event":{dir:"in"},"inc.channel.list.result":{dir:"in"},"inc.channel.closed":{dir:"in"},"theme.get":{dir:"out",fields:{...h}},"theme.get.result":{dir:"in"},"theme.changed":{dir:"in"},"keys.forward":{dir:"out",fields:{key:"string",code:"string",ctrl:"boolean",alt:"boolean",shift:"boolean",meta:"boolean"}},"keys.registerAction":{dir:"out",fields:{...h,action:"object"}},"keys.unregisterAction":{dir:"out",fields:{actionId:"string"}},"keys.registerAction.result":{dir:"in"},"keys.bindings":{dir:"in"},"keys.action":{dir:"in"},"media.session.create":{dir:"out",fields:{...h,owner:"object"}},"media.session.update":{dir:"out",fields:{sessionId:"string",metadata:"object"}},"media.session.destroy":{dir:"out",fields:{sessionId:"string"}},"media.state":{dir:"out",fields:{sessionId:"string",status:"string"}},"media.capabilities":{dir:"out",fields:{sessionId:"string",actions:"array"}},"media.session.create.result":{dir:"in"},"media.command":{dir:"in"},"media.controls":{dir:"in"},"notify.send":{dir:"out",fields:{...h,title:"string"}},"notify.dismiss":{dir:"out",fields:{notificationId:"string"}},"notify.badge":{dir:"out",fields:{count:"number"}},"notify.channel.register":{dir:"out",fields:{channelId:"string",label:"string"}},"notify.permission.request":{dir:"out",fields:{...h}},"notify.send.result":{dir:"in"},"notify.permission.result":{dir:"in"},"notify.action":{dir:"in"},"notify.clicked":{dir:"in"},"notify.dismissed":{dir:"in"},"notify.controls":{dir:"in"},"config.registerSchema":{dir:"out",fields:{...h,schema:"object"}},"config.get":{dir:"out",fields:{...h}},"config.subscribe":{dir:"out"},"config.unsubscribe":{dir:"out"},"config.openSettings":{dir:"out"},"config.registerSchema.result":{dir:"in"},"config.values":{dir:"in"},"config.schemaError":{dir:"in"},"resource.info":{dir:"out",fields:{...h}},"resource.bytes":{dir:"out",fields:{...h,url:"string"}},"resource.bytesMany":{dir:"out",fields:{...h,urls:"array"}},"resource.cancel":{dir:"out",fields:{...h}},"resource.info.result":{dir:"in"},"resource.info.error":{dir:"in"},"resource.bytes.result":{dir:"in"},"resource.bytes.error":{dir:"in"},"resource.bytesMany.result":{dir:"in"},"resource.bytesMany.error":{dir:"in"},"cvm.discover":{dir:"out",fields:{...h}},"cvm.request":{dir:"out",fields:{...h,server:"object",message:"object"}},"cvm.close":{dir:"out",fields:{...h,server:"object"}},"cvm.registry.list":{dir:"out",fields:{...h}},"cvm.registry.has":{dir:"out",fields:{...h,family:"string"}},"cvm.registry.describe":{dir:"out",fields:{...h,family:"string"}},"cvm.registry.call":{dir:"out",fields:{...h,family:"string",tool:"string"}},"cvm.discover.result":{dir:"in"},"cvm.request.result":{dir:"in"},"cvm.close.result":{dir:"in"},"cvm.event":{dir:"in"},"cvm.registry.list.result":{dir:"in"},"cvm.registry.has.result":{dir:"in"},"cvm.registry.describe.result":{dir:"in"},"cvm.registry.call.result":{dir:"in"},"outbox.getEvent":{dir:"out",fields:{...h,eventId:"string"}},"outbox.query":{dir:"out",fields:{...h,filters:"present"}},"outbox.subscribe":{dir:"out",fields:{...h,subId:"string",filters:"present"}},"outbox.close":{dir:"out",fields:{...h,subId:"string"}},"outbox.publish":{dir:"out",fields:{...h,event:"object"}},"outbox.resolveRelays":{dir:"out",fields:{...h,target:"present"}},"outbox.getEvent.result":{dir:"in"},"outbox.query.result":{dir:"in"},"outbox.event":{dir:"in"},"outbox.closed":{dir:"in"},"outbox.publish.result":{dir:"in"},"outbox.resolveRelays.result":{dir:"in"},"upload.info":{dir:"out",fields:{...h}},"upload.upload":{dir:"out",fields:{...h,request:"object"}},"upload.status":{dir:"out",fields:{...h,uploadId:"string"}},"upload.info.result":{dir:"in"},"upload.upload.result":{dir:"in"},"upload.status.result":{dir:"in"},"upload.status.changed":{dir:"in"},"intent.invoke":{dir:"out",fields:{...h,request:"object"}},"intent.available":{dir:"out",fields:{...h,archetype:"string"}},"intent.handlers":{dir:"out",fields:{...h}},"intent.invoke.result":{dir:"in"},"intent.available.result":{dir:"in"},"intent.handlers.result":{dir:"in"},"intent.changed":{dir:"in"},"ble.open":{dir:"out",fields:{...h,request:"object"}},"ble.services":{dir:"out",fields:{...h,sessionId:"string"}},"ble.read":{dir:"out",fields:{...h,sessionId:"string",target:"object"}},"ble.write":{dir:"out",fields:{...h,sessionId:"string",target:"object",data:"array"}},"ble.subscribe":{dir:"out",fields:{...h,sessionId:"string",target:"object"}},"ble.unsubscribe":{dir:"out",fields:{...h,sessionId:"string",target:"object"}},"ble.close":{dir:"out",fields:{...h,sessionId:"string"}},"ble.open.result":{dir:"in"},"ble.services.result":{dir:"in"},"ble.read.result":{dir:"in"},"ble.write.result":{dir:"in"},"ble.subscribe.result":{dir:"in"},"ble.unsubscribe.result":{dir:"in"},"ble.close.result":{dir:"in"},"ble.event":{dir:"in"},"common.encodeNip19":{dir:"out",fields:{...h,input:"object"}},"common.decodeNip19":{dir:"out",fields:{...h,value:"string"}},"common.getProfile":{dir:"out",fields:{...h,target:"string"}},"common.follows":{dir:"out",fields:{...h}},"common.follow":{dir:"out",fields:{...h,pubkeys:"array"}},"common.unfollow":{dir:"out",fields:{...h,pubkeys:"array"}},"common.react":{dir:"out",fields:{...h,targetEventId:"string",reaction:"string"}},"common.report":{dir:"out",fields:{...h,target:"object",reason:"string",text:"string"}},"common.encodeNip19.result":{dir:"in"},"common.decodeNip19.result":{dir:"in"},"common.getProfile.result":{dir:"in"},"common.follows.result":{dir:"in"},"common.follow.result":{dir:"in"},"common.unfollow.result":{dir:"in"},"common.react.result":{dir:"in"},"common.report.result":{dir:"in"},"webrtc.open":{dir:"out",fields:{...h,request:"object"}},"webrtc.send":{dir:"out",fields:{...h,sessionId:"string",payload:"present"}},"webrtc.close":{dir:"out",fields:{...h,sessionId:"string"}},"webrtc.open.result":{dir:"in"},"webrtc.send.result":{dir:"in"},"webrtc.close.result":{dir:"in"},"webrtc.event":{dir:"in"},"link.open":{dir:"out",fields:{...h,url:"string"}},"link.open.result":{dir:"in"},"count.query":{dir:"out",fields:{...h,filters:"array"}},"count.query.result":{dir:"in"},"lists.supported":{dir:"out",fields:{...h}},"lists.add":{dir:"out",fields:{...h,list:"object",items:"array"}},"lists.remove":{dir:"out",fields:{...h,list:"object",items:"array"}},"lists.supported.result":{dir:"in"},"lists.add.result":{dir:"in"},"lists.remove.result":{dir:"in"},"serial.open":{dir:"out",fields:{...h,request:"object"}},"serial.write":{dir:"out",fields:{...h,sessionId:"string",data:"array"}},"serial.close":{dir:"out",fields:{...h,sessionId:"string"}},"serial.open.result":{dir:"in"},"serial.write.result":{dir:"in"},"serial.close.result":{dir:"in"},"serial.event":{dir:"in"},"dm.status":{dir:"out",fields:{...h}},"dm.conversations":{dir:"out",fields:{...h}},"dm.messages":{dir:"out",fields:{...h,conversationId:"string"}},"dm.send":{dir:"out",fields:{...h,recipients:"array",content:"string"}},"dm.subscribe":{dir:"out",fields:{...h}},"dm.unsubscribe":{dir:"out",fields:{...h,subscriptionId:"string"}},"dm.status.result":{dir:"in"},"dm.conversations.result":{dir:"in"},"dm.messages.result":{dir:"in"},"dm.send.result":{dir:"in"},"dm.subscribe.result":{dir:"in"},"dm.unsubscribe.result":{dir:"in"},"dm.message":{dir:"in"}};function Ut(e){if(e===void 0)return"undefined";if(e===null)return"null";if(Array.isArray(e))return"array";const t=typeof e;return t==="string"||t==="number"||t==="boolean"?t:t==="object"?"object":"present"}function $n(e,t){return t==="present"?e!=null:Ut(e)===t}function In(e,t){if(typeof e!="object"||e===null||Array.isArray(e))return;const r=e;typeof r.archetype!="string"&&t.push({code:r.archetype===void 0?"missing-field":"wrong-type",message:'Intent request requires a string "archetype" field',field:"request.archetype"});for(const n of["action","convention"])r[n]!==void 0&&typeof r[n]!="string"&&t.push({code:"wrong-type",message:`Intent request field "${n}" must be a string`,field:`request.${n}`});"sender"in r&&t.push({code:"forbidden-field",message:"Intent request does not define a caller-supplied sender field",field:"request.sender"})}function Tn(e){const t=[];if(typeof e!="object"||e===null||Array.isArray(e))return{ok:!1,errors:[{code:"not-an-object",message:"Envelope must be a non-null object"}]};const r=e,n=r.type;if(typeof n!="string")return{ok:!1,errors:[{code:"missing-type",message:"Envelope is missing a string `type` field"}]};const i=n.indexOf(".");if(i<=0)return{ok:!1,type:n,errors:[{code:"malformed-type",message:`Envelope type "${n}" is not in domain.action form`}]};const s=n.slice(0,i);if(!st.includes(s))return{ok:!1,type:n,domain:s,errors:[{code:"unknown-domain",message:`"${s}" is not a known NAP domain`}]};const c=Rn[n];if(!c)return{ok:!1,type:n,domain:s,errors:[{code:"unknown-type",message:`"${n}" is not a known ${s} message type`}]};for(const[a,l]of Object.entries(c.fields??{})){if(!(a in r)||r[a]===void 0){t.push({code:"missing-field",message:`Required field "${a}" is missing`,field:a});continue}$n(r[a],l)||t.push({code:"wrong-type",message:`Field "${a}" should be ${l} but is ${Ut(r[a])}`,field:a})}if(c.dir==="in")return{ok:!1,type:n,domain:s,direction:"in",errors:[{code:"inbound-type-emitted",message:`"${n}" is a shell→napplet message; a napplet must not emit it`},...t]};for(const a of c.forbiddenFields??[])a in r&&t.push({code:"forbidden-field",message:`Field "${a}" must be runtime-derived and cannot be emitted by a napplet`,field:a});return n==="intent.invoke"&&In(r.request,t),{ok:t.length===0,type:n,domain:s,direction:"out",errors:t}}var Ht=5129,jt=15129,ge=35129,ot=[Ht,jt,ge];function Dt(e,t){return e.tags.find(r=>r[0]===t)}function Bn(e){return ot.includes(e)}function An(e){return typeof e=="string"&&/^[0-9a-f]{64}$/i.test(e)}function Mt(e){return Dt(e,"d")?.[1]?.trim()||void 0}function On(e){return e.tags.filter(t=>t[0]==="requires").map(t=>t[1]?.trim()??"").filter(Boolean)}function Zt(e){return Mt(e)??Dt(e,"title")?.[1]??e.id}function at(e){const t=[],r=[];if(!e)return{ok:!1,requires:[],errors:[{code:"missing-manifest-event",message:"No NIP-5D manifest event was resolved"}],warnings:r};const n=Mt(e),i=On(e);Bn(e.kind)||t.push({code:"invalid-napplet-kind",message:`Manifest event kind ${e.kind} is not a NIP-5D napplet kind`}),e.kind===ge&&!n?t.push({code:"missing-d-tag",message:"Named napplet manifest kind 35129 must include a non-empty d tag"}):(e.kind===jt||e.kind===Ht)&&n&&t.push({code:"unexpected-d-tag",message:`Napplet manifest kind ${e.kind} must not include a d tag`});const s=e.tags.find(o=>o[0]==="path"&&o[1]==="/index.html");s?An(s[2])||t.push({code:"invalid-index-html-hash",message:"The /index.html path tag must carry a 64-character sha256 hash"}):t.push({code:"missing-index-html",message:"Napplet manifest must include a path tag for /index.html"});for(const o of i){if(o.startsWith("nap:")||o.startsWith("NAP-")){t.push({code:"invalid-required-nap",message:`requires tag "${o}" must be a bare NAP domain such as "relay"`});continue}st.includes(o)||t.push({code:"unknown-required-nap",message:`requires tag "${o}" is not a known NAP domain`})}return{ok:t.length===0,kind:e.kind,dTag:n,requires:i,errors:t,warnings:r}}var xe="f".repeat(64),Nn={dTag:"reference-source"},qn="https://reference.invalid/blob",mt="reference-handler",Ln="reference-subscriber",ke="napplet:note/open",b=e=>[e],L=()=>[];function yt(e){if(typeof e!="string"||!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return{blob:new Blob([],{type:"text/plain"}),mime:"text/plain"};const r=e.slice(5,t),n=e.slice(t+1),i=r.split(";").filter(Boolean),s=i.includes("base64"),o=i.find(c=>c.includes("/"))??"text/plain";try{if(s){const c=globalThis.atob(n),a=Uint8Array.from(c,l=>l.charCodeAt(0));return{blob:new Blob([a],{type:o}),mime:o}}return{blob:new Blob([decodeURIComponent(n)],{type:o}),mime:o}}catch{return null}}var Pn={"relay.subscribe":e=>b({type:"relay.eose",subId:e.subId}),"relay.close":L,"relay.publish":e=>b({type:"relay.publish.result",id:e.id,ok:!0,event:e.event}),"relay.publishEncrypted":e=>b({type:"relay.publishEncrypted.result",id:e.id,ok:!0,event:e.event}),"relay.query":e=>b({type:"relay.query.result",id:e.id,events:[]}),"identity.getPublicKey":e=>b({type:"identity.getPublicKey.result",id:e.id,pubkey:xe}),"identity.getRelays":e=>b({type:"identity.getRelays.result",id:e.id,relays:{}}),"identity.getProfile":e=>b({type:"identity.getProfile.result",id:e.id,profile:null}),"identity.getFollows":e=>b({type:"identity.getFollows.result",id:e.id,pubkeys:[]}),"identity.getList":e=>b({type:"identity.getList.result",id:e.id,entries:[]}),"identity.getZaps":e=>b({type:"identity.getZaps.result",id:e.id,zaps:[]}),"identity.getMutes":e=>b({type:"identity.getMutes.result",id:e.id,pubkeys:[]}),"identity.getBlocked":e=>b({type:"identity.getBlocked.result",id:e.id,pubkeys:[]}),"identity.getBadges":e=>b({type:"identity.getBadges.result",id:e.id,badges:[]}),"storage.get":e=>b({type:"storage.get.result",id:e.id,value:null}),"storage.set":e=>b({type:"storage.set.result",id:e.id}),"storage.remove":e=>b({type:"storage.remove.result",id:e.id}),"storage.keys":e=>b({type:"storage.keys.result",id:e.id,keys:[]}),"inc.emit":L,"inc.subscribe":e=>b({type:"inc.subscribe.result",id:e.id}),"inc.unsubscribe":L,"inc.channel.open":e=>b({type:"inc.channel.open.result",id:e.id,channelId:`chan-${String(e.id)}`,peer:"reference-peer"}),"inc.channel.emit":L,"inc.channel.broadcast":L,"inc.channel.list":e=>b({type:"inc.channel.list.result",id:e.id,channels:[]}),"inc.channel.close":L,"theme.get":e=>b({type:"theme.get.result",id:e.id,theme:{colors:{},mode:"dark"}}),"keys.forward":L,"keys.registerAction":e=>b({type:"keys.registerAction.result",id:e.id,actionId:`action-${String(e.id)}`}),"keys.unregisterAction":L,"media.session.create":e=>b({type:"media.session.create.result",id:e.id,sessionId:`session-${String(e.id)}`,owner:e.owner}),"media.session.update":L,"media.session.destroy":L,"media.state":L,"media.capabilities":L,"notify.send":e=>b({type:"notify.send.result",id:e.id,notificationId:`notif-${String(e.id)}`}),"notify.dismiss":L,"notify.badge":L,"notify.channel.register":L,"notify.permission.request":e=>b({type:"notify.permission.result",id:e.id,granted:!0}),"config.registerSchema":e=>b({type:"config.registerSchema.result",id:e.id,ok:!0}),"config.get":e=>b({type:"config.values",id:e.id,values:{}}),"config.subscribe":()=>b({type:"config.values",values:{}}),"config.unsubscribe":L,"config.openSettings":L,"resource.bytes":e=>{const t=yt(e.url);return b(t?{type:"resource.bytes.result",id:e.id,blob:t.blob,mime:t.mime}:{type:"resource.bytes.result",id:e.id,blob:new Blob([]),mime:"application/octet-stream"})},"resource.bytesMany":e=>b({type:"resource.bytesMany.result",id:e.id,items:Array.isArray(e.urls)?e.urls.map(t=>{const r=yt(t);return{url:t,ok:!0,blob:r?.blob??new Blob([]),mime:r?.mime??"application/octet-stream"}}):[]}),"resource.info":e=>b({type:"resource.info.result",id:e.id,info:{schemes:[{scheme:"data",enabled:!0},{scheme:"https",enabled:!0}]}}),"resource.cancel":L,"cvm.discover":e=>b({type:"cvm.discover.result",id:e.id,servers:[]}),"cvm.request":e=>b({type:"cvm.request.result",id:e.id,message:{}}),"cvm.close":e=>b({type:"cvm.close.result",id:e.id}),"outbox.getEvent":e=>b({type:"outbox.getEvent.result",id:e.id}),"outbox.query":e=>b({type:"outbox.query.result",id:e.id,events:[]}),"outbox.subscribe":e=>b({type:"outbox.closed",subId:e.subId,reason:"reference shell complete"}),"outbox.close":L,"outbox.publish":e=>b({type:"outbox.publish.result",id:e.id,ok:!0}),"outbox.resolveRelays":e=>b({type:"outbox.resolveRelays.result",id:e.id,plan:{}}),"upload.info":e=>b({type:"upload.info.result",id:e.id,info:{rails:[{rail:"nip96",enabled:!0,returns:["https"]},{rail:"blossom",enabled:!0,returns:["https","blossom"]}]}}),"upload.upload":e=>b({type:"upload.upload.result",id:e.id,result:{url:qn}}),"upload.status":e=>b({type:"upload.status.result",id:e.id,status:{}}),"ble.open":e=>b({type:"ble.open.result",id:e.id,session:{id:"ble-reference",state:"open",device:{id:"reference-device",name:"Reference BLE"}}}),"ble.services":e=>b({type:"ble.services.result",id:e.id,services:[]}),"ble.read":e=>b({type:"ble.read.result",id:e.id,data:[]}),"ble.write":e=>b({type:"ble.write.result",id:e.id}),"ble.subscribe":e=>b({type:"ble.subscribe.result",id:e.id}),"ble.unsubscribe":e=>b({type:"ble.unsubscribe.result",id:e.id}),"ble.close":e=>b({type:"ble.close.result",id:e.id}),"common.encodeNip19":e=>b({type:"common.encodeNip19.result",id:e.id,ok:!0,value:"npub1reference",nip19Type:"npub"}),"common.decodeNip19":e=>b({type:"common.decodeNip19.result",id:e.id,ok:!0,nip19Type:"npub",hex:xe}),"common.getProfile":e=>b({type:"common.getProfile.result",id:e.id,ok:!0,pubkey:xe,profile:null}),"common.follows":e=>b({type:"common.follows.result",id:e.id,ok:!0,pubkeys:[]}),"common.follow":e=>b({type:"common.follow.result",id:e.id,ok:!0}),"common.unfollow":e=>b({type:"common.unfollow.result",id:e.id,ok:!0}),"common.react":e=>b({type:"common.react.result",id:e.id,ok:!0,eventId:"0".repeat(64)}),"common.report":e=>b({type:"common.report.result",id:e.id,ok:!0,eventId:"1".repeat(64)}),"webrtc.open":e=>b({type:"webrtc.open.result",id:e.id,session:{id:"webrtc-reference",scope:{type:"direct",pubkey:xe},channel:"default",state:"connecting"}}),"webrtc.send":e=>b({type:"webrtc.send.result",id:e.id}),"webrtc.close":e=>b({type:"webrtc.close.result",id:e.id}),"link.open":e=>b({type:"link.open.result",id:e.id,status:"opened"}),"count.query":e=>b({type:"count.query.result",id:e.id,ok:!0,count:0}),"lists.supported":e=>b({type:"lists.supported.result",id:e.id,lists:[]}),"lists.add":e=>b({type:"lists.add.result",id:e.id,ok:!0,added:0,skipped:0}),"lists.remove":e=>b({type:"lists.remove.result",id:e.id,ok:!0,removed:0,skipped:0}),"serial.open":e=>b({type:"serial.open.result",id:e.id,session:{id:`serial-${String(e.id)}`,state:"open"}}),"serial.write":e=>b({type:"serial.write.result",id:e.id}),"serial.close":e=>b({type:"serial.close.result",id:e.id})};function _n(e={}){const t=e.now??(()=>Date.now()),r=[],n=new Map;function i(d,u){const f=n.get(d);if(f){f.push(u);return}n.set(d,[u])}function s(d){const u=n.get(d)??[];return n.delete(d),u}function o(d,u,f,m){return b({type:"intent.invoke.result",id:d,result:{ok:!1,archetype:u,action:f,handled:!1,error:m}})}function c(d,u){const f=u.request;if(typeof f!="object"||f===null||Array.isArray(f))return o(u.id,"","open","invalid intent request");const m=f,w=typeof m.archetype=="string"?m.archetype:"",I=typeof m.action=="string"?m.action:"open";return w?w!=="note"?o(u.id,w,I,"no handler"):m.convention!==void 0&&m.convention!==ke?o(u.id,w,I,"unsupported convention"):b({type:"intent.invoke.result",id:u.id,result:{ok:!0,archetype:w,action:I,handled:!0,handler:mt,windowId:"reference-window",convention:typeof m.convention=="string"?m.convention:ke}}):o(u.id,w,I,"intent request requires an archetype")}function a(d){return d!=="note"?{archetype:d,available:!1,candidates:[],hasDefault:!1}:{archetype:d,available:!0,candidates:[{dTag:mt,actions:["open"],conventions:[ke],isDefault:!0}],hasDefault:!0}}function l(d,u){const f=u&&typeof u=="object"&&typeof u.type=="string"?u.type:void 0,m=Tn(u);if(r.push({envelope:u,verdict:m,timestamp:t()}),!f||!m.ok)return[];const w=u;if(f==="intent.invoke")return c(d,w);if(f==="intent.available")return b({type:"intent.available.result",id:w.id,availability:a(w.archetype)});if(f==="intent.handlers")return b({type:"intent.handlers.result",id:w.id,handlers:[a("note")]});if(f==="inc.emit"){if(w.topic===ke){const N={type:"inc.event",topic:w.topic,sender:d.dTag};"payload"in w&&(N.payload=w.payload),i(Ln,N)}return[]}const I=Pn[f];return I?I(w):[]}function p(d){return l(Nn,d)}return{get records(){return r},handle:p,handleFrom:l,takeDeliveries:s,reset(){r.length=0,n.clear()}}}function Cn(e){return{manifestHtml:e.manifestHtml,manifestEvent:e.manifestEvent??null,sandbox:e.sandbox??{allowScripts:!0,allowSameOrigin:!1},installedGlobal:e.boot.installedGlobal,bootError:e.boot.bootError,emitted:e.boot.emitted,forbiddenGlobals:e.forbiddenGlobals??[],degraded:e.boot.degraded,lifecycle:e.lifecycle??null}}var Vt="__nappletConformance.error";function wt(e){return new Promise(t=>setTimeout(t,e))}function Un(e){return e.replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Hn(e){return`
2
- (() => {
3
- const domains = ${JSON.stringify(e)};
4
- const napplet = {};
5
- for (const domain of domains) napplet[domain] = {};
6
- const pending = new Map();
7
- let seq = 0;
8
- const nextId = () => {
9
- try {
10
- if (window.crypto && typeof window.crypto.randomUUID === 'function') return window.crypto.randomUUID();
11
- } catch {}
12
- seq += 1;
13
- return 'conformance-' + Date.now().toString(36) + '-' + seq.toString(36);
14
- };
15
- const request = (message, resultType, errorType) => new Promise((resolve, reject) => {
16
- const id = message.id || nextId();
17
- const timeout = window.setTimeout(() => {
18
- pending.delete(id);
19
- reject(new Error(message.type + ' timed out'));
20
- }, 5000);
21
- pending.set(id, { resolve, reject, resultType, errorType, timeout });
22
- window.parent.postMessage({ ...message, id }, '*');
23
- });
24
- window.addEventListener('message', (event) => {
25
- const msg = event.data;
26
- if (!msg || typeof msg !== 'object' || typeof msg.id !== 'string') return;
27
- const slot = pending.get(msg.id);
28
- if (!slot) return;
29
- if (msg.type !== slot.resultType && msg.type !== slot.errorType) return;
30
- pending.delete(msg.id);
31
- window.clearTimeout(slot.timeout);
32
- if (msg.type === slot.errorType) {
33
- slot.reject(new Error(msg.message ? msg.error + ': ' + msg.message : String(msg.error || 'request failed')));
34
- return;
35
- }
36
- slot.resolve(msg);
37
- });
38
- if (napplet.resource) {
39
- napplet.resource.info = () =>
40
- request({ type: 'resource.info' }, 'resource.info.result', 'resource.info.error')
41
- .then((msg) => msg.info);
42
- napplet.resource.bytes = (url) =>
43
- request({ type: 'resource.bytes', url: String(url) }, 'resource.bytes.result', 'resource.bytes.error')
44
- .then((msg) => msg.blob);
45
- napplet.resource.bytesMany = (urls) =>
46
- request({ type: 'resource.bytesMany', urls: Array.from(urls || []) }, 'resource.bytesMany.result', 'resource.bytesMany.error')
47
- .then((msg) => msg.items);
48
- napplet.resource.bytesAsObjectURL = (url) => {
49
- const handle = { url: '', revoke: () => {} };
50
- let objectUrl = '';
51
- let revoked = false;
52
- const ready = napplet.resource.bytes(url).then((blob) => {
53
- if (revoked) return;
54
- objectUrl = URL.createObjectURL(blob);
55
- handle.url = objectUrl;
56
- return objectUrl;
57
- });
58
- handle.revoke = () => {
59
- if (revoked) return;
60
- revoked = true;
61
- if (objectUrl) URL.revokeObjectURL(objectUrl);
62
- };
63
- Object.defineProperty(handle, 'ready', { value: ready, enumerable: false });
64
- return handle;
65
- };
66
- }
67
- window.napplet = napplet;
68
- const report = (reason) => {
69
- try {
70
- window.parent.postMessage({ type: '${Vt}', reason: String(reason && reason.message || reason) }, '*');
71
- } catch {}
72
- };
73
- window.addEventListener('error', (event) => report(event.error || event.message));
74
- window.addEventListener('unhandledrejection', (event) => report(event.reason));
75
- })();
76
- `}function jn(e,t,r){const n=`<base href="${Un(t)}">`,i=`<script>${Hn(r)}<\/script>`,s=/<head(?:\s[^>]*)?>/i.exec(e);if(s){const o=s.index+s[0].length;return`${e.slice(0,o)}${n}${i}${e.slice(o)}`}return`${n}${i}${e}`}function Dn(e){if(!e.startsWith("data:"))return null;const t=e.indexOf(",");if(t<0)return"";const r=e.slice(0,t),n=e.slice(t+1);return r.endsWith(";base64")?atob(n):decodeURIComponent(n)}async function Mn(e){if(e==="about:blank")return"<!doctype html><html><head></head><body></body></html>";const t=Dn(e);if(t!==null)return t;const r=await fetch(e);if(!r.ok)throw new Error(`Failed to fetch napplet HTML: ${r.status} ${r.statusText}`);return r.text()}async function vt(e,t,r,n){const i=_n(),s=r.createElement("iframe");s.setAttribute("sandbox",t.allowSameOrigin?"allow-scripts allow-same-origin":"allow-scripts"),s.setAttribute("aria-hidden","true"),s.style.position="absolute",s.style.width="1px",s.style.height="1px",s.style.left="-9999px";let o=null;const c=p=>{if(p.source!==s.contentWindow)return;const d=p.data;if(d&&typeof d=="object"&&d.type===Vt){o=`napplet boot error: ${String(d.reason??"unknown error")}`;return}const u=i.handle(p.data),f=p.source;for(const m of u)f?.postMessage(m,"*")};let a=!1;const l=new Promise(p=>{s.addEventListener("load",()=>{a=!0,p()},{once:!0})});n.addEventListener("message",c),(r.body??r.documentElement).appendChild(s);try{const p=await Mn(t.url);s.srcdoc=jn(p,t.url,e)}catch(p){o=p instanceof Error?p.message:String(p)}if(!o){const p=Symbol("timeout");await Promise.race([l.then(()=>"loaded"),wt(t.readyTimeoutMs).then(()=>p)])===p||!a?o=`napplet did not boot (iframe did not load within ${t.readyTimeoutMs}ms; a conformant napplet must run under sandbox="allow-scripts" without allow-same-origin)`:await wt(t.settleMs)}n.removeEventListener("message",c);try{s.remove()}catch{}return{installedGlobal:o===null,bootError:o,emitted:[...i.records]}}async function Zn(e){const t=e.document??document,r=e.window??window,n={url:e.url,readyTimeoutMs:e.readyTimeoutMs??5e3,settleMs:e.settleMs,allowSameOrigin:e.allowSameOrigin??!1},i=await vt(st,n,t,r);let s=null;{const o=await vt([],n,t,r);s={bootError:o.bootError,emitted:o.emitted}}return{installedGlobal:i.installedGlobal,bootError:i.bootError,emitted:i.emitted,degraded:s}}var Vn=e=>({status:"pass",detail:e}),Wn=(e,t)=>({status:"fail",detail:e,diagnostics:t}),Fn=e=>({status:"skip",detail:e}),q={pass:Vn,fail:Wn,skip:Fn};function Kn(e,t){return at(e.manifestEvent).errors.filter(r=>t.includes(r.code))}function je(e,t,r){return{id:e,area:"manifest",severity:"error",title:t,run:n=>{if(!n.manifestEvent)return q.skip("No NIP-5D manifest event was resolved");const i=Kn(n,r);return i.length?q.fail(i[0].message,i):q.pass()}}}var Yn=[je("manifest/event-kind","Resolved event is a NIP-5D napplet manifest",["invalid-napplet-kind","missing-d-tag","unexpected-d-tag"]),je("manifest/index-html","Manifest declares a hashed /index.html",["missing-index-html","invalid-index-html-hash"]),je("manifest/requires","requires tags are bare known NAP domains",["invalid-required-nap","unknown-required-nap"]),{id:"boot/sandbox-allow-scripts",area:"boot",severity:"error",title:"Runs under allow-scripts without allow-same-origin",run:e=>e.sandbox.allowScripts?e.sandbox.allowSameOrigin?q.fail("Napplet relied on allow-same-origin, which a shell must not grant"):q.pass():q.fail("Napplet was not loaded with allow-scripts")},{id:"boot/installs-global",area:"boot",severity:"error",title:"Runs after runtime-injected window.napplet is installed",run:e=>e.installedGlobal?q.pass():q.fail("runtime did not inject window.napplet before load")},{id:"boot/no-boot-error",area:"boot",severity:"error",title:"Boots without an uncaught error",run:e=>e.bootError?q.fail(e.bootError):q.pass()},{id:"boot/no-forbidden-globals",area:"boot",severity:"error",title:"Does not access forbidden browser authority surfaces",run:e=>e.forbiddenGlobals.length?q.fail(`Accessed forbidden surface(s): ${e.forbiddenGlobals.join(", ")}`,e.forbiddenGlobals):q.pass()},{id:"wire/envelope-well-formed",area:"wire",severity:"error",title:"Every emitted envelope is well-formed",run:e=>{if(e.emitted.length===0)return q.skip("Napplet emitted no envelopes");const t=e.emitted.filter(n=>!n.verdict.ok);if(t.length===0)return q.pass(`${e.emitted.length} envelope(s) valid`);const r=t.map(n=>({envelope:n.envelope,errors:n.verdict.errors}));return q.fail(`${t.length}/${e.emitted.length} emitted envelope(s) invalid`,r)}},{id:"degrade/domain-absence",area:"degradation",severity:"error",title:"Does not crash when no NAP domains are injected",run:e=>e.degraded?e.degraded.bootError?q.fail(`Crashed with no injected domains: ${e.degraded.bootError}`):q.pass():q.skip("Host did not run the degraded (no-capabilities) pass")},{id:"lifecycle/clean-teardown",area:"lifecycle",severity:"warning",title:"Tears down listeners on unload",run:e=>e.lifecycle?e.lifecycle.listenerLeak?q.fail("Message listeners remained after unload"):q.pass():q.skip("Lifecycle not measured")}];function zn(e,t={}){const r=t.now??(()=>Date.now()),n=t.checks??Yn,i=r(),s=n.map(a=>{const l=a.run(e);return{id:a.id,area:a.area,severity:a.severity,title:a.title,status:l.status,detail:l.detail,diagnostics:l.diagnostics}}),o={total:s.length,passed:s.filter(a=>a.status==="pass").length,failed:s.filter(a=>a.status==="fail").length,skipped:s.filter(a=>a.status==="skip").length,errors:s.filter(a=>a.status==="fail"&&a.severity==="error").length,warnings:s.filter(a=>a.status==="fail"&&a.severity==="warning").length};return{napplet:e.manifestEvent?Zt(e.manifestEvent):void 0,startedAt:i,finishedAt:r(),checks:s,summary:o,ok:o.errors===0}}/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Gn(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function ct(e,t=""){if(!Number.isSafeInteger(e)||e<0){const r=t&&`"${t}" `;throw new Error(`${r}expected integer >= 0, got ${e}`)}}function D(e,t,r=""){const n=Gn(e),i=e?.length,s=t!==void 0;if(!n||s&&i!==t){const o=r&&`"${r}" `,c=s?` of length ${t}`:"",a=n?`length=${i}`:`type=${typeof e}`;throw new Error(o+"expected Uint8Array"+c+", got "+a)}return e}function Et(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Xn(e,t){D(e,void 0,"digestInto() output");const r=t.outputLen;if(e.length<r)throw new Error('"digestInto() output" expected to be of length >='+r)}function Ge(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function De(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function z(e,t){return e<<32-t|e>>>t}const Wt=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Jn=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function _(e){if(D(e),Wt)return e.toHex();let t="";for(let r=0;r<e.length;r++)t+=Jn[e[r]];return t}const J={_0:48,_9:57,A:65,F:70,a:97,f:102};function xt(e){if(e>=J._0&&e<=J._9)return e-J._0;if(e>=J.A&&e<=J.F)return e-(J.A-10);if(e>=J.a&&e<=J.f)return e-(J.a-10)}function X(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(Wt)return Uint8Array.fromHex(e);const t=e.length,r=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const n=new Uint8Array(r);for(let i=0,s=0;i<r;i++,s+=2){const o=xt(e.charCodeAt(s)),c=xt(e.charCodeAt(s+1));if(o===void 0||c===void 0){const a=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+a+'" at index '+s)}n[i]=o*16+c}return n}function Be(...e){let t=0;for(let n=0;n<e.length;n++){const i=e[n];D(i),t+=i.length}const r=new Uint8Array(t);for(let n=0,i=0;n<e.length;n++){const s=e[n];r.set(s,i),i+=s.length}return r}function Qn(e,t={}){const r=(i,s)=>e(s).update(i).digest(),n=e(void 0);return r.outputLen=n.outputLen,r.blockLen=n.blockLen,r.create=i=>e(i),Object.assign(r,t),Object.freeze(r)}function Ft(e=32){const t=typeof globalThis=="object"?globalThis.crypto:null;if(typeof t?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const er=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});/*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */function Kt(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function Yt(e,t){return Array.isArray(t)?t.length===0?!0:e?t.every(r=>typeof r=="string"):t.every(r=>Number.isSafeInteger(r)):!1}function tr(e){if(typeof e!="function")throw new Error("function expected");return!0}function me(e,t){if(typeof t!="string")throw new Error(`${e}: string expected`);return!0}function zt(e){if(!Number.isSafeInteger(e))throw new Error(`invalid integer: ${e}`)}function Xe(e){if(!Array.isArray(e))throw new Error("array expected")}function Gt(e,t){if(!Yt(!0,t))throw new Error(`${e}: array of strings expected`)}function Xt(e,t){if(!Yt(!1,t))throw new Error(`${e}: array of numbers expected`)}function nr(...e){const t=s=>s,r=(s,o)=>c=>s(o(c)),n=e.map(s=>s.encode).reduceRight(r,t),i=e.map(s=>s.decode).reduce(r,t);return{encode:n,decode:i}}function rr(e){const t=typeof e=="string"?e.split(""):e,r=t.length;Gt("alphabet",t);const n=new Map(t.map((i,s)=>[i,s]));return{encode:i=>(Xe(i),i.map(s=>{if(!Number.isSafeInteger(s)||s<0||s>=r)throw new Error(`alphabet.encode: digit index outside alphabet "${s}". Allowed: ${e}`);return t[s]})),decode:i=>(Xe(i),i.map(s=>{me("alphabet.decode",s);const o=n.get(s);if(o===void 0)throw new Error(`Unknown letter: "${s}". Allowed: ${e}`);return o}))}}function ir(e=""){return me("join",e),{encode:t=>(Gt("join.decode",t),t.join(e)),decode:t=>(me("join.decode",t),t.split(e))}}const Jt=(e,t)=>t===0?e:Jt(t,e%t),Ae=(e,t)=>e+(t-Jt(e,t)),Ie=(()=>{let e=[];for(let t=0;t<40;t++)e.push(2**t);return e})();function Je(e,t,r,n){if(Xe(e),t<=0||t>32)throw new Error(`convertRadix2: wrong from=${t}`);if(r<=0||r>32)throw new Error(`convertRadix2: wrong to=${r}`);if(Ae(t,r)>32)throw new Error(`convertRadix2: carry overflow from=${t} to=${r} carryBits=${Ae(t,r)}`);let i=0,s=0;const o=Ie[t],c=Ie[r]-1,a=[];for(const l of e){if(zt(l),l>=o)throw new Error(`convertRadix2: invalid data word=${l} from=${t}`);if(i=i<<t|l,s+t>32)throw new Error(`convertRadix2: carry overflow pos=${s} from=${t}`);for(s+=t;s>=r;s-=r)a.push((i>>s-r&c)>>>0);const p=Ie[s];if(p===void 0)throw new Error("invalid carry");i&=p-1}if(i=i<<r-s&c,!n&&s>=t)throw new Error("Excess padding");if(!n&&i>0)throw new Error(`Non-zero padding: ${i}`);return n&&s>0&&a.push(i>>>0),a}function sr(e,t=!1){if(zt(e),e<=0||e>32)throw new Error("radix2: bits should be in (0..32]");if(Ae(8,e)>32||Ae(e,8)>32)throw new Error("radix2: carry overflow");return{encode:r=>{if(!Kt(r))throw new Error("radix2.encode input should be Uint8Array");return Je(Array.from(r),8,e,!t)},decode:r=>(Xt("radix2.decode",r),Uint8Array.from(Je(r,e,8,t)))}}function kt(e){return tr(e),function(...t){try{return e.apply(null,t)}catch{}}}const Qe=nr(rr("qpzry9x8gf2tvdw0s3jn54khce6mua7l"),ir("")),St=[996825010,642813549,513874426,1027748829,705979059];function fe(e){const t=e>>25;let r=(e&33554431)<<5;for(let n=0;n<St.length;n++)(t>>n&1)===1&&(r^=St[n]);return r}function Rt(e,t,r=1){const n=e.length;let i=1;for(let s=0;s<n;s++){const o=e.charCodeAt(s);if(o<33||o>126)throw new Error(`Invalid prefix (${e})`);i=fe(i)^o>>5}i=fe(i);for(let s=0;s<n;s++)i=fe(i)^e.charCodeAt(s)&31;for(let s of t)i=fe(i)^s;for(let s=0;s<6;s++)i=fe(i);return i^=r,Qe.encode(Je([i%Ie[30]],30,5,!1))}function or(e){const t=e==="bech32"?1:734539939,r=sr(5),n=r.decode,i=r.encode,s=kt(n);function o(d,u,f=90){me("bech32.encode prefix",d),Kt(u)&&(u=Array.from(u)),Xt("bech32.encode",u);const m=d.length;if(m===0)throw new TypeError(`Invalid prefix length ${m}`);const w=m+7+u.length;if(f!==!1&&w>f)throw new TypeError(`Length ${w} exceeds limit ${f}`);const I=d.toLowerCase(),N=Rt(I,u,t);return`${I}1${Qe.encode(u)}${N}`}function c(d,u=90){me("bech32.decode input",d);const f=d.length;if(f<8||u!==!1&&f>u)throw new TypeError(`invalid string length: ${f} (${d}). Expected (8..${u})`);const m=d.toLowerCase();if(d!==m&&d!==d.toUpperCase())throw new Error("String must be lowercase or uppercase");const w=m.lastIndexOf("1");if(w===0||w===-1)throw new Error('Letter "1" must be present between prefix and data only');const I=m.slice(0,w),N=m.slice(w+1);if(N.length<6)throw new Error("Data must be at least 6 characters long");const K=Qe.decode(N).slice(0,-6),Q=Rt(I,K,t);if(!N.endsWith(Q))throw new Error(`Invalid checksum in ${d}: expected "${Q}"`);return{prefix:I,words:K}}const a=kt(c);function l(d){const{prefix:u,words:f}=c(d,!1);return{prefix:u,words:f,bytes:n(f)}}function p(d,u){return o(d,i(u))}return{encode:o,decode:c,encodeFromBytes:p,decodeToBytes:l,decodeUnsafe:a,fromWords:n,fromWordsUnsafe:s,toWords:i}}const $t=or("bech32");var Se=new TextDecoder("utf-8");new TextEncoder;var ar=5e3;function cr(e){try{return e.startsWith("nostr:")&&(e=e.substring(6)),lr(e)}catch{return{type:"invalid",data:null}}}function lr(e){let{prefix:t,words:r}=$t.decode(e,ar),n=new Uint8Array($t.fromWords(r));switch(t){case"nprofile":{let i=Me(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nprofile");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");return{type:"nprofile",data:{pubkey:_(i[0][0]),relays:i[1]?i[1].map(s=>Se.decode(s)):[]}}}case"nevent":{let i=Me(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for nevent");if(i[0][0].length!==32)throw new Error("TLV 0 should be 32 bytes");if(i[2]&&i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(i[3]&&i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"nevent",data:{id:_(i[0][0]),relays:i[1]?i[1].map(s=>Se.decode(s)):[],author:i[2]?.[0]?_(i[2][0]):void 0,kind:i[3]?.[0]?parseInt(_(i[3][0]),16):void 0}}}case"naddr":{let i=Me(n);if(!i[0]?.[0])throw new Error("missing TLV 0 for naddr");if(!i[2]?.[0])throw new Error("missing TLV 2 for naddr");if(i[2][0].length!==32)throw new Error("TLV 2 should be 32 bytes");if(!i[3]?.[0])throw new Error("missing TLV 3 for naddr");if(i[3][0].length!==4)throw new Error("TLV 3 should be 4 bytes");return{type:"naddr",data:{identifier:Se.decode(i[0][0]),pubkey:_(i[2][0]),kind:parseInt(_(i[3][0]),16),relays:i[1]?i[1].map(s=>Se.decode(s)):[]}}}case"nsec":return{type:t,data:n};case"npub":case"note":return{type:t,data:_(n)};default:throw new Error(`unknown prefix ${t}`)}}function Me(e){let t={},r=e;for(;r.length>0;){let n=r[0],i=r[1],s=r.slice(2,2+i);if(r=r.slice(2+i),s.length<i)throw new Error(`not enough data to read on TLV ${n}`);t[n]=t[n]||[],t[n].push(s)}return t}function dr(e,t,r){return e&t^~e&r}function ur(e,t,r){return e&t^e&r^t&r}class fr{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(t,r,n,i){this.blockLen=t,this.outputLen=r,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(t),this.view=De(this.buffer)}update(t){Et(this),D(t);const{view:r,buffer:n,blockLen:i}=this,s=t.length;for(let o=0;o<s;){const c=Math.min(i-this.pos,s-o);if(c===i){const a=De(t);for(;i<=s-o;o+=i)this.process(a,o);continue}n.set(t.subarray(o,o+c),this.pos),this.pos+=c,o+=c,this.pos===i&&(this.process(r,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){Et(this),Xn(t,this),this.finished=!0;const{buffer:r,view:n,blockLen:i,isLE:s}=this;let{pos:o}=this;r[o++]=128,Ge(this.buffer.subarray(o)),this.padOffset>i-o&&(this.process(n,0),o=0);for(let d=o;d<i;d++)r[d]=0;n.setBigUint64(i-8,BigInt(this.length*8),s),this.process(n,0);const c=De(t),a=this.outputLen;if(a%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const l=a/4,p=this.get();if(l>p.length)throw new Error("_sha2: outputLen bigger than state");for(let d=0;d<l;d++)c.setUint32(4*d,p[d],s)}digest(){const{buffer:t,outputLen:r}=this;this.digestInto(t);const n=t.slice(0,r);return this.destroy(),n}_cloneInto(t){t||=new this.constructor,t.set(...this.get());const{blockLen:r,buffer:n,length:i,finished:s,destroyed:o,pos:c}=this;return t.destroyed=o,t.finished=s,t.length=i,t.pos=c,i%r&&t.buffer.set(n),t}clone(){return this._cloneInto()}}const ee=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),hr=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),te=new Uint32Array(64);class pr extends fr{constructor(t){super(64,t,8,!1)}get(){const{A:t,B:r,C:n,D:i,E:s,F:o,G:c,H:a}=this;return[t,r,n,i,s,o,c,a]}set(t,r,n,i,s,o,c,a){this.A=t|0,this.B=r|0,this.C=n|0,this.D=i|0,this.E=s|0,this.F=o|0,this.G=c|0,this.H=a|0}process(t,r){for(let d=0;d<16;d++,r+=4)te[d]=t.getUint32(r,!1);for(let d=16;d<64;d++){const u=te[d-15],f=te[d-2],m=z(u,7)^z(u,18)^u>>>3,w=z(f,17)^z(f,19)^f>>>10;te[d]=w+te[d-7]+m+te[d-16]|0}let{A:n,B:i,C:s,D:o,E:c,F:a,G:l,H:p}=this;for(let d=0;d<64;d++){const u=z(c,6)^z(c,11)^z(c,25),f=p+u+dr(c,a,l)+hr[d]+te[d]|0,w=(z(n,2)^z(n,13)^z(n,22))+ur(n,i,s)|0;p=l,l=a,a=c,c=o+f|0,o=s,s=i,i=n,n=f+w|0}n=n+this.A|0,i=i+this.B|0,s=s+this.C|0,o=o+this.D|0,c=c+this.E|0,a=a+this.F|0,l=l+this.G|0,p=p+this.H|0,this.set(n,i,s,o,c,a,l,p)}roundClean(){Ge(te)}destroy(){this.set(0,0,0,0,0,0,0,0),Ge(this.buffer)}}class gr extends pr{A=ee[0]|0;B=ee[1]|0;C=ee[2]|0;D=ee[3]|0;E=ee[4]|0;F=ee[5]|0;G=ee[6]|0;H=ee[7]|0;constructor(){super(32)}}const Oe=Qn(()=>new gr,er(1));/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const lt=BigInt(0),et=BigInt(1);function It(e,t=""){if(typeof e!="boolean"){const r=t&&`"${t}" `;throw new Error(r+"expected boolean, got type="+typeof e)}return e}function br(e){if(typeof e=="bigint"){if(!wr(e))throw new Error("positive bigint expected, got "+e)}else ct(e);return e}function Qt(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);return e===""?lt:BigInt("0x"+e)}function dt(e){return Qt(_(e))}function en(e){return Qt(_(mr(D(e)).reverse()))}function ut(e,t){ct(t),e=br(e);const r=X(e.toString(16).padStart(t*2,"0"));if(r.length!==t)throw new Error("number too large");return r}function tn(e,t){return ut(e,t).reverse()}function mr(e){return Uint8Array.from(e)}function yr(e){return Uint8Array.from(e,(t,r)=>{const n=t.charCodeAt(0);if(t.length!==1||n>127)throw new Error(`string contains non-ASCII character "${e[r]}" with code ${n} at position ${r}`);return n})}const wr=e=>typeof e=="bigint"&&lt<=e;function vr(e){let t;for(t=0;e>lt;e>>=et,t+=1);return t}const nn=e=>(et<<BigInt(e))-et;function rn(e,t={},r={}){if(!e||typeof e!="object")throw new Error("expected valid options object");function n(s,o,c){const a=e[s];if(c&&a===void 0)return;const l=typeof a;if(l!==o||a===null)throw new Error(`param "${s}" is invalid: expected ${o}, got ${l}`)}const i=(s,o)=>Object.entries(s).forEach(([c,a])=>n(c,a,o));i(t,!1),i(r,!0)}function Tt(e){const t=new WeakMap;return(r,...n)=>{const i=t.get(r);if(i!==void 0)return i;const s=e(r,...n);return t.set(r,s),s}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const j=BigInt(0),H=BigInt(1),se=BigInt(2),sn=BigInt(3),on=BigInt(4),an=BigInt(5),Er=BigInt(7),cn=BigInt(8),xr=BigInt(9),ln=BigInt(16);function F(e,t){const r=e%t;return r>=j?r:t+r}function Z(e,t,r){let n=e;for(;t-- >j;)n*=n,n%=r;return n}function Bt(e,t){if(e===j)throw new Error("invert: expected non-zero number");if(t<=j)throw new Error("invert: expected positive modulus, got "+t);let r=F(e,t),n=t,i=j,s=H;for(;r!==j;){const c=n/r,a=n%r,l=i-s*c;n=r,r=a,i=s,s=l}if(n!==H)throw new Error("invert: does not exist");return F(i,t)}function ft(e,t,r){if(!e.eql(e.sqr(t),r))throw new Error("Cannot find square root")}function dn(e,t){const r=(e.ORDER+H)/on,n=e.pow(t,r);return ft(e,n,t),n}function kr(e,t){const r=(e.ORDER-an)/cn,n=e.mul(t,se),i=e.pow(n,r),s=e.mul(t,i),o=e.mul(e.mul(s,se),i),c=e.mul(s,e.sub(o,e.ONE));return ft(e,c,t),c}function Sr(e){const t=Pe(e),r=un(e),n=r(t,t.neg(t.ONE)),i=r(t,n),s=r(t,t.neg(n)),o=(e+Er)/ln;return(c,a)=>{let l=c.pow(a,o),p=c.mul(l,n);const d=c.mul(l,i),u=c.mul(l,s),f=c.eql(c.sqr(p),a),m=c.eql(c.sqr(d),a);l=c.cmov(l,p,f),p=c.cmov(u,d,m);const w=c.eql(c.sqr(p),a),I=c.cmov(l,p,w);return ft(c,I,a),I}}function un(e){if(e<sn)throw new Error("sqrt is not defined for small field");let t=e-H,r=0;for(;t%se===j;)t/=se,r++;let n=se;const i=Pe(e);for(;At(i,n)===1;)if(n++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(r===1)return dn;let s=i.pow(n,t);const o=(t+H)/se;return function(a,l){if(a.is0(l))return l;if(At(a,l)!==1)throw new Error("Cannot find square root");let p=r,d=a.mul(a.ONE,s),u=a.pow(l,t),f=a.pow(l,o);for(;!a.eql(u,a.ONE);){if(a.is0(u))return a.ZERO;let m=1,w=a.sqr(u);for(;!a.eql(w,a.ONE);)if(m++,w=a.sqr(w),m===p)throw new Error("Cannot find square root");const I=H<<BigInt(p-m-1),N=a.pow(d,I);p=m,d=a.sqr(N),u=a.mul(u,d),f=a.mul(f,N)}return f}}function Rr(e){return e%on===sn?dn:e%cn===an?kr:e%ln===xr?Sr(e):un(e)}const $r=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function Ir(e){const t={ORDER:"bigint",BYTES:"number",BITS:"number"},r=$r.reduce((n,i)=>(n[i]="function",n),t);return rn(e,r),e}function Tr(e,t,r){if(r<j)throw new Error("invalid exponent, negatives unsupported");if(r===j)return e.ONE;if(r===H)return t;let n=e.ONE,i=t;for(;r>j;)r&H&&(n=e.mul(n,i)),i=e.sqr(i),r>>=H;return n}function fn(e,t,r=!1){const n=new Array(t.length).fill(r?e.ZERO:void 0),i=t.reduce((o,c,a)=>e.is0(c)?o:(n[a]=o,e.mul(o,c)),e.ONE),s=e.inv(i);return t.reduceRight((o,c,a)=>e.is0(c)?o:(n[a]=e.mul(o,n[a]),e.mul(o,c)),s),n}function At(e,t){const r=(e.ORDER-H)/se,n=e.pow(t,r),i=e.eql(n,e.ONE),s=e.eql(n,e.ZERO),o=e.eql(n,e.neg(e.ONE));if(!i&&!s&&!o)throw new Error("invalid Legendre symbol result");return i?1:s?0:-1}function Br(e,t){t!==void 0&&ct(t);const r=t!==void 0?t:e.toString(2).length,n=Math.ceil(r/8);return{nBitLength:r,nByteLength:n}}class Ar{ORDER;BITS;BYTES;isLE;ZERO=j;ONE=H;_lengths;_sqrt;_mod;constructor(t,r={}){if(t<=j)throw new Error("invalid field: expected ORDER > 0, got "+t);let n;this.isLE=!1,r!=null&&typeof r=="object"&&(typeof r.BITS=="number"&&(n=r.BITS),typeof r.sqrt=="function"&&(this.sqrt=r.sqrt),typeof r.isLE=="boolean"&&(this.isLE=r.isLE),r.allowedLengths&&(this._lengths=r.allowedLengths?.slice()),typeof r.modFromBytes=="boolean"&&(this._mod=r.modFromBytes));const{nBitLength:i,nByteLength:s}=Br(t,n);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=t,this.BITS=i,this.BYTES=s,this._sqrt=void 0,Object.preventExtensions(this)}create(t){return F(t,this.ORDER)}isValid(t){if(typeof t!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof t);return j<=t&&t<this.ORDER}is0(t){return t===j}isValidNot0(t){return!this.is0(t)&&this.isValid(t)}isOdd(t){return(t&H)===H}neg(t){return F(-t,this.ORDER)}eql(t,r){return t===r}sqr(t){return F(t*t,this.ORDER)}add(t,r){return F(t+r,this.ORDER)}sub(t,r){return F(t-r,this.ORDER)}mul(t,r){return F(t*r,this.ORDER)}pow(t,r){return Tr(this,t,r)}div(t,r){return F(t*Bt(r,this.ORDER),this.ORDER)}sqrN(t){return t*t}addN(t,r){return t+r}subN(t,r){return t-r}mulN(t,r){return t*r}inv(t){return Bt(t,this.ORDER)}sqrt(t){return this._sqrt||(this._sqrt=Rr(this.ORDER)),this._sqrt(this,t)}toBytes(t){return this.isLE?tn(t,this.BYTES):ut(t,this.BYTES)}fromBytes(t,r=!1){D(t);const{_lengths:n,BYTES:i,isLE:s,ORDER:o,_mod:c}=this;if(n){if(!n.includes(t.length)||t.length>i)throw new Error("Field.fromBytes: expected "+n+" bytes, got "+t.length);const l=new Uint8Array(i);l.set(t,s?0:l.length-t.length),t=l}if(t.length!==i)throw new Error("Field.fromBytes: expected "+i+" bytes, got "+t.length);let a=s?en(t):dt(t);if(c&&(a=F(a,o)),!r&&!this.isValid(a))throw new Error("invalid field element: outside of range 0..ORDER");return a}invertBatch(t){return fn(this,t)}cmov(t,r,n){return n?r:t}}function Pe(e,t={}){return new Ar(e,t)}function hn(e){if(typeof e!="bigint")throw new Error("field order must be bigint");const t=e.toString(2).length;return Math.ceil(t/8)}function Or(e){const t=hn(e);return t+Math.ceil(t/2)}function Nr(e,t,r=!1){D(e);const n=e.length,i=hn(t),s=Or(t);if(n<16||n<s||n>1024)throw new Error("expected "+s+"-1024 bytes of input, got "+n);const o=r?en(e):dt(e),c=F(o,t-H)+H;return r?tn(c,i):ut(c,i)}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const le=BigInt(0),oe=BigInt(1);function Ne(e,t){const r=t.negate();return e?r:t}function Ot(e,t){const r=fn(e.Fp,t.map(n=>n.Z));return t.map((n,i)=>e.fromAffine(n.toAffine(r[i])))}function pn(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new Error("invalid window size, expected [1.."+t+"], got W="+e)}function Ze(e,t){pn(e,t);const r=Math.ceil(t/e)+1,n=2**(e-1),i=2**e,s=nn(e),o=BigInt(e);return{windows:r,windowSize:n,mask:s,maxNumber:i,shiftBy:o}}function Nt(e,t,r){const{windowSize:n,mask:i,maxNumber:s,shiftBy:o}=r;let c=Number(e&i),a=e>>o;c>n&&(c-=s,a+=oe);const l=t*n,p=l+Math.abs(c)-1,d=c===0,u=c<0,f=t%2!==0;return{nextN:a,offset:p,isZero:d,isNeg:u,isNegF:f,offsetF:l}}const Ve=new WeakMap,gn=new WeakMap;function We(e){return gn.get(e)||1}function qt(e){if(e!==le)throw new Error("invalid wNAF")}class qr{BASE;ZERO;Fn;bits;constructor(t,r){this.BASE=t.BASE,this.ZERO=t.ZERO,this.Fn=t.Fn,this.bits=r}_unsafeLadder(t,r,n=this.ZERO){let i=t;for(;r>le;)r&oe&&(n=n.add(i)),i=i.double(),r>>=oe;return n}precomputeWindow(t,r){const{windows:n,windowSize:i}=Ze(r,this.bits),s=[];let o=t,c=o;for(let a=0;a<n;a++){c=o,s.push(c);for(let l=1;l<i;l++)c=c.add(o),s.push(c);o=c.double()}return s}wNAF(t,r,n){if(!this.Fn.isValid(n))throw new Error("invalid scalar");let i=this.ZERO,s=this.BASE;const o=Ze(t,this.bits);for(let c=0;c<o.windows;c++){const{nextN:a,offset:l,isZero:p,isNeg:d,isNegF:u,offsetF:f}=Nt(n,c,o);n=a,p?s=s.add(Ne(u,r[f])):i=i.add(Ne(d,r[l]))}return qt(n),{p:i,f:s}}wNAFUnsafe(t,r,n,i=this.ZERO){const s=Ze(t,this.bits);for(let o=0;o<s.windows&&n!==le;o++){const{nextN:c,offset:a,isZero:l,isNeg:p}=Nt(n,o,s);if(n=c,!l){const d=r[a];i=i.add(p?d.negate():d)}}return qt(n),i}getPrecomputes(t,r,n){let i=Ve.get(r);return i||(i=this.precomputeWindow(r,t),t!==1&&(typeof n=="function"&&(i=n(i)),Ve.set(r,i))),i}cached(t,r,n){const i=We(t);return this.wNAF(i,this.getPrecomputes(i,t,n),r)}unsafe(t,r,n,i){const s=We(t);return s===1?this._unsafeLadder(t,r,i):this.wNAFUnsafe(s,this.getPrecomputes(s,t,n),r,i)}createCache(t,r){pn(r,this.bits),gn.set(t,r),Ve.delete(t)}hasCache(t){return We(t)!==1}}function Lr(e,t,r,n){let i=t,s=e.ZERO,o=e.ZERO;for(;r>le||n>le;)r&oe&&(s=s.add(i)),n&oe&&(o=o.add(i)),i=i.double(),r>>=oe,n>>=oe;return{p1:s,p2:o}}function Lt(e,t,r){if(t){if(t.ORDER!==e)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return Ir(t),t}else return Pe(e,{isLE:r})}function Pr(e,t,r={},n){if(n===void 0&&(n=e==="edwards"),!t||typeof t!="object")throw new Error(`expected valid ${e} CURVE object`);for(const a of["p","n","h"]){const l=t[a];if(!(typeof l=="bigint"&&l>le))throw new Error(`CURVE.${a} must be positive bigint`)}const i=Lt(t.p,r.Fp,n),s=Lt(t.n,r.Fn,n),c=["Gx","Gy","a","b"];for(const a of c)if(!i.isValid(t[a]))throw new Error(`CURVE.${a} must be valid field element of CURVE.Fp`);return t=Object.freeze(Object.assign({},t)),{CURVE:t,Fp:i,Fn:s}}function _r(e,t){return function(n){const i=e(n);return{secretKey:i,publicKey:t(i)}}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const Pt=(e,t)=>(e+(e>=0?t:-t)/Ur)/t;function Cr(e,t,r){const[[n,i],[s,o]]=t,c=Pt(o*e,r),a=Pt(-i*e,r);let l=e-c*n-a*s,p=-c*i-a*o;const d=l<he,u=p<he;d&&(l=-l),u&&(p=-p);const f=nn(Math.ceil(vr(r)/2))+Te;if(l<he||l>=f||p<he||p>=f)throw new Error("splitScalar (endomorphism): failed, k="+e);return{k1neg:d,k1:l,k2neg:u,k2:p}}const he=BigInt(0),Te=BigInt(1),Ur=BigInt(2),Re=BigInt(3),Hr=BigInt(4);function jr(e,t={}){const r=Pr("weierstrass",e,t),{Fp:n,Fn:i}=r;let s=r.CURVE;const{h:o,n:c}=s;rn(t,{},{allowInfinityPoint:"boolean",clearCofactor:"function",isTorsionFree:"function",fromBytes:"function",toBytes:"function",endo:"object"});const{endo:a}=t;if(a&&(!n.is0(s.a)||typeof a.beta!="bigint"||!Array.isArray(a.basises)))throw new Error('invalid endo: expected "beta": bigint and "basises": array');const l=Mr(n,i);function p(){if(!n.isOdd)throw new Error("compression is not supported: Field does not have .isOdd()")}function d(T,g,y){const{x:E,y:x}=g.toAffine(),B=n.toBytes(E);if(It(y,"isCompressed"),y){p();const R=!n.isOdd(x);return Be(Dr(R),B)}else return Be(Uint8Array.of(4),B,n.toBytes(x))}function u(T){D(T,void 0,"Point");const{publicKey:g,publicKeyUncompressed:y}=l,E=T.length,x=T[0],B=T.subarray(1);if(E===g&&(x===2||x===3)){const R=n.fromBytes(B);if(!n.isValid(R))throw new Error("bad point: is not on curve, wrong x");const k=w(R);let v;try{v=n.sqrt(k)}catch(M){const P=M instanceof Error?": "+M.message:"";throw new Error("bad point: is not on curve, sqrt error"+P)}p();const S=n.isOdd(v);return(x&1)===1!==S&&(v=n.neg(v)),{x:R,y:v}}else if(E===y&&x===4){const R=n.BYTES,k=n.fromBytes(B.subarray(0,R)),v=n.fromBytes(B.subarray(R,R*2));if(!I(k,v))throw new Error("bad point: is not on curve");return{x:k,y:v}}else throw new Error(`bad point: got length ${E}, expected compressed=${g} or uncompressed=${y}`)}const f=t.toBytes||d,m=t.fromBytes||u;function w(T){const g=n.sqr(T),y=n.mul(g,T);return n.add(n.add(y,n.mul(T,s.a)),s.b)}function I(T,g){const y=n.sqr(g),E=w(T);return n.eql(y,E)}if(!I(s.Gx,s.Gy))throw new Error("bad curve params: generator point");const N=n.mul(n.pow(s.a,Re),Hr),K=n.mul(n.sqr(s.b),BigInt(27));if(n.is0(n.add(N,K)))throw new Error("bad curve params: a or b");function Q(T,g,y=!1){if(!n.isValid(g)||y&&n.is0(g))throw new Error(`bad point coordinate ${T}`);return g}function we(T){if(!(T instanceof O))throw new Error("Weierstrass Point expected")}function ve(T){if(!a||!a.basises)throw new Error("no endo");return Cr(T,a.basises,i.ORDER)}const Ee=Tt((T,g)=>{const{X:y,Y:E,Z:x}=T;if(n.eql(x,n.ONE))return{x:y,y:E};const B=T.is0();g==null&&(g=B?n.ONE:n.inv(x));const R=n.mul(y,g),k=n.mul(E,g),v=n.mul(x,g);if(B)return{x:n.ZERO,y:n.ZERO};if(!n.eql(v,n.ONE))throw new Error("invZ was invalid");return{x:R,y:k}}),Sn=Tt(T=>{if(T.is0()){if(t.allowInfinityPoint&&!n.is0(T.Y))return;throw new Error("bad point: ZERO")}const{x:g,y}=T.toAffine();if(!n.isValid(g)||!n.isValid(y))throw new Error("bad point: x or y not field elements");if(!I(g,y))throw new Error("bad point: equation left != right");if(!T.isTorsionFree())throw new Error("bad point: not in prime-order subgroup");return!0});function gt(T,g,y,E,x){return y=new O(n.mul(y.X,T),y.Y,y.Z),g=Ne(E,g),y=Ne(x,y),g.add(y)}class O{static BASE=new O(s.Gx,s.Gy,n.ONE);static ZERO=new O(n.ZERO,n.ONE,n.ZERO);static Fp=n;static Fn=i;X;Y;Z;constructor(g,y,E){this.X=Q("x",g),this.Y=Q("y",y,!0),this.Z=Q("z",E),Object.freeze(this)}static CURVE(){return s}static fromAffine(g){const{x:y,y:E}=g||{};if(!g||!n.isValid(y)||!n.isValid(E))throw new Error("invalid affine point");if(g instanceof O)throw new Error("projective point not allowed");return n.is0(y)&&n.is0(E)?O.ZERO:new O(y,E,n.ONE)}static fromBytes(g){const y=O.fromAffine(m(D(g,void 0,"point")));return y.assertValidity(),y}static fromHex(g){return O.fromBytes(X(g))}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(g=8,y=!0){return ue.createCache(this,g),y||this.multiply(Re),this}assertValidity(){Sn(this)}hasEvenY(){const{y:g}=this.toAffine();if(!n.isOdd)throw new Error("Field doesn't support isOdd");return!n.isOdd(g)}equals(g){we(g);const{X:y,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=g,v=n.eql(n.mul(y,k),n.mul(B,x)),S=n.eql(n.mul(E,k),n.mul(R,x));return v&&S}negate(){return new O(this.X,n.neg(this.Y),this.Z)}double(){const{a:g,b:y}=s,E=n.mul(y,Re),{X:x,Y:B,Z:R}=this;let k=n.ZERO,v=n.ZERO,S=n.ZERO,$=n.mul(x,x),M=n.mul(B,B),P=n.mul(R,R),A=n.mul(x,B);return A=n.add(A,A),S=n.mul(x,R),S=n.add(S,S),k=n.mul(g,S),v=n.mul(E,P),v=n.add(k,v),k=n.sub(M,v),v=n.add(M,v),v=n.mul(k,v),k=n.mul(A,k),S=n.mul(E,S),P=n.mul(g,P),A=n.sub($,P),A=n.mul(g,A),A=n.add(A,S),S=n.add($,$),$=n.add(S,$),$=n.add($,P),$=n.mul($,A),v=n.add(v,$),P=n.mul(B,R),P=n.add(P,P),$=n.mul(P,A),k=n.sub(k,$),S=n.mul(P,M),S=n.add(S,S),S=n.add(S,S),new O(k,v,S)}add(g){we(g);const{X:y,Y:E,Z:x}=this,{X:B,Y:R,Z:k}=g;let v=n.ZERO,S=n.ZERO,$=n.ZERO;const M=s.a,P=n.mul(s.b,Re);let A=n.mul(y,B),V=n.mul(E,R),W=n.mul(x,k),ae=n.add(y,E),U=n.add(B,R);ae=n.mul(ae,U),U=n.add(A,V),ae=n.sub(ae,U),U=n.add(y,x);let Y=n.add(B,k);return U=n.mul(U,Y),Y=n.add(A,W),U=n.sub(U,Y),Y=n.add(E,x),v=n.add(R,k),Y=n.mul(Y,v),v=n.add(V,W),Y=n.sub(Y,v),$=n.mul(M,U),v=n.mul(P,W),$=n.add(v,$),v=n.sub(V,$),$=n.add(V,$),S=n.mul(v,$),V=n.add(A,A),V=n.add(V,A),W=n.mul(M,W),U=n.mul(P,U),V=n.add(V,W),W=n.sub(A,W),W=n.mul(M,W),U=n.add(U,W),A=n.mul(V,U),S=n.add(S,A),A=n.mul(Y,U),v=n.mul(ae,v),v=n.sub(v,A),A=n.mul(ae,V),$=n.mul(Y,$),$=n.add($,A),new O(v,S,$)}subtract(g){return this.add(g.negate())}is0(){return this.equals(O.ZERO)}multiply(g){const{endo:y}=t;if(!i.isValidNot0(g))throw new Error("invalid scalar: out of range");let E,x;const B=R=>ue.cached(this,R,k=>Ot(O,k));if(y){const{k1neg:R,k1:k,k2neg:v,k2:S}=ve(g),{p:$,f:M}=B(k),{p:P,f:A}=B(S);x=M.add(A),E=gt(y.beta,$,P,R,v)}else{const{p:R,f:k}=B(g);E=R,x=k}return Ot(O,[E,x])[0]}multiplyUnsafe(g){const{endo:y}=t,E=this;if(!i.isValid(g))throw new Error("invalid scalar: out of range");if(g===he||E.is0())return O.ZERO;if(g===Te)return E;if(ue.hasCache(this))return this.multiply(g);if(y){const{k1neg:x,k1:B,k2neg:R,k2:k}=ve(g),{p1:v,p2:S}=Lr(O,E,B,k);return gt(y.beta,v,S,x,R)}else return ue.unsafe(E,g)}toAffine(g){return Ee(this,g)}isTorsionFree(){const{isTorsionFree:g}=t;return o===Te?!0:g?g(O,this):ue.unsafe(this,c).is0()}clearCofactor(){const{clearCofactor:g}=t;return o===Te?this:g?g(O,this):this.multiplyUnsafe(o)}isSmallOrder(){return this.multiplyUnsafe(o).is0()}toBytes(g=!0){return It(g,"isCompressed"),this.assertValidity(),f(O,this,g)}toHex(g=!0){return _(this.toBytes(g))}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const bt=i.BITS,ue=new qr(O,t.endo?Math.ceil(bt/2):bt);return O.BASE.precompute(8),O}function Dr(e){return Uint8Array.of(e?2:3)}function Mr(e,t){return{secretKey:t.BYTES,publicKey:1+e.BYTES,publicKeyUncompressed:1+2*e.BYTES,publicKeyHasPrefix:!0,signature:2*t.BYTES}}/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */const _e={p:BigInt("0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),n:BigInt("0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),h:BigInt(1),a:BigInt(0),b:BigInt(7),Gx:BigInt("0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),Gy:BigInt("0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8")},Zr={beta:BigInt("0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),basises:[[BigInt("0x3086d221a7d46bcde86c90e49284eb15"),-BigInt("0xe4437ed6010e88286f547fa90abfe4c3")],[BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8"),BigInt("0x3086d221a7d46bcde86c90e49284eb15")]]},Vr=BigInt(0),tt=BigInt(2);function Wr(e){const t=_e.p,r=BigInt(3),n=BigInt(6),i=BigInt(11),s=BigInt(22),o=BigInt(23),c=BigInt(44),a=BigInt(88),l=e*e*e%t,p=l*l*e%t,d=Z(p,r,t)*p%t,u=Z(d,r,t)*p%t,f=Z(u,tt,t)*l%t,m=Z(f,i,t)*f%t,w=Z(m,s,t)*m%t,I=Z(w,c,t)*w%t,N=Z(I,a,t)*I%t,K=Z(N,c,t)*w%t,Q=Z(K,r,t)*p%t,we=Z(Q,o,t)*m%t,ve=Z(we,n,t)*l%t,Ee=Z(ve,tt,t);if(!qe.eql(qe.sqr(Ee),e))throw new Error("Cannot find square root");return Ee}const qe=Pe(_e.p,{sqrt:Wr}),de=jr(_e,{Fp:qe,endo:Zr}),_t={};function Le(e,...t){let r=_t[e];if(r===void 0){const n=Oe(yr(e));r=Be(n,n),_t[e]=r}return Oe(Be(r,...t))}const ht=e=>e.toBytes(!0).slice(1),pt=e=>e%tt===Vr;function nt(e){const{Fn:t,BASE:r}=de,n=t.fromBytes(e),i=r.multiply(n);return{scalar:pt(i.y)?n:t.neg(n),bytes:ht(i)}}function bn(e){const t=qe;if(!t.isValidNot0(e))throw new Error("invalid x: Fail if x ≥ p");const r=t.create(e*e),n=t.create(r*e+BigInt(7));let i=t.sqrt(n);pt(i)||(i=t.neg(i));const s=de.fromAffine({x:e,y:i});return s.assertValidity(),s}const be=dt;function mn(...e){return de.Fn.create(be(Le("BIP0340/challenge",...e)))}function Ct(e){return nt(e).bytes}function Fr(e,t,r=Ft(32)){const{Fn:n}=de,i=D(e,void 0,"message"),{bytes:s,scalar:o}=nt(t),c=D(r,32,"auxRand"),a=n.toBytes(o^be(Le("BIP0340/aux",c))),l=Le("BIP0340/nonce",a,s,i),{bytes:p,scalar:d}=nt(l),u=mn(p,s,i),f=new Uint8Array(64);if(f.set(p,0),f.set(n.toBytes(n.create(d+u*o)),32),!yn(f,i,s))throw new Error("sign: Invalid signature produced");return f}function yn(e,t,r){const{Fp:n,Fn:i,BASE:s}=de,o=D(e,64,"signature"),c=D(t,void 0,"message"),a=D(r,32,"publicKey");try{const l=bn(be(a)),p=be(o.subarray(0,32));if(!n.isValidNot0(p))return!1;const d=be(o.subarray(32,64));if(!i.isValidNot0(d))return!1;const u=mn(i.toBytes(p),ht(l),c),f=s.multiplyUnsafe(d).add(l.multiplyUnsafe(i.neg(u))),{x:m,y:w}=f.toAffine();return!(f.is0()||!pt(w)||m!==p)}catch{return!1}}const G=(()=>{const r=(n=Ft(48))=>Nr(n,_e.n);return{keygen:_r(r,Ct),getPublicKey:Ct,sign:Fr,verify:yn,Point:de,utils:{randomSecretKey:r,taggedHash:Le,lift_x:bn,pointToBytes:ht},lengths:{secretKey:32,publicKey:32,publicKeyHasPrefix:!1,signature:64,seed:48}}})();var ie=Symbol("verified"),Kr=e=>e instanceof Object;function Yr(e){if(!Kr(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var zr=new TextEncoder;function pe(e){try{e.indexOf("://")===-1&&(e="wss://"+e);let t=new URL(e);return t.protocol==="http:"?t.protocol="ws:":t.protocol==="https:"&&(t.protocol="wss:"),t.pathname=t.pathname.replace(/\/+/g,"/"),t.pathname.endsWith("/")&&(t.pathname=t.pathname.slice(0,-1)),(t.port==="80"&&t.protocol==="ws:"||t.port==="443"&&t.protocol==="wss:")&&(t.port=""),t.searchParams.sort(),t.hash="",t.toString()}catch{throw new Error(`Invalid URL: ${e}`)}}var Gr=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(t){return _(G.getPublicKey(t))}finalizeEvent(t,r){const n=t;return n.pubkey=_(G.getPublicKey(r)),n.id=Fe(n),n.sig=_(G.sign(X(Fe(n)),r)),n[ie]=!0,n}verifyEvent(t){if(typeof t[ie]=="boolean")return t[ie];try{const r=Fe(t);if(r!==t.id)return t[ie]=!1,!1;const n=G.verify(X(t.sig),X(r),X(t.pubkey));return t[ie]=n,n}catch{return t[ie]=!1,!1}}};function Xr(e){if(!Yr(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Fe(e){let t=Oe(zr.encode(Xr(e)));return _(t)}var Ce=new Gr;Ce.generateSecretKey;Ce.getPublicKey;Ce.finalizeEvent;var Jr=Ce.verifyEvent,Qr=22242;function ei(e,t){if(e.ids&&e.ids.indexOf(t.id)===-1||e.kinds&&e.kinds.indexOf(t.kind)===-1||e.authors&&e.authors.indexOf(t.pubkey)===-1)return!1;for(let r in e)if(r[0]==="#"){let n=r.slice(1),i=e[`#${n}`];if(i&&!t.tags.find(([s,o])=>s===r.slice(1)&&i.indexOf(o)!==-1))return!1}return!(e.since&&t.created_at<e.since||e.until&&t.created_at>e.until)}function ti(e,t){for(let r=0;r<e.length;r++)if(ei(e[r],t))return!0;return!1}function ni(e,t){let r=t.length+3,n=e.indexOf(`"${t}":`)+r,i=e.slice(n).indexOf('"')+n+1;return e.slice(i,i+64)}function ri(e){let t=e.slice(0,22).indexOf('"EVENT"');if(t===-1)return null;let r=e.slice(t+7+1).indexOf('"');if(r===-1)return null;let n=t+7+1+r,i=e.slice(n+1,80).indexOf('"');if(i===-1)return null;let s=n+1+i;return e.slice(n+1,s)}function ii(e,t){return{kind:Qr,created_at:Math.floor(Date.now()/1e3),tags:[["relay",e],["challenge",t]],content:""}}var wn=class extends Error{constructor(e,t){super(`Tried to send message '${e} on a closed connection to ${t}.`),this.name="SendingOnClosedConnection"}},vn=class{url;_connected=!1;onclose=null;onnotice=e=>console.debug(`NOTICE from ${this.url}: ${e}`);onauth;baseEoseTimeout=4400;publishTimeout=4400;pingFrequency=29e3;pingTimeout=2e4;resubscribeBackoff=[1e4,1e4,1e4,2e4,2e4,3e4,6e4];openSubs=new Map;enablePing;enableReconnect;idleSince=Date.now();ongoingOperations=0;reconnectTimeoutHandle;pingIntervalHandle;reconnectAttempts=0;skipReconnection=!1;connectionPromise;openCountRequests=new Map;openEventPublishes=new Map;ws;challenge;authPromise;serial=0;verifyEvent;_WebSocket;constructor(e,t){this.url=pe(e),this.verifyEvent=t.verifyEvent,this._WebSocket=t.websocketImplementation||WebSocket,this.enablePing=t.enablePing,this.enableReconnect=t.enableReconnect||!1}static async connect(e,t){const r=new vn(e,t);return await r.connect(t),r}closeAllSubscriptions(e){for(let[t,r]of this.openSubs)r.close(e);this.openSubs.clear();for(let[t,r]of this.openEventPublishes)r.reject(new Error(e));this.openEventPublishes.clear();for(let[t,r]of this.openCountRequests)r.reject(new Error(e));this.openCountRequests.clear()}get connected(){return this._connected}async reconnect(){const e=this.resubscribeBackoff[Math.min(this.reconnectAttempts,this.resubscribeBackoff.length-1)];this.reconnectAttempts++,this.reconnectTimeoutHandle=setTimeout(async()=>{try{await this.connect()}catch{}},e)}handleHardClose(e){this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this._connected=!1,this.connectionPromise=void 0,this.idleSince=void 0,this.enableReconnect&&!this.skipReconnection?this.reconnect():(this.onclose?.(),this.closeAllSubscriptions(e))}async connect(e){let t;return this.connectionPromise?this.connectionPromise:(this.challenge=void 0,this.authPromise=void 0,this.skipReconnection=!1,this.connectionPromise=new Promise((r,n)=>{e?.timeout&&(t=setTimeout(()=>{n("connection timed out"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection timed out")},e.timeout)),e?.abort&&(e.abort.onabort=n);try{this.ws=new this._WebSocket(this.url)}catch(i){clearTimeout(t),n(i);return}this.ws.onopen=()=>{this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),clearTimeout(t),this._connected=!0;const i=this.reconnectAttempts>0;this.reconnectAttempts=0;for(const s of this.openSubs.values()){if(s.eosed=!1,i)for(let o=0;o<s.filters.length;o++)s.lastEmitted&&(s.filters[o].since=s.lastEmitted+1);s.fire()}this.enablePing&&(this.pingIntervalHandle=setInterval(()=>this.pingpong(),this.pingFrequency)),r()},this.ws.onerror=()=>{clearTimeout(t),n("connection failed"),this.connectionPromise=void 0,this.skipReconnection=!0,this.onclose?.(),this.handleHardClose("relay connection failed")},this.ws.onclose=i=>{clearTimeout(t),n(i.message||"websocket closed"),this.handleHardClose("relay connection closed")},this.ws.onmessage=this._onmessage.bind(this)}),this.connectionPromise)}waitForPingPong(){return new Promise(e=>{this.ws.once("pong",()=>e(!0)),this.ws.ping()})}waitForDummyReq(){return new Promise((e,t)=>{if(!this.connectionPromise)return t(new Error(`no connection to ${this.url}, can't ping`));try{const r=this.subscribe([{ids:["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"],limit:0}],{label:"<forced-ping>",oneose:()=>{e(!0),r.close()},onclose(){e(!0)},eoseTimeout:this.pingTimeout+1e3})}catch(r){t(r)}})}async pingpong(){this.ws?.readyState===1&&(await Promise.any([this.ws&&this.ws.ping&&this.ws.once?this.waitForPingPong():this.waitForDummyReq(),new Promise(t=>setTimeout(()=>t(!1),this.pingTimeout))])||this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close())}async send(e){if(!this.connectionPromise)throw new wn(e,this.url);this.connectionPromise.then(()=>{this.ws?.send(e)})}async auth(e){const t=this.challenge;if(!t)throw new Error("can't perform auth, no challenge was received");return this.authPromise?this.authPromise:(this.authPromise=new Promise(async(r,n)=>{try{let i=await e(ii(this.url,t)),s=setTimeout(()=>{let o=this.openEventPublishes.get(i.id);o&&(o.reject(new Error("auth timed out")),this.openEventPublishes.delete(i.id))},this.publishTimeout);this.openEventPublishes.set(i.id,{resolve:r,reject:n,timeout:s}),this.send('["AUTH",'+JSON.stringify(i)+"]")}catch(i){console.warn("subscribe auth function failed:",i)}}),this.authPromise)}async publish(e){this.idleSince=void 0,this.ongoingOperations++;const t=new Promise((r,n)=>{const i=setTimeout(()=>{const s=this.openEventPublishes.get(e.id);s&&(s.reject(new Error("publish timed out")),this.openEventPublishes.delete(e.id))},this.publishTimeout);this.openEventPublishes.set(e.id,{resolve:r,reject:n,timeout:i})});return this.send('["EVENT",'+JSON.stringify(e)+"]"),this.ongoingOperations--,this.ongoingOperations===0&&(this.idleSince=Date.now()),t}async count(e,t){this.serial++;const r=t?.id||"count:"+this.serial,n=new Promise((i,s)=>{this.openCountRequests.set(r,{resolve:i,reject:s})});return this.send('["COUNT","'+r+'",'+JSON.stringify(e).substring(1)),n}subscribe(e,t){t.label!=="<forced-ping>"&&(this.idleSince=void 0,this.ongoingOperations++);const r=this.prepareSubscription(e,t);return r.fire(),t.abort&&(t.abort.onabort=()=>r.close(String(t.abort.reason||"<aborted>"))),r}prepareSubscription(e,t){this.serial++;const r=t.id||(t.label?t.label+":":"sub:")+this.serial,n=new si(this,r,e,t);return this.openSubs.set(r,n),n}close(){this.skipReconnection=!0,this.reconnectTimeoutHandle&&(clearTimeout(this.reconnectTimeoutHandle),this.reconnectTimeoutHandle=void 0),this.pingIntervalHandle&&(clearInterval(this.pingIntervalHandle),this.pingIntervalHandle=void 0),this.closeAllSubscriptions("relay connection closed by us"),this._connected=!1,this.idleSince=void 0,this.onclose?.(),this.ws?.readyState===this._WebSocket.OPEN&&this.ws?.close()}_onmessage(e){const t=e.data;if(!t)return;const r=ri(t);if(r){const n=this.openSubs.get(r);if(!n)return;const i=ni(t,"id"),s=n.alreadyHaveEvent?.(i);if(n.receivedEvent?.(this,i),s)return}try{let n=JSON.parse(t);switch(n[0]){case"EVENT":{const i=this.openSubs.get(n[1]),s=n[2];this.verifyEvent(s)&&ti(i.filters,s)?i.onevent(s):i.oninvalidevent?.(s),(!i.lastEmitted||i.lastEmitted<s.created_at)&&(i.lastEmitted=s.created_at);return}case"COUNT":{const i=n[1],s=n[2],o=this.openCountRequests.get(i);o&&(o.resolve(s.count),this.openCountRequests.delete(i));return}case"EOSE":{const i=this.openSubs.get(n[1]);if(!i)return;i.receivedEose();return}case"OK":{const i=n[1],s=n[2],o=n[3],c=this.openEventPublishes.get(i);c&&(clearTimeout(c.timeout),s?c.resolve(o):c.reject(new Error(o)),this.openEventPublishes.delete(i));return}case"CLOSED":{const i=n[1],s=this.openSubs.get(i);if(!s)return;s.closed=!0,s.close(n[2]);return}case"NOTICE":{this.onnotice(n[1]);return}case"AUTH":{this.challenge=n[1],this.onauth&&this.auth(this.onauth);return}default:{this.openSubs.get(n[1])?.oncustom?.(n);return}}}catch(n){try{const[i,s,o]=JSON.parse(t);console.warn(`[nostr] relay ${this.url} error processing message:`,n,o)}catch{console.warn(`[nostr] relay ${this.url} error processing message:`,n)}return}}},si=class{relay;id;lastEmitted;closed=!1;eosed=!1;filters;alreadyHaveEvent;receivedEvent;onevent;oninvalidevent;oneose;onclose;oncustom;eoseTimeout;eoseTimeoutHandle;constructor(e,t,r,n){if(r.length===0)throw new Error("subscription can't be created with zero filters");this.relay=e,this.filters=r,this.id=t,this.alreadyHaveEvent=n.alreadyHaveEvent,this.receivedEvent=n.receivedEvent,this.eoseTimeout=n.eoseTimeout||e.baseEoseTimeout,this.oneose=n.oneose,this.onclose=n.onclose,this.oninvalidevent=n.oninvalidevent,this.onevent=n.onevent||(i=>{console.warn(`onevent() callback not defined for subscription '${this.id}' in relay ${this.relay.url}. event received:`,i)})}fire(){this.relay.send('["REQ","'+this.id+'",'+JSON.stringify(this.filters).substring(1)),this.eoseTimeoutHandle=setTimeout(this.receivedEose.bind(this),this.eoseTimeout)}receivedEose(){this.eosed||(clearTimeout(this.eoseTimeoutHandle),this.eosed=!0,this.oneose?.())}close(e="closed by caller"){if(!this.closed&&this.relay.connected){try{this.relay.send('["CLOSE",'+JSON.stringify(this.id)+"]")}catch(t){if(!(t instanceof wn))throw t}this.closed=!0}this.relay.openSubs.delete(this.id),this.relay.ongoingOperations--,this.relay.ongoingOperations===0&&(this.relay.idleSince=Date.now()),this.onclose?.(e)}},oi=e=>(e[ie]=!0,!0),ai=class{relays=new Map;seenOn=new Map;trackRelays=!1;verifyEvent;enablePing;enableReconnect;automaticallyAuth;trustedRelayURLs=new Set;onRelayConnectionFailure;onRelayConnectionSuccess;allowConnectingToRelay;maxWaitForConnection;_WebSocket;constructor(e){this.verifyEvent=e.verifyEvent,this._WebSocket=e.websocketImplementation,this.enablePing=e.enablePing,this.enableReconnect=e.enableReconnect||!1,this.automaticallyAuth=e.automaticallyAuth,this.onRelayConnectionFailure=e.onRelayConnectionFailure,this.onRelayConnectionSuccess=e.onRelayConnectionSuccess,this.allowConnectingToRelay=e.allowConnectingToRelay,this.maxWaitForConnection=e.maxWaitForConnection||3e3}async ensureRelay(e,t){e=pe(e);let r=this.relays.get(e);if(r||(r=new vn(e,{verifyEvent:this.trustedRelayURLs.has(e)?oi:this.verifyEvent,websocketImplementation:this._WebSocket,enablePing:this.enablePing,enableReconnect:this.enableReconnect}),r.onclose=()=>{this.relays.delete(e)},this.relays.set(e,r)),this.automaticallyAuth){const n=this.automaticallyAuth(e);n&&(r.onauth=n)}try{await r.connect({timeout:t?.connectionTimeout,abort:t?.abort})}catch(n){throw this.relays.delete(e),n}return r}close(e){e.map(pe).forEach(t=>{this.relays.get(t)?.close(),this.relays.delete(t)})}subscribe(e,t,r){const n=[],i=[];for(let s=0;s<e.length;s++){const o=pe(e[s]);n.find(c=>c.url===o)||i.indexOf(o)===-1&&(i.push(o),n.push({url:o,filter:t}))}return this.subscribeMap(n,r)}subscribeMany(e,t,r){return this.subscribe(e,t,r)}subscribeMap(e,t){const r=new Map;for(const u of e){const{url:f,filter:m}=u;r.has(f)||r.set(f,[]),r.get(f).push(m)}const n=Array.from(r.entries()).map(([u,f])=>({url:u,filters:f}));this.trackRelays&&(t.receivedEvent=(u,f)=>{let m=this.seenOn.get(f);m||(m=new Set,this.seenOn.set(f,m)),m.add(u)});const i=new Set,s=[],o=[];let c=u=>{o[u]||(o[u]=!0,o.filter(f=>f).length===n.length&&(t.oneose?.(),c=()=>{}))};const a=[];let l=(u,f)=>{a[u]||(c(u),a[u]=f,a.filter(m=>m).length===n.length&&(t.onclose?.(a),l=()=>{}))};const p=u=>{if(t.alreadyHaveEvent?.(u))return!0;const f=i.has(u);return i.add(u),f},d=Promise.all(n.map(async({url:u,filters:f},m)=>{if(this.allowConnectingToRelay?.(u,["read",f])===!1){l(m,"connection skipped by allowConnectingToRelay");return}let w;try{w=await this.ensureRelay(u,{connectionTimeout:this.maxWaitForConnection<(t.maxWait||0)?Math.max(t.maxWait*.8,t.maxWait-1e3):this.maxWaitForConnection,abort:t.abort})}catch(N){this.onRelayConnectionFailure?.(u),l(m,N?.message||String(N));return}this.onRelayConnectionSuccess?.(u);let I=w.subscribe(f,{...t,oneose:()=>c(m),onclose:N=>{N.startsWith("auth-required: ")&&t.onauth?w.auth(t.onauth).then(()=>{w.subscribe(f,{...t,oneose:()=>c(m),onclose:K=>{l(m,K)},alreadyHaveEvent:p,eoseTimeout:t.maxWait,abort:t.abort})}).catch(K=>{l(m,`auth was required and attempted, but failed with: ${K}`)}):l(m,N)},alreadyHaveEvent:p,eoseTimeout:t.maxWait,abort:t.abort});s.push(I)}));return{async close(u){await d,s.forEach(f=>{f.close(u)})}}}subscribeEose(e,t,r){let n;return n=this.subscribe(e,t,{...r,oneose(){const i="closed automatically on eose";n?n.close(i):r.onclose?.(e.map(s=>i))}}),n}subscribeManyEose(e,t,r){return this.subscribeEose(e,t,r)}async querySync(e,t,r){return new Promise(async n=>{const i=[];this.subscribeEose(e,t,{...r,onevent(s){i.push(s)},onclose(s){n(i)}})})}async get(e,t,r){t.limit=1;const n=await this.querySync(e,t,r);return n.sort((i,s)=>s.created_at-i.created_at),n[0]||null}publish(e,t,r){return e.map(pe).map(async(n,i,s)=>{if(s.indexOf(n)!==i)return Promise.reject("duplicate url");if(this.allowConnectingToRelay?.(n,["write",t])===!1)return Promise.reject("connection skipped by allowConnectingToRelay");let o;try{o=await this.ensureRelay(n,{connectionTimeout:this.maxWaitForConnection<(r?.maxWait||0)?Math.max(r.maxWait*.8,r.maxWait-1e3):this.maxWaitForConnection,abort:r?.abort})}catch(c){return this.onRelayConnectionFailure?.(n),"connection failure: "+String(c)}return o.publish(t).catch(async c=>{if(c instanceof Error&&c.message.startsWith("auth-required: ")&&r?.onauth)return await o.auth(r.onauth),o.publish(t);throw c}).then(c=>{if(this.trackRelays){let a=this.seenOn.get(t.id);a||(a=new Set,this.seenOn.set(t.id,a)),a.add(o)}return c})})}listConnectionStatus(){const e=new Map;return this.relays.forEach((t,r)=>e.set(r,t.connected)),e}destroy(){this.relays.forEach(e=>e.close()),this.relays=new Map}pruneIdleRelays(e=1e4){const t=[];for(const[r,n]of this.relays)n.idleSince&&Date.now()-n.idleSince>=e&&(this.relays.delete(r),t.push(r),n.close());return t}},En;try{En=WebSocket}catch{}var ci=class extends ai{constructor(e){super({verifyEvent:Jr,websocketImplementation:En,maxWaitForConnection:3e3,...e})}},ce=Symbol("verified"),li=e=>e instanceof Object;function di(e){if(!li(e)||typeof e.kind!="number"||typeof e.content!="string"||typeof e.created_at!="number"||typeof e.pubkey!="string"||!e.pubkey.match(/^[a-f0-9]{64}$/)||!Array.isArray(e.tags))return!1;for(let t=0;t<e.tags.length;t++){let r=e.tags[t];if(!Array.isArray(r))return!1;for(let n=0;n<r.length;n++)if(typeof r[n]!="string")return!1}return!0}new TextDecoder("utf-8");var ui=new TextEncoder,fi=class{generateSecretKey(){return G.utils.randomSecretKey()}getPublicKey(e){return _(G.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=_(G.getPublicKey(t)),r.id=Ke(r),r.sig=_(G.sign(X(Ke(r)),t)),r[ce]=!0,r}verifyEvent(e){if(typeof e[ce]=="boolean")return e[ce];try{const t=Ke(e);if(t!==e.id)return e[ce]=!1,!1;const r=G.verify(X(e.sig),X(t),X(e.pubkey));return e[ce]=r,r}catch{return e[ce]=!1,!1}}};function hi(e){if(!di(e))throw new Error("can't serialize event with wrong or missing properties");return JSON.stringify([0,e.pubkey,e.created_at,e.kind,e.tags,e.content])}function Ke(e){let t=Oe(ui.encode(hi(e)));return _(t)}var Ue=new fi;Ue.generateSecretKey;Ue.getPublicKey;Ue.finalizeEvent;var pi=Ue.verifyEvent;const gi=8e3;function bi(e){return typeof e=="number"&&ot.includes(e)}function mi(e){try{const t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}function yi(e){const t=[];for(const r of e??[])try{const n=new URL(r);if(n.protocol!=="ws:"&&n.protocol!=="wss:")continue;t.push(n.href)}catch{}return[...new Set(t)]}function wi(e){const t=cr(e.trim());if(t.type!=="nevent"&&t.type!=="naddr")throw new Error("Enter a NIP-19 nevent or naddr for a NIP-5D napplet manifest event");const r=yi(t.data.relays);if(r.length===0)throw new Error("The pointer does not include relay hints; include at least one relay in the nevent/naddr");if(t.type==="nevent"){if(t.data.kind!==void 0&&!bi(t.data.kind))throw new Error(`nevent points at kind ${t.data.kind}, not a NIP-5D napplet manifest kind`);return{type:"nevent",relays:r,filter:{ids:[t.data.id],kinds:t.data.kind===void 0?[...ot]:[t.data.kind],authors:t.data.author?[t.data.author]:void 0,limit:1}}}if(t.data.kind!==ge)throw new Error(`naddr kind ${t.data.kind} is not the named napplet kind ${ge}`);return{type:"naddr",relays:r,filter:{kinds:[ge],authors:[t.data.pubkey],"#d":[t.data.identifier],limit:1}}}function vi(e){return{id:e.id,pubkey:e.pubkey,kind:e.kind,tags:e.tags}}async function xn(e){const t=typeof e=="string"?new TextEncoder().encode(e):e,r=new Uint8Array(t.byteLength);r.set(t);const n=await crypto.subtle.digest("SHA-256",r.buffer);return[...new Uint8Array(n)].map(i=>i.toString(16).padStart(2,"0")).join("")}function Ei(e){return e.tags.filter(t=>t[0]==="path"&&typeof t[1]=="string"&&typeof t[2]=="string")}async function xi(e){const t=Ei(e).map(r=>`${r[2]} ${r[1]}
77
- `).sort().join("");return xn(t)}async function ki(e){const t=await xi(e);for(const r of e.tags.filter(n=>n[0]==="x"))if(r[2]!==t)throw new Error(`Manifest x tag does not match recomputed aggregate hash ${t}`)}function Si(e){return e.tags.find(t=>t[0]==="path"&&t[1]==="/index.html")}function Ri(e){const t=[];for(const r of e.tags)if(!(r[0]!=="server"||!r[1]))try{const n=new URL(r[1]);(n.protocol==="http:"||n.protocol==="https:")&&t.push(n.href)}catch{}return[...new Set(t)]}function $i(e,t){const r=e.endsWith("/")?e:`${e}/`;return new URL(t,r).href}async function Ii(e,t=fetch){const n=Si(e)?.[2];if(!n)throw new Error("Manifest does not include a /index.html path hash");const i=Ri(e);if(i.length===0)throw new Error("Manifest does not include any usable Blossom server hints");const s=[];for(const o of i){const c=$i(o,n);try{const a=await t(c,{mode:"cors"});if(!a.ok){s.push(`${c}: HTTP ${a.status}`);continue}const l=new Uint8Array(await a.arrayBuffer()),p=await xn(l);if(p!==n){s.push(`${c}: sha256 ${p} did not match manifest ${n}`);continue}return new TextDecoder().decode(l)}catch(a){s.push(`${c}: ${a instanceof Error?a.message:String(a)}`)}}throw new Error(`Unable to fetch verified /index.html from Blossom servers: ${s.join("; ")}`)}async function Ti(e,t){try{const n=await(await t(e,{mode:"cors"})).text();return{source:"url",input:e,label:e,bootUrl:e,html:n,fetched:!0,manifestEvent:null}}catch{return{source:"url",input:e,label:e,bootUrl:e,html:"",fetched:!1,manifestEvent:null}}}async function Bi(e,t){const r=wi(e),n=!t.pool,i=t.pool??new ci;try{const s=await i.get(r.relays,{...r.filter},{maxWait:t.maxRelayWaitMs??gi});if(!s)throw new Error("No matching napplet manifest event was found on the pointer relay hints");if(!pi(s))throw new Error("Resolved manifest event signature is invalid");const o=vi(s),c=at(o);if(!c.ok)throw new Error(`Resolved event is not a valid NIP-5D napplet manifest: ${c.errors[0]?.message}`);await ki(o);const a=await Ii(o,t.fetcher??fetch),l=(t.createObjectUrl??URL.createObjectURL)(new Blob([a],{type:"text/html;charset=utf-8"})),p=()=>(t.revokeObjectUrl??URL.revokeObjectURL)(l);return{source:"nostr",input:e,label:o.id??e,bootUrl:l,html:a,fetched:!0,manifestEvent:o,revoke:p}}finally{n&&i.destroy()}}async function Ai(e,t={}){const r=e.trim();if(!r)throw new Error("Enter a NIP-19 nevent/naddr, or an HTTP URL for local dev");return mi(r)?Ti(r,t.fetcher??fetch):Bi(r,t)}const Oi=/\bwindow\s*\.\s*nostr\b|\bglobalThis\s*\.\s*nostr\b/,Ni="/__conformance__/events",rt=new URLSearchParams(location.search),kn=rt.get("live")==="1";function ne(e){return String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}const re=document.getElementById("app");function qi(){return re.innerHTML=`
78
- <header class="masthead">
79
- <h1>napplet conformance ${kn?'<span class="live-badge" id="live-badge">● live</span>':""}</h1>
80
- <p>Load a napplet by <code>nevent</code> or <code>naddr</code> and run NAP protocol conformance live. Same engine as <code>napplet-conformance</code> CI.</p>
81
- </header>
82
- <form id="run-form" class="runbar">
83
- <input id="target" type="text" placeholder="naddr1… or nevent1… for a NIP-5D napplet manifest" autocomplete="off" spellcheck="false" />
84
- <button id="run" type="submit">Run conformance</button>
85
- <button id="rerun" type="button" class="secondary" hidden>Re-run</button>
86
- </form>
87
- <p id="status" class="status" role="status"></p>
88
- <section id="output" class="output"></section>
89
- `,{targetInput:re.querySelector("#target"),runButton:re.querySelector("#run"),rerunButton:re.querySelector("#rerun"),liveBadge:re.querySelector("#live-badge")??document.createElement("span"),status:re.querySelector("#status"),output:re.querySelector("#output")}}const C=qi();let ye="",it=0;function $e(e,t="info"){C.status.textContent=e,C.status.dataset.kind=t}function Ye(e){return String(e).padStart(2,"0")}function Li(e){const t=new Date(e);return`${Ye(t.getHours())}:${Ye(t.getMinutes())}:${Ye(t.getSeconds())}`}function Pi(e){const t=e.ok?"conformant":"non-conformant",n=[...new Set(e.checks.map(o=>o.area))].map(o=>{const c=e.checks.filter(a=>a.area===o).map(a=>{const l=a.severity==="warning"&&a.status==="fail"?' <span class="tag warn">warning</span>':"",p=a.detail?`<span class="detail">${ne(a.detail)}</span>`:"";return`<li class="check ${a.status}"><span class="badge ${a.status}">${a.status}</span><span class="id">${ne(a.id)}</span>${l}${p}</li>`}).join("");return`<div class="area"><h3>${ne(o)}</h3><ul>${c}</ul></div>`}).join(""),i=e.summary,s=it>1?`<span class="run-stamp">run #${it} · ${Li(e.finishedAt)}</span>`:"";return`
90
- <div class="verdict ${t}">
91
- <span class="result">${e.ok?"CONFORMANT":"NON-CONFORMANT"}</span>
92
- <span class="counts">${i.passed} passed · ${i.failed} failed · ${i.skipped} skipped${i.warnings?` · ${i.warnings} warning(s)`:""}</span>
93
- ${s}
94
- </div>
95
- <div class="checks">${n}</div>
96
- `}function _i(e){return e.length===0?'<p class="empty">No envelopes were emitted.</p>':`<ul class="envlog">${e.map(r=>{const n=r.verdict.ok?"ok":"bad",i=r.verdict.ok?"":`<div class="errs">${r.verdict.errors.map(s=>ne(`${s.code}: ${s.message}`)).join("<br>")}</div>`;return`<li class="env ${n}"><code>${ne(JSON.stringify(r.envelope))}</code>${i}</li>`}).join("")}</ul>`}function Ci(e){const t=(r,n)=>`<tr><th>${ne(r)}</th><td>${n?ne(String(n)):"<em>—</em>"}</td></tr>`;if(e.manifestEvent){const r=e.manifestEvent,n=at(r),i=r.tags.find(c=>c[0]==="d")?.[1],s=r.tags.find(c=>c[0]==="path"&&c[1]==="/index.html"),o=r.tags.filter(c=>c[0]==="server").map(c=>c[1]).filter(Boolean);return`
97
- <table class="manifest">
98
- ${t("event",r.id)}
99
- ${t("kind",r.kind)}
100
- ${t("d",i)}
101
- ${t("name",Zt(r))}
102
- ${t("requires",n.requires.join(", "))}
103
- ${t("/index.html",s?.[2])}
104
- ${t("servers",o.join(", "))}
105
- </table>
106
- ${n.errors.length?`<div class="errs">${n.errors.map(c=>ne(`${c.code}: ${c.message}`)).join("<br>")}</div>`:""}
107
- `}return e.fetched?'<p class="empty">Local URL mode booted raw HTML. It does not include a signed NIP-5D manifest event, so manifest-event checks are skipped.</p>':`<p class="empty">Couldn't fetch the local URL HTML, likely because of CORS. Use a NIP-19 <code>nevent</code>/<code>naddr</code> for authoritative manifest checks, or use the CLI for local URL runs.</p>`}function Ui(e,t,r){C.output.innerHTML=`
108
- ${Pi(e)}
109
- <div class="panels">
110
- <section class="panel"><h2>Emitted envelopes (${t.length})</h2>${_i(t)}</section>
111
- <section class="panel"><h2>Manifest</h2>${Ci(r)}</section>
112
- </div>
113
- `}async function He(e){ye=e,C.runButton.disabled=!0,C.rerunButton.disabled=!0;let t=null;try{$e(`Resolving ${e} …`),t=await Ai(e);const r=Oi.test(t.html)?["window.nostr"]:[];$e("Booting napplet in a sandboxed iframe …");const n=await Zn({url:t.bootUrl,readyTimeoutMs:5e3,settleMs:800,runDegraded:!0}),i=Cn({manifestHtml:t.html,manifestEvent:t.manifestEvent,boot:n,forbiddenGlobals:r}),s=zn(i);it+=1,$e(s.ok?"Done — conformant.":"Done — non-conformant.",s.ok?"info":"error"),Ui(s,n.emitted,t),C.rerunButton.hidden=!1}catch(r){$e(`Error: ${r instanceof Error?r.message:String(r)}`,"error")}finally{t?.revoke?.(),C.runButton.disabled=!1,C.rerunButton.disabled=!1}}function Hi(){if(!kn||typeof EventSource>"u")return;let e=!1;const t=new EventSource(Ni);t.addEventListener("rerun",()=>{!ye||e||(e=!0,setTimeout(()=>{e=!1,He(ye)},50))}),t.addEventListener("open",()=>{C.liveBadge&&(C.liveBadge.dataset.state="connected")}),t.addEventListener("error",()=>{C.liveBadge&&(C.liveBadge.dataset.state="disconnected")})}C.runButton.parentElement.addEventListener("submit",e=>{e.preventDefault();const t=C.targetInput.value.trim();if(t){const r=new URL(location.href);r.searchParams.set("target",t),r.searchParams.delete("url"),history.replaceState(null,"",r),He(t)}});C.rerunButton.addEventListener("click",()=>{ye&&He(ye)});Hi();const ze=rt.get("target")??rt.get("url");ze&&(C.targetInput.value=ze,He(ze));