nostr-components 0.2.6 → 0.2.7

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.
Files changed (33) hide show
  1. package/dist/assets/{base-styles-CBypR3FR.js → base-styles-BSEzBDsk.js} +3 -3
  2. package/dist/assets/{base-styles-CBypR3FR.js.map → base-styles-BSEzBDsk.js.map} +1 -1
  3. package/dist/assets/{copy-delegation-C4uvRTVM.js → copy-delegation-B7y2q5Kn.js} +5 -5
  4. package/dist/assets/{copy-delegation-C4uvRTVM.js.map → copy-delegation-B7y2q5Kn.js.map} +1 -1
  5. package/dist/assets/{dialog-likers-BjiCHFan.js → dialog-likers-BqDn2P_3.js} +4 -4
  6. package/dist/assets/{dialog-likers-BjiCHFan.js.map → dialog-likers-BqDn2P_3.js.map} +1 -1
  7. package/dist/assets/{nostr-service-pr_crY62.js → nostr-service-CnaPxjc6.js} +2 -2
  8. package/dist/assets/{nostr-service-pr_crY62.js.map → nostr-service-CnaPxjc6.js.map} +1 -1
  9. package/dist/assets/{nostr-user-component-BOdux8_6.js → nostr-user-component-Cbs97dlK.js} +2 -2
  10. package/dist/assets/{nostr-user-component-BOdux8_6.js.map → nostr-user-component-Cbs97dlK.js.map} +1 -1
  11. package/dist/assets/{pure-jrVhRVpB.js → pure-DPo-pzxM.js} +2 -2
  12. package/dist/assets/{pure-jrVhRVpB.js.map → pure-DPo-pzxM.js.map} +1 -1
  13. package/dist/assets/{theme-C1r1Zw8r.js → theme-BN1Bvweb.js} +2 -2
  14. package/dist/assets/{theme-C1r1Zw8r.js.map → theme-BN1Bvweb.js.map} +1 -1
  15. package/dist/assets/{user-resolver-C-E6KdwY.js → user-resolver-CMmbtY9Y.js} +2 -2
  16. package/dist/assets/{user-resolver-C-E6KdwY.js.map → user-resolver-CMmbtY9Y.js.map} +1 -1
  17. package/dist/assets/{zap-utils-B1sz0Abx.js → zap-utils-KFUD_vTU.js} +2 -2
  18. package/dist/assets/{zap-utils-B1sz0Abx.js.map → zap-utils-KFUD_vTU.js.map} +1 -1
  19. package/dist/components/nostr-comment.es.js +5 -5
  20. package/dist/components/nostr-dm.es.js +2 -2
  21. package/dist/components/nostr-follow-button.es.js +2 -2
  22. package/dist/components/nostr-follow-button.es.js.map +1 -1
  23. package/dist/components/nostr-like.es.js +4 -4
  24. package/dist/components/nostr-live-chat.es.js +3 -3
  25. package/dist/components/nostr-live-chat.es.js.map +1 -1
  26. package/dist/components/nostr-post.es.js +2 -2
  27. package/dist/components/nostr-profile-badge.es.js +3 -3
  28. package/dist/components/nostr-profile.es.js +2 -2
  29. package/dist/components/nostr-zap.es.js +4 -4
  30. package/dist/components/nostr-zap.es.js.map +1 -1
  31. package/dist/nostr-components.es.js +1 -1
  32. package/dist/nostr-components.es.js.map +1 -1
  33. package/package.json +1 -1
@@ -1,2 +1,2 @@
1
- var l=Object.defineProperty;var p=(i,r,e)=>r in i?l(i,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[r]=e;var n=(i,r,e)=>p(i,typeof r!="symbol"?r+"":r,e);import{N as h,a as o}from"./base-styles-CBypR3FR.js";import{U as c}from"./user-resolver-C-E6KdwY.js";const d="nc:user";class C extends h{constructor(e=!0){super(e);n(this,"user",null);n(this,"profile",null);n(this,"userStatus",this.channel("user"));n(this,"loadSeq",0);n(this,"resolver",new c(this.nostrService))}static get observedAttributes(){return[...super.observedAttributes,"npub","pubkey","nip05"]}connectedCallback(){var e;(e=super.connectedCallback)==null||e.call(this),this.userStatus.get()==o.Idle&&this.initChannelStatus("user",o.Loading,{reflectOverall:!1}),this.validateInputs()&&this.resolveUserAndProfile().catch(t=>{console.error("[NostrUserComponent] init failed:",t)})}attributeChangedCallback(e,t,s){var u;t!==s&&((u=super.attributeChangedCallback)==null||u.call(this,e,t,s),(e==="npub"||e==="nip05"||e==="pubkey")&&this.validateInputs()&&this.resolveUserAndProfile())}validateInputs(){if(!super.validateInputs())return this.userStatus.set(o.Idle),!1;const e=this.getAttribute("npub"),t=this.getAttribute("pubkey"),s=this.getAttribute("nip05"),u=this.tagName.toLowerCase(),a=this.resolver.validateInputs({npub:e,pubkey:t,nip05:s});return a?(this.userStatus.set(o.Error,a),console.error(`Nostr-Components: ${u}: ${a}`),!1):(this.errorMessage="",!0)}async resolveUserAndProfile(){const e=++this.loadSeq;try{await this.ensureNostrConnected()}catch(t){if(e!==this.loadSeq)return;console.error("[NostrUserComponent] Relay connect failed before user/profile load:",t);return}this.userStatus.set(o.Loading);try{const{user:t,profile:s}=await this.resolver.resolveUser({npub:this.getAttribute("npub"),pubkey:this.getAttribute("pubkey"),nip05:this.getAttribute("nip05")});if(e!==this.loadSeq)return;if(s==null){this.userStatus.set(o.Error,"Profile not found");return}this.user=t,this.profile=s,this.userStatus.set(o.Ready),this.dispatchEvent(new CustomEvent(d,{detail:{user:this.user,profile:this.profile},bubbles:!0,composed:!0})),this.onUserReady(this.user,this.profile)}catch(t){if(e!==this.loadSeq)return;const s=t instanceof Error?t.message:"Failed to load user/profile";console.error("[NostrUserComponent] "+s,t),this.userStatus.set(o.Error,s)}}renderContent(){}onUserReady(e,t){}}export{C as N};
2
- //# sourceMappingURL=nostr-user-component-BOdux8_6.js.map
1
+ var l=Object.defineProperty;var p=(i,r,e)=>r in i?l(i,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[r]=e;var n=(i,r,e)=>p(i,typeof r!="symbol"?r+"":r,e);import{c as h,N as o}from"./base-styles-BSEzBDsk.js";import{U as c}from"./user-resolver-CMmbtY9Y.js";const d="nc:user";class C extends h{constructor(e=!0){super(e);n(this,"user",null);n(this,"profile",null);n(this,"userStatus",this.channel("user"));n(this,"loadSeq",0);n(this,"resolver",new c(this.nostrService))}static get observedAttributes(){return[...super.observedAttributes,"npub","pubkey","nip05"]}connectedCallback(){var e;(e=super.connectedCallback)==null||e.call(this),this.userStatus.get()==o.Idle&&this.initChannelStatus("user",o.Loading,{reflectOverall:!1}),this.validateInputs()&&this.resolveUserAndProfile().catch(t=>{console.error("[NostrUserComponent] init failed:",t)})}attributeChangedCallback(e,t,s){var u;t!==s&&((u=super.attributeChangedCallback)==null||u.call(this,e,t,s),(e==="npub"||e==="nip05"||e==="pubkey")&&this.validateInputs()&&this.resolveUserAndProfile())}validateInputs(){if(!super.validateInputs())return this.userStatus.set(o.Idle),!1;const e=this.getAttribute("npub"),t=this.getAttribute("pubkey"),s=this.getAttribute("nip05"),u=this.tagName.toLowerCase(),a=this.resolver.validateInputs({npub:e,pubkey:t,nip05:s});return a?(this.userStatus.set(o.Error,a),console.error(`Nostr-Components: ${u}: ${a}`),!1):(this.errorMessage="",!0)}async resolveUserAndProfile(){const e=++this.loadSeq;try{await this.ensureNostrConnected()}catch(t){if(e!==this.loadSeq)return;console.error("[NostrUserComponent] Relay connect failed before user/profile load:",t);return}this.userStatus.set(o.Loading);try{const{user:t,profile:s}=await this.resolver.resolveUser({npub:this.getAttribute("npub"),pubkey:this.getAttribute("pubkey"),nip05:this.getAttribute("nip05")});if(e!==this.loadSeq)return;if(s==null){this.userStatus.set(o.Error,"Profile not found");return}this.user=t,this.profile=s,this.userStatus.set(o.Ready),this.dispatchEvent(new CustomEvent(d,{detail:{user:this.user,profile:this.profile},bubbles:!0,composed:!0})),this.onUserReady(this.user,this.profile)}catch(t){if(e!==this.loadSeq)return;const s=t instanceof Error?t.message:"Failed to load user/profile";console.error("[NostrUserComponent] "+s,t),this.userStatus.set(o.Error,s)}}renderContent(){}onUserReady(e,t){}}export{C as N};
2
+ //# sourceMappingURL=nostr-user-component-Cbs97dlK.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"nostr-user-component-BOdux8_6.js","sources":["../../src/base/user-component/nostr-user-component.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrBaseComponent, NCStatus } from '../base-component/nostr-base-component';\nimport { UserResolver } from '../resolvers/user-resolver';\n\nconst EVT_USER = 'nc:user';\n\n/**\n * NostrUserComponent\n * ==================\n * Extension of `NostrBaseComponent` that resolves and manages a Nostr user.\n *\n * Overview\n * - Accepts identity attributes (`npub`, `nip05`, or `pubkey`) and validates them.\n * - Resolves an `NDKUser` via the shared `nostrService` and fetches its profile.\n * - Exposes resolved `user` and `profile` to subclasses for rendering or logic.\n * - Emits lifecycle events for status and user readiness.\n *\n * Observed attributes\n * - `npub` — user's Nostr public key (bech32 npub)\n * - `nip05` — NIP-05 identifier (e.g. `alice@example.com`)\n * - `pubkey` — raw hex-encoded public key\n *\n * Events\n * - `nc:status` — from base, reflects connection and user/profile loading status\n * - `nc:user` — fired when a user and profile are successfully resolved\n */\n\nexport class NostrUserComponent extends NostrBaseComponent {\n\n protected user: NDKUser | null = null;\n protected profile: NDKUserProfile | null = null;\n\n protected userStatus = this.channel('user');\n\n // guard to ignore stale user fetches\n private loadSeq = 0;\n\n private resolver = new UserResolver(this.nostrService);\n\n constructor(shadow: boolean = true) {\n super(shadow);\n }\n\n /** Lifecycle methods */\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'npub',\n 'pubkey',\n 'nip05',\n ];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n\n if (this.userStatus.get() == NCStatus.Idle) {\n this.initChannelStatus('user', NCStatus.Loading, { reflectOverall: false });\n }\n\n if (this.validateInputs()) {\n this.resolveUserAndProfile().catch(e => {\n console.error('[NostrUserComponent] init failed:', e);\n });\n }\n }\n\n attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'npub' || name === 'nip05' || name === 'pubkey') {\n if (this.validateInputs()) {\n // Re-resolve user + profile on identity changes\n void this.resolveUserAndProfile();\n }\n }\n }\n\n /** Protected methods */\n protected validateInputs(): boolean {\n\n if (!super.validateInputs()) {\n this.userStatus.set(NCStatus.Idle);\n return false;\n }\n\n const npub = this.getAttribute(\"npub\");\n const pubkey = this.getAttribute(\"pubkey\");\n const nip05 = this.getAttribute(\"nip05\");\n const tagName = this.tagName.toLowerCase();\n\n const err = this.resolver.validateInputs({\n npub: npub,\n pubkey: pubkey,\n nip05: nip05,\n });\n\n if (err) {\n this.userStatus.set(NCStatus.Error, err);\n console.error(`Nostr-Components: ${tagName}: ${err}`);\n return false;\n }\n\n this.errorMessage = \"\";\n return true;\n\n }\n\n protected async resolveUserAndProfile(): Promise<void> {\n const seq = ++this.loadSeq; // token to prevent stale writes\n\n // Ensure relays are connected; handle failure inside to avoid unhandled rejection\n try {\n await this.ensureNostrConnected();\n } catch (e) {\n if (seq !== this.loadSeq) return; // stale\n // Base already set status=Error, but make the failure explicit here too\n console.error('[NostrUserComponent] Relay connect failed before user/profile load:', e);\n return;\n }\n\n this.userStatus.set(NCStatus.Loading);\n\n try {\n const { user, profile } = await this.resolver.resolveUser({\n npub: this.getAttribute('npub'),\n pubkey: this.getAttribute('pubkey'),\n nip05: this.getAttribute('nip05'),\n });\n\n // stale call check\n if (seq !== this.loadSeq) return;\n\n if (profile == null) {\n this.userStatus.set(NCStatus.Error, \"Profile not found\");\n return;\n }\n\n this.user = user;\n this.profile = profile;\n this.userStatus.set(NCStatus.Ready);\n // Notify listeners that user + profile are available\n this.dispatchEvent(new CustomEvent(EVT_USER, {\n detail: { user: this.user, profile: this.profile },\n bubbles: true,\n composed: true,\n }));\n this.onUserReady(this.user!, this.profile);\n } catch (err) {\n if (seq !== this.loadSeq) return; // stale\n const msg = err instanceof Error ? err.message : 'Failed to load user/profile';\n console.error('[NostrUserComponent] ' + msg, err);\n this.userStatus.set(NCStatus.Error, msg);\n }\n }\n\n protected renderContent() { }\n\n /** Hook for subclasses to react when user/profile are ready (e.g., render). */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null) { }\n}\n"],"names":["EVT_USER","NostrUserComponent","NostrBaseComponent","shadow","__publicField","UserResolver","_a","NCStatus","e","name","oldValue","newValue","npub","pubkey","nip05","tagName","err","seq","user","profile","msg","_user","_profile"],"mappings":"yQAMA,MAAMA,EAAW,UAuBV,MAAMC,UAA2BC,CAAmB,CAYzD,YAAYC,EAAkB,GAAM,CAClC,MAAMA,CAAM,EAXJC,EAAA,YAAuB,MACvBA,EAAA,eAAiC,MAEjCA,EAAA,kBAAa,KAAK,QAAQ,MAAM,GAGlCA,EAAA,eAAU,GAEVA,EAAA,gBAAW,IAAIC,EAAa,KAAK,YAAY,EAGvC,CAId,WAAW,oBAAqB,CACvB,MAAA,CACL,GAAG,MAAM,mBACT,OACA,SACA,OACF,CAAA,CAGF,mBAAoB,QAClBC,EAAA,MAAM,oBAAN,MAAAA,EAAA,WAEI,KAAK,WAAW,IAAI,GAAKC,EAAS,MACpC,KAAK,kBAAkB,OAAQA,EAAS,QAAS,CAAE,eAAgB,GAAO,EAGxE,KAAK,kBACF,KAAA,sBAAA,EAAwB,MAAWC,GAAA,CAC9B,QAAA,MAAM,oCAAqCA,CAAC,CAAA,CACrD,CACH,CAGF,yBACEC,EACAC,EACAC,EACA,OACID,IAAaC,KACXL,EAAA,MAAA,2BAAA,MAAAA,EAAA,UAA2BG,EAAMC,EAAUC,IAE7CF,IAAS,QAAUA,IAAS,SAAWA,IAAS,WAC9C,KAAK,kBAEF,KAAK,sBAAsB,EAEpC,CAIQ,gBAA0B,CAE9B,GAAA,CAAC,MAAM,iBACJ,YAAA,WAAW,IAAIF,EAAS,IAAI,EAC1B,GAGH,MAAAK,EAAU,KAAK,aAAa,MAAM,EAClCC,EAAU,KAAK,aAAa,QAAQ,EACpCC,EAAU,KAAK,aAAa,OAAO,EACnCC,EAAU,KAAK,QAAQ,YAAY,EAEnCC,EAAM,KAAK,SAAS,eAAe,CACvC,KAAAJ,EACA,OAAAC,EACA,MAAAC,CAAA,CACD,EAED,OAAIE,GACF,KAAK,WAAW,IAAIT,EAAS,MAAOS,CAAG,EACvC,QAAQ,MAAM,qBAAqBD,CAAO,KAAKC,CAAG,EAAE,EAC7C,KAGT,KAAK,aAAe,GACb,GAAA,CAIT,MAAgB,uBAAuC,CAC/C,MAAAC,EAAM,EAAE,KAAK,QAGf,GAAA,CACF,MAAM,KAAK,qBAAqB,QACzBT,EAAG,CACN,GAAAS,IAAQ,KAAK,QAAS,OAElB,QAAA,MAAM,sEAAuET,CAAC,EACtF,MAAA,CAGG,KAAA,WAAW,IAAID,EAAS,OAAO,EAEhC,GAAA,CACF,KAAM,CAAE,KAAAW,EAAM,QAAAC,CAAA,EAAY,MAAM,KAAK,SAAS,YAAY,CACxD,KAAM,KAAK,aAAa,MAAM,EAC9B,OAAQ,KAAK,aAAa,QAAQ,EAClC,MAAO,KAAK,aAAa,OAAO,CAAA,CACjC,EAGG,GAAAF,IAAQ,KAAK,QAAS,OAE1B,GAAIE,GAAW,KAAM,CACnB,KAAK,WAAW,IAAIZ,EAAS,MAAO,mBAAmB,EACvD,MAAA,CAGF,KAAK,KAAOW,EACZ,KAAK,QAAUC,EACV,KAAA,WAAW,IAAIZ,EAAS,KAAK,EAE7B,KAAA,cAAc,IAAI,YAAYP,EAAU,CAC3C,OAAQ,CAAE,KAAM,KAAK,KAAM,QAAS,KAAK,OAAQ,EACjD,QAAS,GACT,SAAU,EAAA,CACX,CAAC,EACF,KAAK,YAAY,KAAK,KAAO,KAAK,OAAO,QAClCgB,EAAK,CACR,GAAAC,IAAQ,KAAK,QAAS,OAC1B,MAAMG,EAAMJ,aAAe,MAAQA,EAAI,QAAU,8BACzC,QAAA,MAAM,wBAA0BI,EAAKJ,CAAG,EAChD,KAAK,WAAW,IAAIT,EAAS,MAAOa,CAAG,CAAA,CACzC,CAGQ,eAAgB,CAAA,CAIhB,YAAYC,EAAgBC,EAAiC,CAAA,CACzE"}
1
+ {"version":3,"file":"nostr-user-component-Cbs97dlK.js","sources":["../../src/base/user-component/nostr-user-component.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrBaseComponent, NCStatus } from '../base-component/nostr-base-component';\nimport { UserResolver } from '../resolvers/user-resolver';\n\nconst EVT_USER = 'nc:user';\n\n/**\n * NostrUserComponent\n * ==================\n * Extension of `NostrBaseComponent` that resolves and manages a Nostr user.\n *\n * Overview\n * - Accepts identity attributes (`npub`, `nip05`, or `pubkey`) and validates them.\n * - Resolves an `NDKUser` via the shared `nostrService` and fetches its profile.\n * - Exposes resolved `user` and `profile` to subclasses for rendering or logic.\n * - Emits lifecycle events for status and user readiness.\n *\n * Observed attributes\n * - `npub` — user's Nostr public key (bech32 npub)\n * - `nip05` — NIP-05 identifier (e.g. `alice@example.com`)\n * - `pubkey` — raw hex-encoded public key\n *\n * Events\n * - `nc:status` — from base, reflects connection and user/profile loading status\n * - `nc:user` — fired when a user and profile are successfully resolved\n */\n\nexport class NostrUserComponent extends NostrBaseComponent {\n\n protected user: NDKUser | null = null;\n protected profile: NDKUserProfile | null = null;\n\n protected userStatus = this.channel('user');\n\n // guard to ignore stale user fetches\n private loadSeq = 0;\n\n private resolver = new UserResolver(this.nostrService);\n\n constructor(shadow: boolean = true) {\n super(shadow);\n }\n\n /** Lifecycle methods */\n static get observedAttributes() {\n return [\n ...super.observedAttributes,\n 'npub',\n 'pubkey',\n 'nip05',\n ];\n }\n\n connectedCallback() {\n super.connectedCallback?.();\n\n if (this.userStatus.get() == NCStatus.Idle) {\n this.initChannelStatus('user', NCStatus.Loading, { reflectOverall: false });\n }\n\n if (this.validateInputs()) {\n this.resolveUserAndProfile().catch(e => {\n console.error('[NostrUserComponent] init failed:', e);\n });\n }\n }\n\n attributeChangedCallback(\n name: string,\n oldValue: string | null,\n newValue: string | null\n ) {\n if (oldValue === newValue) return;\n super.attributeChangedCallback?.(name, oldValue, newValue);\n\n if (name === 'npub' || name === 'nip05' || name === 'pubkey') {\n if (this.validateInputs()) {\n // Re-resolve user + profile on identity changes\n void this.resolveUserAndProfile();\n }\n }\n }\n\n /** Protected methods */\n protected validateInputs(): boolean {\n\n if (!super.validateInputs()) {\n this.userStatus.set(NCStatus.Idle);\n return false;\n }\n\n const npub = this.getAttribute(\"npub\");\n const pubkey = this.getAttribute(\"pubkey\");\n const nip05 = this.getAttribute(\"nip05\");\n const tagName = this.tagName.toLowerCase();\n\n const err = this.resolver.validateInputs({\n npub: npub,\n pubkey: pubkey,\n nip05: nip05,\n });\n\n if (err) {\n this.userStatus.set(NCStatus.Error, err);\n console.error(`Nostr-Components: ${tagName}: ${err}`);\n return false;\n }\n\n this.errorMessage = \"\";\n return true;\n\n }\n\n protected async resolveUserAndProfile(): Promise<void> {\n const seq = ++this.loadSeq; // token to prevent stale writes\n\n // Ensure relays are connected; handle failure inside to avoid unhandled rejection\n try {\n await this.ensureNostrConnected();\n } catch (e) {\n if (seq !== this.loadSeq) return; // stale\n // Base already set status=Error, but make the failure explicit here too\n console.error('[NostrUserComponent] Relay connect failed before user/profile load:', e);\n return;\n }\n\n this.userStatus.set(NCStatus.Loading);\n\n try {\n const { user, profile } = await this.resolver.resolveUser({\n npub: this.getAttribute('npub'),\n pubkey: this.getAttribute('pubkey'),\n nip05: this.getAttribute('nip05'),\n });\n\n // stale call check\n if (seq !== this.loadSeq) return;\n\n if (profile == null) {\n this.userStatus.set(NCStatus.Error, \"Profile not found\");\n return;\n }\n\n this.user = user;\n this.profile = profile;\n this.userStatus.set(NCStatus.Ready);\n // Notify listeners that user + profile are available\n this.dispatchEvent(new CustomEvent(EVT_USER, {\n detail: { user: this.user, profile: this.profile },\n bubbles: true,\n composed: true,\n }));\n this.onUserReady(this.user!, this.profile);\n } catch (err) {\n if (seq !== this.loadSeq) return; // stale\n const msg = err instanceof Error ? err.message : 'Failed to load user/profile';\n console.error('[NostrUserComponent] ' + msg, err);\n this.userStatus.set(NCStatus.Error, msg);\n }\n }\n\n protected renderContent() { }\n\n /** Hook for subclasses to react when user/profile are ready (e.g., render). */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected onUserReady(_user: NDKUser, _profile: NDKUserProfile | null) { }\n}\n"],"names":["EVT_USER","NostrUserComponent","NostrBaseComponent","shadow","__publicField","UserResolver","_a","NCStatus","e","name","oldValue","newValue","npub","pubkey","nip05","tagName","err","seq","user","profile","msg","_user","_profile"],"mappings":"yQAMA,MAAMA,EAAW,UAuBV,MAAMC,UAA2BC,CAAmB,CAYzD,YAAYC,EAAkB,GAAM,CAClC,MAAMA,CAAM,EAXJC,EAAA,YAAuB,MACvBA,EAAA,eAAiC,MAEjCA,EAAA,kBAAa,KAAK,QAAQ,MAAM,GAGlCA,EAAA,eAAU,GAEVA,EAAA,gBAAW,IAAIC,EAAa,KAAK,YAAY,EAGvC,CAId,WAAW,oBAAqB,CACvB,MAAA,CACL,GAAG,MAAM,mBACT,OACA,SACA,OACF,CAAA,CAGF,mBAAoB,QAClBC,EAAA,MAAM,oBAAN,MAAAA,EAAA,WAEI,KAAK,WAAW,IAAI,GAAKC,EAAS,MACpC,KAAK,kBAAkB,OAAQA,EAAS,QAAS,CAAE,eAAgB,GAAO,EAGxE,KAAK,kBACF,KAAA,sBAAA,EAAwB,MAAWC,GAAA,CAC9B,QAAA,MAAM,oCAAqCA,CAAC,CAAA,CACrD,CACH,CAGF,yBACEC,EACAC,EACAC,EACA,OACID,IAAaC,KACXL,EAAA,MAAA,2BAAA,MAAAA,EAAA,UAA2BG,EAAMC,EAAUC,IAE7CF,IAAS,QAAUA,IAAS,SAAWA,IAAS,WAC9C,KAAK,kBAEF,KAAK,sBAAsB,EAEpC,CAIQ,gBAA0B,CAE9B,GAAA,CAAC,MAAM,iBACJ,YAAA,WAAW,IAAIF,EAAS,IAAI,EAC1B,GAGH,MAAAK,EAAU,KAAK,aAAa,MAAM,EAClCC,EAAU,KAAK,aAAa,QAAQ,EACpCC,EAAU,KAAK,aAAa,OAAO,EACnCC,EAAU,KAAK,QAAQ,YAAY,EAEnCC,EAAM,KAAK,SAAS,eAAe,CACvC,KAAAJ,EACA,OAAAC,EACA,MAAAC,CAAA,CACD,EAED,OAAIE,GACF,KAAK,WAAW,IAAIT,EAAS,MAAOS,CAAG,EACvC,QAAQ,MAAM,qBAAqBD,CAAO,KAAKC,CAAG,EAAE,EAC7C,KAGT,KAAK,aAAe,GACb,GAAA,CAIT,MAAgB,uBAAuC,CAC/C,MAAAC,EAAM,EAAE,KAAK,QAGf,GAAA,CACF,MAAM,KAAK,qBAAqB,QACzBT,EAAG,CACN,GAAAS,IAAQ,KAAK,QAAS,OAElB,QAAA,MAAM,sEAAuET,CAAC,EACtF,MAAA,CAGG,KAAA,WAAW,IAAID,EAAS,OAAO,EAEhC,GAAA,CACF,KAAM,CAAE,KAAAW,EAAM,QAAAC,CAAA,EAAY,MAAM,KAAK,SAAS,YAAY,CACxD,KAAM,KAAK,aAAa,MAAM,EAC9B,OAAQ,KAAK,aAAa,QAAQ,EAClC,MAAO,KAAK,aAAa,OAAO,CAAA,CACjC,EAGG,GAAAF,IAAQ,KAAK,QAAS,OAE1B,GAAIE,GAAW,KAAM,CACnB,KAAK,WAAW,IAAIZ,EAAS,MAAO,mBAAmB,EACvD,MAAA,CAGF,KAAK,KAAOW,EACZ,KAAK,QAAUC,EACV,KAAA,WAAW,IAAIZ,EAAS,KAAK,EAE7B,KAAA,cAAc,IAAI,YAAYP,EAAU,CAC3C,OAAQ,CAAE,KAAM,KAAK,KAAM,QAAS,KAAK,OAAQ,EACjD,QAAS,GACT,SAAU,EAAA,CACX,CAAC,EACF,KAAK,YAAY,KAAK,KAAO,KAAK,OAAO,QAClCgB,EAAK,CACR,GAAAC,IAAQ,KAAK,QAAS,OAC1B,MAAMG,EAAMJ,aAAe,MAAQA,EAAI,QAAU,8BACzC,QAAA,MAAM,wBAA0BI,EAAKJ,CAAG,EAChD,KAAK,WAAW,IAAIT,EAAS,MAAOa,CAAG,CAAA,CACzC,CAGQ,eAAgB,CAAA,CAIhB,YAAYC,EAAgBC,EAAiC,CAAA,CACzE"}
@@ -1,2 +1,2 @@
1
- import{s as a,b as n,a as o}from"./nostr-service-pr_crY62.js";var i=Symbol("verified"),l=e=>e instanceof Object;function c(e){if(!l(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 s=0;s<r.length;s++)if(typeof r[s]=="object")return!1}return!0}new TextDecoder("utf-8");var y=new TextEncoder,g=class{generateSecretKey(){return a.utils.randomPrivateKey()}getPublicKey(e){return n(a.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=n(a.getPublicKey(t)),r.id=u(r),r.sig=n(a.sign(u(r),t)),r[i]=!0,r}verifyEvent(e){if(typeof e[i]=="boolean")return e[i];const t=u(e);if(t!==e.id)return e[i]=!1,!1;try{const r=a.verify(e.sig,t,e.pubkey);return e[i]=r,r}catch{return e[i]=!1,!1}}};function b(e){if(!c(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 u(e){let t=o(y.encode(b(e)));return n(t)}var f=new g,p=f.generateSecretKey,h=f.getPublicKey,E=f.finalizeEvent;f.verifyEvent;export{E as finalizeEvent,p as generateSecretKey,u as getEventHash,h as getPublicKey,b as serializeEvent,c as validateEvent,i as verifiedSymbol};
2
- //# sourceMappingURL=pure-jrVhRVpB.js.map
1
+ import{s as a,f as n,g as o}from"./nostr-service-CnaPxjc6.js";var i=Symbol("verified"),l=e=>e instanceof Object;function c(e){if(!l(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 s=0;s<r.length;s++)if(typeof r[s]=="object")return!1}return!0}new TextDecoder("utf-8");var y=new TextEncoder,g=class{generateSecretKey(){return a.utils.randomPrivateKey()}getPublicKey(e){return n(a.getPublicKey(e))}finalizeEvent(e,t){const r=e;return r.pubkey=n(a.getPublicKey(t)),r.id=u(r),r.sig=n(a.sign(u(r),t)),r[i]=!0,r}verifyEvent(e){if(typeof e[i]=="boolean")return e[i];const t=u(e);if(t!==e.id)return e[i]=!1,!1;try{const r=a.verify(e.sig,t,e.pubkey);return e[i]=r,r}catch{return e[i]=!1,!1}}};function b(e){if(!c(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 u(e){let t=o(y.encode(b(e)));return n(t)}var f=new g,p=f.generateSecretKey,h=f.getPublicKey,E=f.finalizeEvent;f.verifyEvent;export{E as finalizeEvent,p as generateSecretKey,u as getEventHash,h as getPublicKey,b as serializeEvent,c as validateEvent,i as verifiedSymbol};
2
+ //# sourceMappingURL=pure-DPo-pzxM.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pure-jrVhRVpB.js","sources":["../../node_modules/nostr-tools/lib/esm/pure.js"],"sourcesContent":["// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] === \"object\")\n return false;\n }\n }\n return true;\n}\nfunction sortEvents(events) {\n return events.sort((a, b) => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\nexport {\n finalizeEvent,\n generateSecretKey,\n getEventHash,\n getPublicKey,\n serializeEvent,\n sortEvents,\n validateEvent,\n verifiedSymbol,\n verifyEvent\n};\n"],"names":["verifiedSymbol","isRecord","obj","validateEvent","event","i2","tag","j","utf8Encoder","JS","schnorr","secretKey","bytesToHex","t","getEventHash","hash","valid","serializeEvent","evt","eventHash","sha256","i","generateSecretKey","getPublicKey","finalizeEvent"],"mappings":"8DAKG,IAACA,EAAiB,OAAO,UAAU,EAClCC,EAAYC,GAAQA,aAAe,OACvC,SAASC,EAAcC,EAAO,CAa5B,GAZI,CAACH,EAASG,CAAK,GAEf,OAAOA,EAAM,MAAS,UAEtB,OAAOA,EAAM,SAAY,UAEzB,OAAOA,EAAM,YAAe,UAE5B,OAAOA,EAAM,QAAW,UAExB,CAACA,EAAM,OAAO,MAAM,gBAAgB,GAEpC,CAAC,MAAM,QAAQA,EAAM,IAAI,EAC3B,MAAO,GACT,QAASC,EAAK,EAAGA,EAAKD,EAAM,KAAK,OAAQC,IAAM,CAC7C,IAAIC,EAAMF,EAAM,KAAKC,CAAE,EACvB,GAAI,CAAC,MAAM,QAAQC,CAAG,EACpB,MAAO,GACT,QAASC,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAC9B,GAAI,OAAOD,EAAIC,CAAC,GAAM,SACpB,MAAO,EAEf,CACE,MAAO,EACT,CAckB,IAAI,YAAY,OAAO,EACzC,IAAIC,EAAc,IAAI,YAGlBC,EAAK,KAAM,CACb,mBAAoB,CAClB,OAAOC,EAAQ,MAAM,iBAAkB,CAC3C,CACE,aAAaC,EAAW,CACtB,OAAOC,EAAWF,EAAQ,aAAaC,CAAS,CAAC,CACrD,CACE,cAAcE,EAAGF,EAAW,CAC1B,MAAMP,EAAQS,EACd,OAAAT,EAAM,OAASQ,EAAWF,EAAQ,aAAaC,CAAS,CAAC,EACzDP,EAAM,GAAKU,EAAaV,CAAK,EAC7BA,EAAM,IAAMQ,EAAWF,EAAQ,KAAKI,EAAaV,CAAK,EAAGO,CAAS,CAAC,EACnEP,EAAMJ,CAAc,EAAI,GACjBI,CACX,CACE,YAAYA,EAAO,CACjB,GAAI,OAAOA,EAAMJ,CAAc,GAAM,UACnC,OAAOI,EAAMJ,CAAc,EAC7B,MAAMe,EAAOD,EAAaV,CAAK,EAC/B,GAAIW,IAASX,EAAM,GACjB,OAAAA,EAAMJ,CAAc,EAAI,GACjB,GAET,GAAI,CACF,MAAMgB,EAAQN,EAAQ,OAAON,EAAM,IAAKW,EAAMX,EAAM,MAAM,EAC1D,OAAAA,EAAMJ,CAAc,EAAIgB,EACjBA,CACR,MAAa,CACZ,OAAAZ,EAAMJ,CAAc,EAAI,GACjB,EACb,CACA,CACA,EACA,SAASiB,EAAeC,EAAK,CAC3B,GAAI,CAACf,EAAce,CAAG,EACpB,MAAM,IAAI,MAAM,wDAAwD,EAC1E,OAAO,KAAK,UAAU,CAAC,EAAGA,EAAI,OAAQA,EAAI,WAAYA,EAAI,KAAMA,EAAI,KAAMA,EAAI,OAAO,CAAC,CACxF,CACA,SAASJ,EAAaV,EAAO,CAC3B,IAAIe,EAAYC,EAAOZ,EAAY,OAAOS,EAAeb,CAAK,CAAC,CAAC,EAChE,OAAOQ,EAAWO,CAAS,CAC7B,CACA,IAAIE,EAAI,IAAIZ,EACRa,EAAoBD,EAAE,kBACtBE,EAAeF,EAAE,aACjBG,EAAgBH,EAAE,cACJA,EAAE","x_google_ignoreList":[0]}
1
+ {"version":3,"file":"pure-DPo-pzxM.js","sources":["../../node_modules/nostr-tools/lib/esm/pure.js"],"sourcesContent":["// pure.ts\nimport { schnorr } from \"@noble/curves/secp256k1\";\nimport { bytesToHex } from \"@noble/hashes/utils\";\n\n// core.ts\nvar verifiedSymbol = Symbol(\"verified\");\nvar isRecord = (obj) => obj instanceof Object;\nfunction validateEvent(event) {\n if (!isRecord(event))\n return false;\n if (typeof event.kind !== \"number\")\n return false;\n if (typeof event.content !== \"string\")\n return false;\n if (typeof event.created_at !== \"number\")\n return false;\n if (typeof event.pubkey !== \"string\")\n return false;\n if (!event.pubkey.match(/^[a-f0-9]{64}$/))\n return false;\n if (!Array.isArray(event.tags))\n return false;\n for (let i2 = 0; i2 < event.tags.length; i2++) {\n let tag = event.tags[i2];\n if (!Array.isArray(tag))\n return false;\n for (let j = 0; j < tag.length; j++) {\n if (typeof tag[j] === \"object\")\n return false;\n }\n }\n return true;\n}\nfunction sortEvents(events) {\n return events.sort((a, b) => {\n if (a.created_at !== b.created_at) {\n return b.created_at - a.created_at;\n }\n return a.id.localeCompare(b.id);\n });\n}\n\n// pure.ts\nimport { sha256 } from \"@noble/hashes/sha256\";\n\n// utils.ts\nvar utf8Decoder = new TextDecoder(\"utf-8\");\nvar utf8Encoder = new TextEncoder();\n\n// pure.ts\nvar JS = class {\n generateSecretKey() {\n return schnorr.utils.randomPrivateKey();\n }\n getPublicKey(secretKey) {\n return bytesToHex(schnorr.getPublicKey(secretKey));\n }\n finalizeEvent(t, secretKey) {\n const event = t;\n event.pubkey = bytesToHex(schnorr.getPublicKey(secretKey));\n event.id = getEventHash(event);\n event.sig = bytesToHex(schnorr.sign(getEventHash(event), secretKey));\n event[verifiedSymbol] = true;\n return event;\n }\n verifyEvent(event) {\n if (typeof event[verifiedSymbol] === \"boolean\")\n return event[verifiedSymbol];\n const hash = getEventHash(event);\n if (hash !== event.id) {\n event[verifiedSymbol] = false;\n return false;\n }\n try {\n const valid = schnorr.verify(event.sig, hash, event.pubkey);\n event[verifiedSymbol] = valid;\n return valid;\n } catch (err) {\n event[verifiedSymbol] = false;\n return false;\n }\n }\n};\nfunction serializeEvent(evt) {\n if (!validateEvent(evt))\n throw new Error(\"can't serialize event with wrong or missing properties\");\n return JSON.stringify([0, evt.pubkey, evt.created_at, evt.kind, evt.tags, evt.content]);\n}\nfunction getEventHash(event) {\n let eventHash = sha256(utf8Encoder.encode(serializeEvent(event)));\n return bytesToHex(eventHash);\n}\nvar i = new JS();\nvar generateSecretKey = i.generateSecretKey;\nvar getPublicKey = i.getPublicKey;\nvar finalizeEvent = i.finalizeEvent;\nvar verifyEvent = i.verifyEvent;\nexport {\n finalizeEvent,\n generateSecretKey,\n getEventHash,\n getPublicKey,\n serializeEvent,\n sortEvents,\n validateEvent,\n verifiedSymbol,\n verifyEvent\n};\n"],"names":["verifiedSymbol","isRecord","obj","validateEvent","event","i2","tag","j","utf8Encoder","JS","schnorr","secretKey","bytesToHex","t","getEventHash","hash","valid","serializeEvent","evt","eventHash","sha256","i","generateSecretKey","getPublicKey","finalizeEvent"],"mappings":"8DAKG,IAACA,EAAiB,OAAO,UAAU,EAClCC,EAAYC,GAAQA,aAAe,OACvC,SAASC,EAAcC,EAAO,CAa5B,GAZI,CAACH,EAASG,CAAK,GAEf,OAAOA,EAAM,MAAS,UAEtB,OAAOA,EAAM,SAAY,UAEzB,OAAOA,EAAM,YAAe,UAE5B,OAAOA,EAAM,QAAW,UAExB,CAACA,EAAM,OAAO,MAAM,gBAAgB,GAEpC,CAAC,MAAM,QAAQA,EAAM,IAAI,EAC3B,MAAO,GACT,QAASC,EAAK,EAAGA,EAAKD,EAAM,KAAK,OAAQC,IAAM,CAC7C,IAAIC,EAAMF,EAAM,KAAKC,CAAE,EACvB,GAAI,CAAC,MAAM,QAAQC,CAAG,EACpB,MAAO,GACT,QAASC,EAAI,EAAGA,EAAID,EAAI,OAAQC,IAC9B,GAAI,OAAOD,EAAIC,CAAC,GAAM,SACpB,MAAO,EAEf,CACE,MAAO,EACT,CAckB,IAAI,YAAY,OAAO,EACzC,IAAIC,EAAc,IAAI,YAGlBC,EAAK,KAAM,CACb,mBAAoB,CAClB,OAAOC,EAAQ,MAAM,iBAAkB,CAC3C,CACE,aAAaC,EAAW,CACtB,OAAOC,EAAWF,EAAQ,aAAaC,CAAS,CAAC,CACrD,CACE,cAAcE,EAAGF,EAAW,CAC1B,MAAMP,EAAQS,EACd,OAAAT,EAAM,OAASQ,EAAWF,EAAQ,aAAaC,CAAS,CAAC,EACzDP,EAAM,GAAKU,EAAaV,CAAK,EAC7BA,EAAM,IAAMQ,EAAWF,EAAQ,KAAKI,EAAaV,CAAK,EAAGO,CAAS,CAAC,EACnEP,EAAMJ,CAAc,EAAI,GACjBI,CACX,CACE,YAAYA,EAAO,CACjB,GAAI,OAAOA,EAAMJ,CAAc,GAAM,UACnC,OAAOI,EAAMJ,CAAc,EAC7B,MAAMe,EAAOD,EAAaV,CAAK,EAC/B,GAAIW,IAASX,EAAM,GACjB,OAAAA,EAAMJ,CAAc,EAAI,GACjB,GAET,GAAI,CACF,MAAMgB,EAAQN,EAAQ,OAAON,EAAM,IAAKW,EAAMX,EAAM,MAAM,EAC1D,OAAAA,EAAMJ,CAAc,EAAIgB,EACjBA,CACR,MAAa,CACZ,OAAAZ,EAAMJ,CAAc,EAAI,GACjB,EACb,CACA,CACA,EACA,SAASiB,EAAeC,EAAK,CAC3B,GAAI,CAACf,EAAce,CAAG,EACpB,MAAM,IAAI,MAAM,wDAAwD,EAC1E,OAAO,KAAK,UAAU,CAAC,EAAGA,EAAI,OAAQA,EAAI,WAAYA,EAAI,KAAMA,EAAI,KAAMA,EAAI,OAAO,CAAC,CACxF,CACA,SAASJ,EAAaV,EAAO,CAC3B,IAAIe,EAAYC,EAAOZ,EAAY,OAAOS,EAAeb,CAAK,CAAC,CAAC,EAChE,OAAOQ,EAAWO,CAAS,CAC7B,CACA,IAAIE,EAAI,IAAIZ,EACRa,EAAoBD,EAAE,kBACtBE,EAAeF,EAAE,aACjBG,EAAgBH,EAAE,cACJA,EAAE","x_google_ignoreList":[0]}
@@ -1,2 +1,2 @@
1
- import{c as t,n as r,l as a}from"./icons-Dr_d9MII.js";function c(o=21,n=24){return r(o,n)}function i(){return a()}function e(o="dark"){return t(o)}export{i as a,e as b,c as g};
2
- //# sourceMappingURL=theme-C1r1Zw8r.js.map
1
+ import{c as t,n as r,l as a}from"./icons-Dr_d9MII.js";function c(o=21,n=24){return r(o,n)}function i(){return a()}function e(o="dark"){return t(o)}export{c as a,i as b,e as g};
2
+ //# sourceMappingURL=theme-BN1Bvweb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"theme-C1r1Zw8r.js","sources":["../../src/common/theme.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { Theme } from './types';\nimport { checkmarkIcon, nostrLogo } from './icons';\n\nexport function getNostrLogo(width: number = 21, height: number = 24) {\n return nostrLogo(width, height);\n}\n\nimport { loadingNostrich } from './icons';\n\nexport function getLoadingNostrich(){\n return loadingNostrich();\n}\n\nexport function getSuccessAnimation(theme: Theme = 'dark') {\n return checkmarkIcon(theme);\n}"],"names":["getNostrLogo","width","height","nostrLogo","getLoadingNostrich","loadingNostrich","getSuccessAnimation","theme","checkmarkIcon"],"mappings":"sDAKO,SAASA,EAAaC,EAAgB,GAAIC,EAAiB,GAAI,CAC7D,OAAAC,EAAUF,EAAOC,CAAM,CAChC,CAIO,SAASE,GAAoB,CAClC,OAAOC,EAAgB,CACzB,CAEgB,SAAAC,EAAoBC,EAAe,OAAQ,CACzD,OAAOC,EAAcD,CAAK,CAC5B"}
1
+ {"version":3,"file":"theme-BN1Bvweb.js","sources":["../../src/common/theme.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { Theme } from './types';\nimport { checkmarkIcon, nostrLogo } from './icons';\n\nexport function getNostrLogo(width: number = 21, height: number = 24) {\n return nostrLogo(width, height);\n}\n\nimport { loadingNostrich } from './icons';\n\nexport function getLoadingNostrich(){\n return loadingNostrich();\n}\n\nexport function getSuccessAnimation(theme: Theme = 'dark') {\n return checkmarkIcon(theme);\n}"],"names":["getNostrLogo","width","height","nostrLogo","getLoadingNostrich","loadingNostrich","getSuccessAnimation","theme","checkmarkIcon"],"mappings":"sDAKO,SAASA,EAAaC,EAAgB,GAAIC,EAAiB,GAAI,CAC7D,OAAAC,EAAUF,EAAOC,CAAM,CAChC,CAIO,SAASE,GAAoB,CAClC,OAAOC,EAAgB,CACzB,CAEgB,SAAAC,EAAoBC,EAAe,OAAQ,CACzD,OAAOC,EAAcD,CAAK,CAC5B"}
@@ -1,2 +1,2 @@
1
- import{i as o,v as a,b as l}from"./base-styles-CBypR3FR.js";class u{constructor(r){this.nostrService=r}validateInputs({npub:r,pubkey:e,nip05:i}){return!r&&!e&&!i?"Provide npub, nip05 or pubkey attribute":e&&!o(e)?`Invalid Pubkey: ${e}`:i&&!a(i)?`Invalid Nip05: ${i}`:r&&!l(r)?`Invalid Npub: ${r}`:null}async resolveUser({npub:r,pubkey:e,nip05:i}){const t=await this.nostrService.resolveNDKUser({npub:r,pubkey:e,nip05:i});if(!t)throw new Error("Unable to resolve user from provided identifier");const s=await this.nostrService.getProfile(t);return{user:t,profile:s??null}}}export{u as U};
2
- //# sourceMappingURL=user-resolver-C-E6KdwY.js.map
1
+ import{a as o,l as a,n as l}from"./base-styles-BSEzBDsk.js";class u{constructor(r){this.nostrService=r}validateInputs({npub:r,pubkey:e,nip05:i}){return!r&&!e&&!i?"Provide npub, nip05 or pubkey attribute":e&&!o(e)?`Invalid Pubkey: ${e}`:i&&!a(i)?`Invalid Nip05: ${i}`:r&&!l(r)?`Invalid Npub: ${r}`:null}async resolveUser({npub:r,pubkey:e,nip05:i}){const t=await this.nostrService.resolveNDKUser({npub:r,pubkey:e,nip05:i});if(!t)throw new Error("Unable to resolve user from provided identifier");const s=await this.nostrService.getProfile(t);return{user:t,profile:s??null}}}export{u as U};
2
+ //# sourceMappingURL=user-resolver-CMmbtY9Y.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-resolver-C-E6KdwY.js","sources":["../../src/base/resolvers/user-resolver.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrService } from '../../common/nostr-service';\nimport { isValidHex, validateNpub, validateNip05 } from '../../common/utils'\n\nexport class UserResolver {\n constructor(private nostrService: NostrService) { }\n\n validateInputs({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): string | null {\n if (!npub && !pubkey && !nip05) {\n return \"Provide npub, nip05 or pubkey attribute\";\n }\n if (pubkey && !isValidHex(pubkey)) return `Invalid Pubkey: ${pubkey}`;\n if (nip05 && !validateNip05(nip05)) return `Invalid Nip05: ${nip05}`;\n if (npub && !validateNpub(npub)) return `Invalid Npub: ${npub}`;\n return null;\n }\n\n async resolveUser({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): Promise<{ user: NDKUser, profile: NDKUserProfile | null }> {\n const user = await this.nostrService.resolveNDKUser({ npub, pubkey, nip05 });\n if (!user) throw new Error(\"Unable to resolve user from provided identifier\");\n\n const profile = await this.nostrService.getProfile(user);\n\n return { user, profile: profile ?? null };\n }\n}\n"],"names":["UserResolver","nostrService","npub","pubkey","nip05","isValidHex","validateNip05","validateNpub","user","profile"],"mappings":"4DAMO,MAAMA,CAAa,CACxB,YAAoBC,EAA4B,CAA5B,KAAA,aAAAA,CAAA,CAEpB,eAAe,CAAE,KAAAC,EAAM,OAAAC,EAAQ,MAAAC,GAAiG,CAC9H,MAAI,CAACF,GAAQ,CAACC,GAAU,CAACC,EAChB,0CAELD,GAAU,CAACE,EAAWF,CAAM,EAAU,mBAAmBA,CAAM,GAC/DC,GAAS,CAACE,EAAcF,CAAK,EAAU,kBAAkBA,CAAK,GAC9DF,GAAQ,CAACK,EAAaL,CAAI,EAAU,iBAAiBA,CAAI,GACtD,IAAA,CAGT,MAAM,YAAY,CAAE,KAAAA,EAAM,OAAAC,EAAQ,MAAAC,GAA8I,CACxK,MAAAI,EAAO,MAAM,KAAK,aAAa,eAAe,CAAE,KAAAN,EAAM,OAAAC,EAAQ,MAAAC,EAAO,EAC3E,GAAI,CAACI,EAAY,MAAA,IAAI,MAAM,iDAAiD,EAE5E,MAAMC,EAAU,MAAM,KAAK,aAAa,WAAWD,CAAI,EAEvD,MAAO,CAAE,KAAAA,EAAM,QAASC,GAAW,IAAK,CAAA,CAE5C"}
1
+ {"version":3,"file":"user-resolver-CMmbtY9Y.js","sources":["../../src/base/resolvers/user-resolver.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport { NDKUser, NDKUserProfile } from '@nostr-dev-kit/ndk';\nimport { NostrService } from '../../common/nostr-service';\nimport { isValidHex, validateNpub, validateNip05 } from '../../common/utils'\n\nexport class UserResolver {\n constructor(private nostrService: NostrService) { }\n\n validateInputs({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): string | null {\n if (!npub && !pubkey && !nip05) {\n return \"Provide npub, nip05 or pubkey attribute\";\n }\n if (pubkey && !isValidHex(pubkey)) return `Invalid Pubkey: ${pubkey}`;\n if (nip05 && !validateNip05(nip05)) return `Invalid Nip05: ${nip05}`;\n if (npub && !validateNpub(npub)) return `Invalid Npub: ${npub}`;\n return null;\n }\n\n async resolveUser({ npub, pubkey, nip05 }: { npub?: string | null; pubkey?: string | null; nip05?: string | null }): Promise<{ user: NDKUser, profile: NDKUserProfile | null }> {\n const user = await this.nostrService.resolveNDKUser({ npub, pubkey, nip05 });\n if (!user) throw new Error(\"Unable to resolve user from provided identifier\");\n\n const profile = await this.nostrService.getProfile(user);\n\n return { user, profile: profile ?? null };\n }\n}\n"],"names":["UserResolver","nostrService","npub","pubkey","nip05","isValidHex","validateNip05","validateNpub","user","profile"],"mappings":"4DAMO,MAAMA,CAAa,CACxB,YAAoBC,EAA4B,CAA5B,KAAA,aAAAA,CAAA,CAEpB,eAAe,CAAE,KAAAC,EAAM,OAAAC,EAAQ,MAAAC,GAAiG,CAC9H,MAAI,CAACF,GAAQ,CAACC,GAAU,CAACC,EAChB,0CAELD,GAAU,CAACE,EAAWF,CAAM,EAAU,mBAAmBA,CAAM,GAC/DC,GAAS,CAACE,EAAcF,CAAK,EAAU,kBAAkBA,CAAK,GAC9DF,GAAQ,CAACK,EAAaL,CAAI,EAAU,iBAAiBA,CAAI,GACtD,IAAA,CAGT,MAAM,YAAY,CAAE,KAAAA,EAAM,OAAAC,EAAQ,MAAAC,GAA8I,CACxK,MAAAI,EAAO,MAAM,KAAK,aAAa,eAAe,CAAE,KAAAN,EAAM,OAAAC,EAAQ,MAAAC,EAAO,EAC3E,GAAI,CAACI,EAAY,MAAA,IAAI,MAAM,iDAAiD,EAE5E,MAAMC,EAAU,MAAM,KAAK,aAAa,WAAWD,CAAI,EAEvD,MAAO,CAAE,KAAAA,EAAM,QAASC,GAAW,IAAK,CAAA,CAE5C"}
@@ -1,2 +1,2 @@
1
- import{S as E,n as N,f as P}from"./nostr-service-pr_crY62.js";import{n as k}from"./utils--bxLbhGF.js";const m={},$=async t=>{if(m[t])return m[t];const n=new E,e=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{const a=await n.get(e,{authors:[t],kinds:[0]});return m[t]=a,a}finally{n.close(e)}},O=async t=>{const n=t.filter(r=>!m[r]);if(n.length===0)return t.map(r=>({id:r,profile:m[r]}));const e=new E,a=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{return(await e.querySync(a,{authors:n,kinds:[0]})).forEach(o=>{m[o.pubkey]=o}),t.map(o=>({id:o,profile:m[o]||null}))}finally{e.close(a)}},x=t=>{try{return JSON.parse((t==null?void 0:t.content)||"{}")}catch{return{}}},z=async t=>{const n=await N.getZapEndpoint(t);if(!n)throw new Error("Failed to retrieve zap LNURL");return n},S=async(t,n)=>{if(R())try{const e=window.nostr;if(e!=null&&e.signEvent)return await e.signEvent(t)}catch{}return P(t,C())},Z=async({profile:t,nip19Target:n,amount:e,relays:a,comment:r,anon:c,url:o})=>{const p={profile:t,amount:e,relays:a,comment:r||""},i=N.makeZapRequest(p);return o&&(i.tags.push(["k","web"]),i.tags.push(["i",k(o)])),(!R()||c)&&i.tags.push(["anon"]),S(i)},D=async({zapEndpoint:t,amount:n,comment:e,authorId:a,nip19Target:r,normalizedRelays:c,anon:o,url:p})=>{const i=await Z({profile:a,nip19Target:r,amount:n,relays:c,comment:e??"",anon:o,url:p});let d=`${t}?amount=${n}&nostr=${encodeURIComponent(JSON.stringify(i))}`;e&&(d+=`&comment=${encodeURIComponent(e??"")}`);const l=await fetch(d,{method:"GET"});if(!l.ok)throw new Error(`LNURL request failed: ${l.status} ${l.statusText}`);let u;try{u=await l.json()}catch{throw new Error("Invalid JSON from LNURL endpoint")}const{pr:h,reason:v,status:g}=u||{};if(h)return h;throw g==="ERROR"?new Error(v??"Unable to fetch invoice"):new Error("Unable to fetch invoice")},C=()=>{const t=new Uint8Array(32);if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function")crypto.getRandomValues(t);else{console.warn("crypto.getRandomValues not available, using Math.random as fallback");for(let n=0;n<32;n++)t[n]=Math.floor(Math.random()*256)}return t},R=()=>typeof window<"u"&&!!window.nostr,J=async({pubkey:t,relays:n,url:e})=>{var p,i,d,l;const a=e?k(e):void 0,r=new E;let c=0;const o=[];try{const u={kinds:[9735],"#p":[t],limit:1e3},h=await r.querySync(n,u);for(const v of h){const g=(p=v.tags)==null?void 0:p.find(s=>s[0]==="description");if(g!=null&&g[1])try{const s=JSON.parse(g[1]),w=(i=s==null?void 0:s.tags)==null?void 0:i.find(f=>f[0]==="amount");if(a){const f=(d=s==null?void 0:s.tags)==null?void 0:d.find(y=>y[0]==="k"),b=(l=s==null?void 0:s.tags)==null?void 0:l.find(y=>y[0]==="i"),U=b!=null&&b[1]?k(b[1]):"";if((f==null?void 0:f[1])==="web"&&U===a&&(w!=null&&w[1])){const y=parseInt(w[1],10);y>0&&(c+=y,o.push({amount:y/1e3,date:new Date(v.created_at*1e3),authorPubkey:s.pubkey,comment:s.content}))}}else if(w!=null&&w[1]){const f=parseInt(w[1],10);f>0&&(c+=f,o.push({amount:f/1e3,date:new Date(v.created_at*1e3),authorPubkey:s.pubkey,comment:s.content}))}}catch(s){console.error("Nostr-Components: Zap button: Could not parse zap request from description tag",s)}}}catch(u){console.error("Nostr-Components: Zap button: Error fetching zap receipts",u)}finally{r.close(n)}return o.sort((u,h)=>h.date.getTime()-u.date.getTime()),{totalAmount:c/1e3,zapDetails:o}},M=({relays:t,receiversPubKey:n,invoice:e,onSuccess:a})=>{const r=new E,c=Array.from(new Set([...t,"wss://relay.nostr.band"])),o=Math.floor((Date.now()-24*60*60*1e3)/1e3);r.subscribe(c,{kinds:[9735],"#p":[n],since:o},{onevent(i){i.tags.some(l=>l[0]==="bolt11"&&l[1]===e)&&(a(),p())}});const p=()=>{r.close(c)};return p};export{x as extractProfileMetadataContent,D as fetchInvoice,J as fetchTotalZapAmount,O as getBatchedProfileMetadata,$ as getProfileMetadata,z as getZapEndpoint,R as isNip07ExtAvailable,M as listenForZapReceipt};
2
- //# sourceMappingURL=zap-utils-B1sz0Abx.js.map
1
+ import{S as E,h as N,i as P}from"./nostr-service-CnaPxjc6.js";import{n as k}from"./utils--bxLbhGF.js";const m={},$=async t=>{if(m[t])return m[t];const n=new E,e=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{const a=await n.get(e,{authors:[t],kinds:[0]});return m[t]=a,a}finally{n.close(e)}},O=async t=>{const n=t.filter(r=>!m[r]);if(n.length===0)return t.map(r=>({id:r,profile:m[r]}));const e=new E,a=["wss://relay.nostr.band","wss://purplepag.es","wss://relay.damus.io","wss://nostr.wine"];try{return(await e.querySync(a,{authors:n,kinds:[0]})).forEach(o=>{m[o.pubkey]=o}),t.map(o=>({id:o,profile:m[o]||null}))}finally{e.close(a)}},x=t=>{try{return JSON.parse((t==null?void 0:t.content)||"{}")}catch{return{}}},z=async t=>{const n=await N.getZapEndpoint(t);if(!n)throw new Error("Failed to retrieve zap LNURL");return n},S=async(t,n)=>{if(R())try{const e=window.nostr;if(e!=null&&e.signEvent)return await e.signEvent(t)}catch{}return P(t,C())},Z=async({profile:t,nip19Target:n,amount:e,relays:a,comment:r,anon:c,url:o})=>{const p={profile:t,amount:e,relays:a,comment:r||""},i=N.makeZapRequest(p);return o&&(i.tags.push(["k","web"]),i.tags.push(["i",k(o)])),(!R()||c)&&i.tags.push(["anon"]),S(i)},D=async({zapEndpoint:t,amount:n,comment:e,authorId:a,nip19Target:r,normalizedRelays:c,anon:o,url:p})=>{const i=await Z({profile:a,nip19Target:r,amount:n,relays:c,comment:e??"",anon:o,url:p});let d=`${t}?amount=${n}&nostr=${encodeURIComponent(JSON.stringify(i))}`;e&&(d+=`&comment=${encodeURIComponent(e??"")}`);const l=await fetch(d,{method:"GET"});if(!l.ok)throw new Error(`LNURL request failed: ${l.status} ${l.statusText}`);let u;try{u=await l.json()}catch{throw new Error("Invalid JSON from LNURL endpoint")}const{pr:h,reason:v,status:g}=u||{};if(h)return h;throw g==="ERROR"?new Error(v??"Unable to fetch invoice"):new Error("Unable to fetch invoice")},C=()=>{const t=new Uint8Array(32);if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function")crypto.getRandomValues(t);else{console.warn("crypto.getRandomValues not available, using Math.random as fallback");for(let n=0;n<32;n++)t[n]=Math.floor(Math.random()*256)}return t},R=()=>typeof window<"u"&&!!window.nostr,J=async({pubkey:t,relays:n,url:e})=>{var p,i,d,l;const a=e?k(e):void 0,r=new E;let c=0;const o=[];try{const u={kinds:[9735],"#p":[t],limit:1e3},h=await r.querySync(n,u);for(const v of h){const g=(p=v.tags)==null?void 0:p.find(s=>s[0]==="description");if(g!=null&&g[1])try{const s=JSON.parse(g[1]),w=(i=s==null?void 0:s.tags)==null?void 0:i.find(f=>f[0]==="amount");if(a){const f=(d=s==null?void 0:s.tags)==null?void 0:d.find(y=>y[0]==="k"),b=(l=s==null?void 0:s.tags)==null?void 0:l.find(y=>y[0]==="i"),U=b!=null&&b[1]?k(b[1]):"";if((f==null?void 0:f[1])==="web"&&U===a&&(w!=null&&w[1])){const y=parseInt(w[1],10);y>0&&(c+=y,o.push({amount:y/1e3,date:new Date(v.created_at*1e3),authorPubkey:s.pubkey,comment:s.content}))}}else if(w!=null&&w[1]){const f=parseInt(w[1],10);f>0&&(c+=f,o.push({amount:f/1e3,date:new Date(v.created_at*1e3),authorPubkey:s.pubkey,comment:s.content}))}}catch(s){console.error("Nostr-Components: Zap button: Could not parse zap request from description tag",s)}}}catch(u){console.error("Nostr-Components: Zap button: Error fetching zap receipts",u)}finally{r.close(n)}return o.sort((u,h)=>h.date.getTime()-u.date.getTime()),{totalAmount:c/1e3,zapDetails:o}},M=({relays:t,receiversPubKey:n,invoice:e,onSuccess:a})=>{const r=new E,c=Array.from(new Set([...t,"wss://relay.nostr.band"])),o=Math.floor((Date.now()-24*60*60*1e3)/1e3);r.subscribe(c,{kinds:[9735],"#p":[n],since:o},{onevent(i){i.tags.some(l=>l[0]==="bolt11"&&l[1]===e)&&(a(),p())}});const p=()=>{r.close(c)};return p};export{x as extractProfileMetadataContent,D as fetchInvoice,J as fetchTotalZapAmount,O as getBatchedProfileMetadata,$ as getProfileMetadata,z as getZapEndpoint,R as isNip07ExtAvailable,M as listenForZapReceipt};
2
+ //# sourceMappingURL=zap-utils-KFUD_vTU.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zap-utils-B1sz0Abx.js","sources":["../../src/nostr-zap/zap-utils.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport {\n nip57,\n nip05,\n finalizeEvent,\n SimplePool,\n} from 'nostr-tools';\nimport { decodeNip19Entity } from '../common/utils';\n\n/**\n * Helper utilities for Nostr zap operations (adapted from the original `nostr-zap` repo).\n * These are deliberately kept self-contained so `nostr-zap` Web Component can import\n * everything from a single module without polluting the rest of the codebase.\n */\n\n// Basic in-memory cache – sufficient for component lifetime.\nconst profileCache: Record<string, any> = {};\n\nexport const getProfileMetadata = async (authorId: string) => {\n if (profileCache[authorId]) return profileCache[authorId];\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n const event = await pool.get(relays, {\n authors: [authorId],\n kinds: [0],\n });\n profileCache[authorId] = event;\n return event;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const getBatchedProfileMetadata = async (authorIds: string[]) => {\n // Filter out already cached profiles\n const uncachedIds = authorIds.filter(id => !profileCache[id]);\n\n // If all profiles are cached, return them\n if (uncachedIds.length === 0) {\n return authorIds.map(id => ({ id, profile: profileCache[id] }));\n }\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n // Fetch all uncached profiles in a single query\n const events = await pool.querySync(relays, {\n authors: uncachedIds,\n kinds: [0],\n });\n\n // Cache the fetched profiles\n events.forEach(event => {\n profileCache[event.pubkey] = event;\n });\n\n // Combine cached and newly fetched profiles\n const allProfiles = authorIds.map(id => ({\n id,\n profile: profileCache[id] || null\n }));\n\n return allProfiles;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const extractProfileMetadataContent = (profileMetadata: any) => {\n try {\n return JSON.parse(profileMetadata?.content || '{}');\n } catch {\n return {};\n }\n};\n\nexport const getZapEndpoint = async (profileMetadata: any) => {\n const endpoint = await nip57.getZapEndpoint(profileMetadata);\n if (!endpoint) throw new Error('Failed to retrieve zap LNURL');\n return endpoint;\n};\n\ninterface NostrExtension {\n signEvent(event: any): Promise<{\n id: string;\n sig: string;\n kind: number;\n tags: string[][];\n pubkey: string;\n content: string;\n created_at: number;\n }>;\n}\n\nconst signEvent = async (zapEvent: any, anon?: boolean) => {\n if (isNip07ExtAvailable() && !anon) {\n try {\n const ext = (window as { nostr?: NostrExtension }).nostr;\n if (ext?.signEvent) return await ext.signEvent(zapEvent);\n } catch {\n /* fall-through -> anonymous */\n }\n }\n return finalizeEvent(zapEvent, generateRandomPrivKey());\n};\n\nconst makeZapEvent = async ({\n profile,\n nip19Target,\n amount,\n relays,\n comment,\n anon,\n url,\n}: {\n profile: string;\n nip19Target?: string;\n amount: number;\n relays: string[];\n comment?: string;\n anon?: boolean;\n url?: string;\n}) => {\n const req: any = {\n profile,\n amount,\n relays,\n comment: comment || '',\n };\n if (nip19Target?.startsWith('note')) {\n req.event = decodeNip19Entity(nip19Target);\n }\n const event = nip57.makeZapRequest(req);\n\n if (nip19Target?.startsWith('naddr')) {\n const naddrData: any = decodeNip19Entity(nip19Target);\n const relayTag = naddrData?.relays?.join(',') ?? '';\n event.tags.push(['a', `${naddrData.kind}:${naddrData.pubkey}:${naddrData.identifier}`, relayTag]);\n }\n\n // Add URL-based zap tags if URL is provided\n if (url) {\n event.tags.push(['k', 'web']);\n event.tags.push(['i', normalizeURL(url)]);\n }\n\n if (!isNip07ExtAvailable() || anon) {\n event.tags.push(['anon']);\n }\n\n return signEvent(event, anon);\n};\n\nexport const fetchInvoice = async ({\n zapEndpoint,\n amount,\n comment,\n authorId,\n nip19Target,\n normalizedRelays,\n anon,\n url,\n}: {\n zapEndpoint: string;\n amount: number;\n comment?: string;\n authorId: string;\n nip19Target?: string;\n normalizedRelays: string[];\n anon?: boolean;\n url?: string;\n}): Promise<string> => {\n const zapEvent = await makeZapEvent({\n profile: authorId,\n nip19Target,\n amount,\n relays: normalizedRelays,\n comment: comment ?? '',\n anon,\n url,\n });\n\n\n let invoiceUrl = `${zapEndpoint}?amount=${amount}&nostr=${encodeURIComponent(\n JSON.stringify(zapEvent)\n )}`;\n if (comment) invoiceUrl += `&comment=${encodeURIComponent(comment ?? '')}`;\n\n const res = await fetch(invoiceUrl, { method: 'GET' });\n if (!res.ok) {\n throw new Error(`LNURL request failed: ${res.status} ${res.statusText}`);\n }\n let json: any;\n try {\n json = await res.json();\n } catch {\n throw new Error('Invalid JSON from LNURL endpoint');\n }\n const { pr: invoice, reason, status } = json || {};\n if (invoice) return invoice;\n if (status === 'ERROR') throw new Error(reason ?? 'Unable to fetch invoice');\n throw new Error('Unable to fetch invoice');\n};\n\nconst generateRandomPrivKey = (): Uint8Array => {\n const bytes = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback during build – use Math.random (not cryptographically strong but acceptable for anon zaps)\n console.warn('crypto.getRandomValues not available, using Math.random as fallback');\n for (let i = 0; i < 32; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return bytes;\n};\n\nexport const isNip07ExtAvailable = (): boolean => typeof window !== 'undefined' && !!(window as any).nostr;\n\n// ---------------------------------------------------------------------------\n// nip05 resolution helper – very lightweight fetch to /.well-known/nostr.json\n// ---------------------------------------------------------------------------\n\n\n\nexport async function resolveNip05(nip05Identifier: string): Promise<string | null> {\n try {\n const profile = await nip05.queryProfile(nip05Identifier);\n return profile?.pubkey || null;\n } catch (error) {\n console.error(`Failed to resolve NIP-05 ${nip05Identifier}:`, error);\n return null;\n }\n}\n\n// Import necessary types from nostr-tools\nimport type { Filter, Event } from 'nostr-tools';\nimport { normalizeURL } from '../nostr-comment/utils';\n\n// Augment the SimplePool type to include our usage\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ndeclare module 'nostr-tools' {\n interface SimplePool {\n subscribe(\n relays: string[],\n filter: Filter,\n params: {\n onevent: (event: Event) => void;\n onclose?: () => void;\n id?: string;\n maxWait?: number;\n }\n ): {\n close: () => void;\n };\n }\n}\n\nexport interface ZapDetails {\n amount: number;\n date: Date;\n authorPubkey: string;\n comment?: string;\n}\n\nexport interface ZapAmountResult {\n totalAmount: number;\n zapDetails: ZapDetails[];\n}\n\nexport const fetchTotalZapAmount = async ({\n pubkey,\n relays,\n url,\n}: {\n pubkey: string;\n relays: string[];\n url?: string;\n}): Promise<ZapAmountResult> => {\n // Normalize URL at the beginning for consistent comparison with tags\n const normalizedUrl = url ? normalizeURL(url) : undefined;\n \n const pool = new SimplePool();\n let totalAmount = 0;\n const zapDetails: ZapDetails[] = [];\n\n try {\n // Build filter for zap receipt events\n const filter: any = {\n kinds: [9735], // Zap receipt\n '#p': [pubkey],\n limit: 1000,\n };\n\n // Add URL-based filtering if URL is provided\n // TODO: These tags doesn't appear in zap receipt event.\n // They goes into the description tag, which has the zap request JSON.\n /*\n if (normalizedUrl) {\n filter['#k'] = ['web'];\n filter['#i'] = [normalizedUrl];\n }\n */\n\n // Use pool.querySync to fetch multiple zap receipt events\n const events = await pool.querySync(relays, filter);\n\n for (const event of events) {\n const descriptionTag = event.tags?.find((tag: string[]) => tag[0] === 'description');\n if (descriptionTag?.[1]) {\n try {\n const zapRequest = JSON.parse(descriptionTag[1]);\n const amountTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'amount');\n \n // If URL is provided, check for URL-based zap tags\n // TODO: Too much work, since #k and #i tags doesn't appear in zap receipt event.\n // This is not a practical solution, but it's working for now!\n if (normalizedUrl) {\n const kTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'k');\n const iTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'i');\n \n const iTagNormalized = iTag?.[1] ? normalizeURL(iTag[1]) : '';\n if (kTag?.[1] === 'web' && iTagNormalized === normalizedUrl && amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n } else {\n // No URL filtering - count all zaps\n if (amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n }\n } catch (e) {\n console.error(\"Nostr-Components: Zap button: Could not parse zap request from description tag\", e);\n }\n }\n }\n } catch (error) {\n console.error(\"Nostr-Components: Zap button: Error fetching zap receipts\", error);\n } finally {\n pool.close(relays);\n }\n\n // Sort zap details by date (newest first)\n zapDetails.sort((a, b) => b.date.getTime() - a.date.getTime());\n\n return {\n totalAmount: totalAmount / 1000, // convert from msats to sats\n zapDetails,\n };\n};\n\nexport const listenForZapReceipt = ({\n relays,\n receiversPubKey,\n invoice,\n onSuccess,\n}: {\n relays: string[];\n receiversPubKey: string,\n invoice: string;\n onSuccess: () => void;\n}) => {\n const pool = new SimplePool();\n const normalizedRelays = Array.from(new Set([...relays, 'wss://relay.nostr.band']));\n const since = Math.floor((Date.now() - 24 * 60 * 60 * 1000) / 1000); // current time - 24 hours\n\n pool.subscribe(\n normalizedRelays,\n {\n kinds: [9735],\n '#p': [receiversPubKey],\n since,\n },\n {\n onevent(event: Event) {\n const tags = event.tags as [string, string][];\n if (tags.some(t => t[0] === 'bolt11' && t[1] === invoice)) {\n onSuccess();\n cleanup();\n }\n }\n }\n );\n\n const cleanup = () => {\n pool.close(normalizedRelays);\n };\n\n return cleanup;\n};\n"],"names":["profileCache","getProfileMetadata","authorId","pool","SimplePool","relays","event","getBatchedProfileMetadata","authorIds","uncachedIds","id","extractProfileMetadataContent","profileMetadata","getZapEndpoint","endpoint","nip57","signEvent","zapEvent","anon","isNip07ExtAvailable","ext","finalizeEvent","generateRandomPrivKey","makeZapEvent","profile","nip19Target","amount","comment","url","req","normalizeURL","fetchInvoice","zapEndpoint","normalizedRelays","invoiceUrl","res","json","invoice","reason","status","bytes","i","fetchTotalZapAmount","pubkey","normalizedUrl","totalAmount","zapDetails","filter","events","descriptionTag","_a","tag","zapRequest","amountTag","_b","kTag","_c","iTag","_d","iTagNormalized","e","error","a","b","listenForZapReceipt","receiversPubKey","onSuccess","since","t","cleanup"],"mappings":"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"}
1
+ {"version":3,"file":"zap-utils-KFUD_vTU.js","sources":["../../src/nostr-zap/zap-utils.ts"],"sourcesContent":["// SPDX-License-Identifier: MIT\n\nimport {\n nip57,\n nip05,\n finalizeEvent,\n SimplePool,\n} from 'nostr-tools';\nimport { decodeNip19Entity } from '../common/utils';\n\n/**\n * Helper utilities for Nostr zap operations (adapted from the original `nostr-zap` repo).\n * These are deliberately kept self-contained so `nostr-zap` Web Component can import\n * everything from a single module without polluting the rest of the codebase.\n */\n\n// Basic in-memory cache – sufficient for component lifetime.\nconst profileCache: Record<string, any> = {};\n\nexport const getProfileMetadata = async (authorId: string) => {\n if (profileCache[authorId]) return profileCache[authorId];\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n const event = await pool.get(relays, {\n authors: [authorId],\n kinds: [0],\n });\n profileCache[authorId] = event;\n return event;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const getBatchedProfileMetadata = async (authorIds: string[]) => {\n // Filter out already cached profiles\n const uncachedIds = authorIds.filter(id => !profileCache[id]);\n\n // If all profiles are cached, return them\n if (uncachedIds.length === 0) {\n return authorIds.map(id => ({ id, profile: profileCache[id] }));\n }\n\n const pool = new SimplePool();\n const relays = [\n 'wss://relay.nostr.band',\n 'wss://purplepag.es',\n 'wss://relay.damus.io',\n 'wss://nostr.wine',\n ];\n\n try {\n // Fetch all uncached profiles in a single query\n const events = await pool.querySync(relays, {\n authors: uncachedIds,\n kinds: [0],\n });\n\n // Cache the fetched profiles\n events.forEach(event => {\n profileCache[event.pubkey] = event;\n });\n\n // Combine cached and newly fetched profiles\n const allProfiles = authorIds.map(id => ({\n id,\n profile: profileCache[id] || null\n }));\n\n return allProfiles;\n } finally {\n pool.close(relays);\n }\n};\n\nexport const extractProfileMetadataContent = (profileMetadata: any) => {\n try {\n return JSON.parse(profileMetadata?.content || '{}');\n } catch {\n return {};\n }\n};\n\nexport const getZapEndpoint = async (profileMetadata: any) => {\n const endpoint = await nip57.getZapEndpoint(profileMetadata);\n if (!endpoint) throw new Error('Failed to retrieve zap LNURL');\n return endpoint;\n};\n\ninterface NostrExtension {\n signEvent(event: any): Promise<{\n id: string;\n sig: string;\n kind: number;\n tags: string[][];\n pubkey: string;\n content: string;\n created_at: number;\n }>;\n}\n\nconst signEvent = async (zapEvent: any, anon?: boolean) => {\n if (isNip07ExtAvailable() && !anon) {\n try {\n const ext = (window as { nostr?: NostrExtension }).nostr;\n if (ext?.signEvent) return await ext.signEvent(zapEvent);\n } catch {\n /* fall-through -> anonymous */\n }\n }\n return finalizeEvent(zapEvent, generateRandomPrivKey());\n};\n\nconst makeZapEvent = async ({\n profile,\n nip19Target,\n amount,\n relays,\n comment,\n anon,\n url,\n}: {\n profile: string;\n nip19Target?: string;\n amount: number;\n relays: string[];\n comment?: string;\n anon?: boolean;\n url?: string;\n}) => {\n const req: any = {\n profile,\n amount,\n relays,\n comment: comment || '',\n };\n if (nip19Target?.startsWith('note')) {\n req.event = decodeNip19Entity(nip19Target);\n }\n const event = nip57.makeZapRequest(req);\n\n if (nip19Target?.startsWith('naddr')) {\n const naddrData: any = decodeNip19Entity(nip19Target);\n const relayTag = naddrData?.relays?.join(',') ?? '';\n event.tags.push(['a', `${naddrData.kind}:${naddrData.pubkey}:${naddrData.identifier}`, relayTag]);\n }\n\n // Add URL-based zap tags if URL is provided\n if (url) {\n event.tags.push(['k', 'web']);\n event.tags.push(['i', normalizeURL(url)]);\n }\n\n if (!isNip07ExtAvailable() || anon) {\n event.tags.push(['anon']);\n }\n\n return signEvent(event, anon);\n};\n\nexport const fetchInvoice = async ({\n zapEndpoint,\n amount,\n comment,\n authorId,\n nip19Target,\n normalizedRelays,\n anon,\n url,\n}: {\n zapEndpoint: string;\n amount: number;\n comment?: string;\n authorId: string;\n nip19Target?: string;\n normalizedRelays: string[];\n anon?: boolean;\n url?: string;\n}): Promise<string> => {\n const zapEvent = await makeZapEvent({\n profile: authorId,\n nip19Target,\n amount,\n relays: normalizedRelays,\n comment: comment ?? '',\n anon,\n url,\n });\n\n\n let invoiceUrl = `${zapEndpoint}?amount=${amount}&nostr=${encodeURIComponent(\n JSON.stringify(zapEvent)\n )}`;\n if (comment) invoiceUrl += `&comment=${encodeURIComponent(comment ?? '')}`;\n\n const res = await fetch(invoiceUrl, { method: 'GET' });\n if (!res.ok) {\n throw new Error(`LNURL request failed: ${res.status} ${res.statusText}`);\n }\n let json: any;\n try {\n json = await res.json();\n } catch {\n throw new Error('Invalid JSON from LNURL endpoint');\n }\n const { pr: invoice, reason, status } = json || {};\n if (invoice) return invoice;\n if (status === 'ERROR') throw new Error(reason ?? 'Unable to fetch invoice');\n throw new Error('Unable to fetch invoice');\n};\n\nconst generateRandomPrivKey = (): Uint8Array => {\n const bytes = new Uint8Array(32);\n if (typeof crypto !== 'undefined' && typeof crypto.getRandomValues === 'function') {\n crypto.getRandomValues(bytes);\n } else {\n // Node.js fallback during build – use Math.random (not cryptographically strong but acceptable for anon zaps)\n console.warn('crypto.getRandomValues not available, using Math.random as fallback');\n for (let i = 0; i < 32; i++) bytes[i] = Math.floor(Math.random() * 256);\n }\n return bytes;\n};\n\nexport const isNip07ExtAvailable = (): boolean => typeof window !== 'undefined' && !!(window as any).nostr;\n\n// ---------------------------------------------------------------------------\n// nip05 resolution helper – very lightweight fetch to /.well-known/nostr.json\n// ---------------------------------------------------------------------------\n\n\n\nexport async function resolveNip05(nip05Identifier: string): Promise<string | null> {\n try {\n const profile = await nip05.queryProfile(nip05Identifier);\n return profile?.pubkey || null;\n } catch (error) {\n console.error(`Failed to resolve NIP-05 ${nip05Identifier}:`, error);\n return null;\n }\n}\n\n// Import necessary types from nostr-tools\nimport type { Filter, Event } from 'nostr-tools';\nimport { normalizeURL } from '../nostr-comment/utils';\n\n// Augment the SimplePool type to include our usage\n// eslint-disable-next-line @typescript-eslint/consistent-type-definitions\ndeclare module 'nostr-tools' {\n interface SimplePool {\n subscribe(\n relays: string[],\n filter: Filter,\n params: {\n onevent: (event: Event) => void;\n onclose?: () => void;\n id?: string;\n maxWait?: number;\n }\n ): {\n close: () => void;\n };\n }\n}\n\nexport interface ZapDetails {\n amount: number;\n date: Date;\n authorPubkey: string;\n comment?: string;\n}\n\nexport interface ZapAmountResult {\n totalAmount: number;\n zapDetails: ZapDetails[];\n}\n\nexport const fetchTotalZapAmount = async ({\n pubkey,\n relays,\n url,\n}: {\n pubkey: string;\n relays: string[];\n url?: string;\n}): Promise<ZapAmountResult> => {\n // Normalize URL at the beginning for consistent comparison with tags\n const normalizedUrl = url ? normalizeURL(url) : undefined;\n \n const pool = new SimplePool();\n let totalAmount = 0;\n const zapDetails: ZapDetails[] = [];\n\n try {\n // Build filter for zap receipt events\n const filter: any = {\n kinds: [9735], // Zap receipt\n '#p': [pubkey],\n limit: 1000,\n };\n\n // Add URL-based filtering if URL is provided\n // TODO: These tags doesn't appear in zap receipt event.\n // They goes into the description tag, which has the zap request JSON.\n /*\n if (normalizedUrl) {\n filter['#k'] = ['web'];\n filter['#i'] = [normalizedUrl];\n }\n */\n\n // Use pool.querySync to fetch multiple zap receipt events\n const events = await pool.querySync(relays, filter);\n\n for (const event of events) {\n const descriptionTag = event.tags?.find((tag: string[]) => tag[0] === 'description');\n if (descriptionTag?.[1]) {\n try {\n const zapRequest = JSON.parse(descriptionTag[1]);\n const amountTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'amount');\n \n // If URL is provided, check for URL-based zap tags\n // TODO: Too much work, since #k and #i tags doesn't appear in zap receipt event.\n // This is not a practical solution, but it's working for now!\n if (normalizedUrl) {\n const kTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'k');\n const iTag = zapRequest?.tags?.find((tag: string[]) => tag[0] === 'i');\n \n const iTagNormalized = iTag?.[1] ? normalizeURL(iTag[1]) : '';\n if (kTag?.[1] === 'web' && iTagNormalized === normalizedUrl && amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n } else {\n // No URL filtering - count all zaps\n if (amountTag?.[1]) {\n const amount = parseInt(amountTag[1], 10);\n if (amount > 0) {\n totalAmount += amount;\n zapDetails.push({\n amount: amount / 1000, // convert from msats to sats\n date: new Date(event.created_at * 1000),\n authorPubkey: zapRequest.pubkey,\n comment: zapRequest.content,\n });\n }\n }\n }\n } catch (e) {\n console.error(\"Nostr-Components: Zap button: Could not parse zap request from description tag\", e);\n }\n }\n }\n } catch (error) {\n console.error(\"Nostr-Components: Zap button: Error fetching zap receipts\", error);\n } finally {\n pool.close(relays);\n }\n\n // Sort zap details by date (newest first)\n zapDetails.sort((a, b) => b.date.getTime() - a.date.getTime());\n\n return {\n totalAmount: totalAmount / 1000, // convert from msats to sats\n zapDetails,\n };\n};\n\nexport const listenForZapReceipt = ({\n relays,\n receiversPubKey,\n invoice,\n onSuccess,\n}: {\n relays: string[];\n receiversPubKey: string,\n invoice: string;\n onSuccess: () => void;\n}) => {\n const pool = new SimplePool();\n const normalizedRelays = Array.from(new Set([...relays, 'wss://relay.nostr.band']));\n const since = Math.floor((Date.now() - 24 * 60 * 60 * 1000) / 1000); // current time - 24 hours\n\n pool.subscribe(\n normalizedRelays,\n {\n kinds: [9735],\n '#p': [receiversPubKey],\n since,\n },\n {\n onevent(event: Event) {\n const tags = event.tags as [string, string][];\n if (tags.some(t => t[0] === 'bolt11' && t[1] === invoice)) {\n onSuccess();\n cleanup();\n }\n }\n }\n );\n\n const cleanup = () => {\n pool.close(normalizedRelays);\n };\n\n return cleanup;\n};\n"],"names":["profileCache","getProfileMetadata","authorId","pool","SimplePool","relays","event","getBatchedProfileMetadata","authorIds","uncachedIds","id","extractProfileMetadataContent","profileMetadata","getZapEndpoint","endpoint","nip57","signEvent","zapEvent","anon","isNip07ExtAvailable","ext","finalizeEvent","generateRandomPrivKey","makeZapEvent","profile","nip19Target","amount","comment","url","req","normalizeURL","fetchInvoice","zapEndpoint","normalizedRelays","invoiceUrl","res","json","invoice","reason","status","bytes","i","fetchTotalZapAmount","pubkey","normalizedUrl","totalAmount","zapDetails","filter","events","descriptionTag","_a","tag","zapRequest","amountTag","_b","kTag","_c","iTag","_d","iTagNormalized","e","error","a","b","listenForZapReceipt","receiversPubKey","onSuccess","since","t","cleanup"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/pure-jrVhRVpB.js","assets/nostr-service-pr_crY62.js"])))=>i.map(i=>d[i]);
2
- var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[r]=t;var f=(o,r,t)=>Zt(o,typeof r!="symbol"?r+"":r,t);import{_ as xe}from"../assets/preload-helper-D7HrI6pR.js";import{N as Qt,D as Jt,e as en}from"../assets/nostr-service-pr_crY62.js";import{n as gt}from"../assets/utils--bxLbhGF.js";function B(o){return o.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function tn(o){const t=Date.now()/1e3-o;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:t<2592e3?`${Math.floor(t/86400)}d ago`:new Date(o*1e3).toLocaleDateString()}function kt(o){var r,t;return(r=o.userProfile)!=null&&r.displayName?o.userProfile.displayName:(t=o.userProfile)!=null&&t.name?o.userProfile.name:`${o.pubkey.slice(0,8)}...${o.pubkey.slice(-4)}`}function nn(o){var r,t;if((r=o.userProfile)!=null&&r.image&&o.userProfile.image.trim()!==""){let n=o.userProfile.image.trim();return console.log("Processing image URL:",n,"for user:",o.userProfile.name||o.pubkey),(n.startsWith("Qm")||n.startsWith("bafy"))&&(n=`https://ipfs.io/ipfs/${n}`,console.log("Converted IPFS to gateway URL:",n)),n.startsWith("//")&&(n="https:"+n,console.log("Added protocol to URL:",n)),console.log("Final image URL:",n),n}return console.log("No image found for user:",((t=o.userProfile)==null?void 0:t.name)||o.pubkey,"using default"),"../../assets/default_dp.png"}function St(o,r=!1,t=null,n=null,a="anon",s=!1){const c=kt(o),h=nn(o),g=tn(o.created_at),y=o.depth||0,d=6,E=t===o.id;return`
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/pure-DPo-pzxM.js","assets/nostr-service-CnaPxjc6.js"])))=>i.map(i=>d[i]);
2
+ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):o[r]=t;var f=(o,r,t)=>Zt(o,typeof r!="symbol"?r+"":r,t);import{_ as xe}from"../assets/preload-helper-D7HrI6pR.js";import{b as Qt,c as Jt,d as en}from"../assets/nostr-service-CnaPxjc6.js";import{n as gt}from"../assets/utils--bxLbhGF.js";function B(o){return o.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}function tn(o){const t=Date.now()/1e3-o;return t<60?"just now":t<3600?`${Math.floor(t/60)}m ago`:t<86400?`${Math.floor(t/3600)}h ago`:t<2592e3?`${Math.floor(t/86400)}d ago`:new Date(o*1e3).toLocaleDateString()}function kt(o){var r,t;return(r=o.userProfile)!=null&&r.displayName?o.userProfile.displayName:(t=o.userProfile)!=null&&t.name?o.userProfile.name:`${o.pubkey.slice(0,8)}...${o.pubkey.slice(-4)}`}function nn(o){var r,t;if((r=o.userProfile)!=null&&r.image&&o.userProfile.image.trim()!==""){let n=o.userProfile.image.trim();return console.log("Processing image URL:",n,"for user:",o.userProfile.name||o.pubkey),(n.startsWith("Qm")||n.startsWith("bafy"))&&(n=`https://ipfs.io/ipfs/${n}`,console.log("Converted IPFS to gateway URL:",n)),n.startsWith("//")&&(n="https:"+n,console.log("Added protocol to URL:",n)),console.log("Final image URL:",n),n}return console.log("No image found for user:",((t=o.userProfile)==null?void 0:t.name)||o.pubkey,"using default"),"../../assets/default_dp.png"}function St(o,r=!1,t=null,n=null,a="anon",s=!1){const c=kt(o),h=nn(o),g=tn(o.created_at),y=o.depth||0,d=6,E=t===o.id;return`
3
3
  <div class="modern-comment" data-comment-id="${B(o.id)}" data-depth="${y}">
4
4
  <div class="comment-content-wrapper">
5
5
  <div class="comment-avatar-section">
@@ -901,7 +901,7 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
901
901
  }
902
902
  </style>
903
903
  `}/*! @license DOMPurify 3.2.6 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.2.6/LICENSE */const{entries:Lt,setPrototypeOf:bt,isFrozen:cn,getPrototypeOf:mn,getOwnPropertyDescriptor:dn}=Object;let{freeze:I,seal:M,create:Pt}=Object,{apply:We,construct:Ge}=typeof Reflect<"u"&&Reflect;I||(I=function(r){return r});M||(M=function(r){return r});We||(We=function(r,t,n){return r.apply(t,n)});Ge||(Ge=function(r,t){return new r(...t)});const ve=C(Array.prototype.forEach),pn=C(Array.prototype.lastIndexOf),yt=C(Array.prototype.pop),se=C(Array.prototype.push),un=C(Array.prototype.splice),Ee=C(String.prototype.toLowerCase),ze=C(String.prototype.toString),xt=C(String.prototype.match),le=C(String.prototype.replace),fn=C(String.prototype.indexOf),hn=C(String.prototype.trim),z=C(Object.prototype.hasOwnProperty),N=C(RegExp.prototype.test),ce=gn(TypeError);function C(o){return function(r){r instanceof RegExp&&(r.lastIndex=0);for(var t=arguments.length,n=new Array(t>1?t-1:0),a=1;a<t;a++)n[a-1]=arguments[a];return We(o,r,n)}}function gn(o){return function(){for(var r=arguments.length,t=new Array(r),n=0;n<r;n++)t[n]=arguments[n];return Ge(o,t)}}function u(o,r){let t=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Ee;bt&&bt(o,null);let n=r.length;for(;n--;){let a=r[n];if(typeof a=="string"){const s=t(a);s!==a&&(cn(r)||(r[n]=s),a=s)}o[a]=!0}return o}function bn(o){for(let r=0;r<o.length;r++)z(o,r)||(o[r]=null);return o}function G(o){const r=Pt(null);for(const[t,n]of Lt(o))z(o,t)&&(Array.isArray(n)?r[t]=bn(n):n&&typeof n=="object"&&n.constructor===Object?r[t]=G(n):r[t]=n);return r}function me(o,r){for(;o!==null;){const n=dn(o,r);if(n){if(n.get)return C(n.get);if(typeof n.value=="function")return C(n.value)}o=mn(o)}function t(){return null}return t}const vt=I(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),Fe=I(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),$e=I(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),yn=I(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),He=I(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),xn=I(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),Tt=I(["#text"]),Et=I(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns","slot"]),Ke=I(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),At=I(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),Te=I(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),vn=M(/\{\{[\w\W]*|[\w\W]*\}\}/gm),Tn=M(/<%[\w\W]*|[\w\W]*%>/gm),En=M(/\$\{[\w\W]*/gm),An=M(/^data-[\-\w.\u00B7-\uFFFF]+$/),wn=M(/^aria-[\-\w]+$/),Nt=M(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),_n=M(/^(?:\w+script|data):/i),kn=M(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),It=M(/^html$/i),Sn=M(/^[a-z][.\w]*(-[.\w]+)+$/i);var wt=Object.freeze({__proto__:null,ARIA_ATTR:wn,ATTR_WHITESPACE:kn,CUSTOM_ELEMENT:Sn,DATA_ATTR:An,DOCTYPE_NAME:It,ERB_EXPR:Tn,IS_ALLOWED_URI:Nt,IS_SCRIPT_OR_DATA:_n,MUSTACHE_EXPR:vn,TMPLIT_EXPR:En});const de={element:1,text:3,progressingInstruction:7,comment:8,document:9},Rn=function(){return typeof window>"u"?null:window},Ln=function(r,t){if(typeof r!="object"||typeof r.createPolicy!="function")return null;let n=null;const a="data-tt-policy-suffix";t&&t.hasAttribute(a)&&(n=t.getAttribute(a));const s="dompurify"+(n?"#"+n:"");try{return r.createPolicy(s,{createHTML(c){return c},createScriptURL(c){return c}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},_t=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}};function Ct(){let o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:Rn();const r=m=>Ct(m);if(r.version="3.2.6",r.removed=[],!o||!o.document||o.document.nodeType!==de.document||!o.Element)return r.isSupported=!1,r;let{document:t}=o;const n=t,a=n.currentScript,{DocumentFragment:s,HTMLTemplateElement:c,Node:h,Element:g,NodeFilter:y,NamedNodeMap:d=o.NamedNodeMap||o.MozNamedAttrMap,HTMLFormElement:E,DOMParser:D,trustedTypes:Y}=o,p=g.prototype,x=me(p,"cloneNode"),k=me(p,"remove"),te=me(p,"nextSibling"),U=me(p,"childNodes"),$=me(p,"parentNode");if(typeof c=="function"){const m=t.createElement("template");m.content&&m.content.ownerDocument&&(t=m.content.ownerDocument)}let L,ne="";const{implementation:Ae,createNodeIterator:Dt,createDocumentFragment:Ot,getElementsByTagName:Mt}=t,{importNode:Ut}=n;let P=_t();r.isSupported=typeof Lt=="function"&&typeof $=="function"&&Ae&&Ae.createHTMLDocument!==void 0;const{MUSTACHE_EXPR:we,ERB_EXPR:_e,TMPLIT_EXPR:ke,DATA_ATTR:zt,ARIA_ATTR:Ft,IS_SCRIPT_OR_DATA:$t,ATTR_WHITESPACE:Be,CUSTOM_ELEMENT:Ht}=wt;let{IS_ALLOWED_URI:Ye}=wt,A=null;const qe=u({},[...vt,...Fe,...$e,...He,...Tt]);let _=null;const Ve=u({},[...Et,...Ke,...At,...Te]);let v=Object.seal(Pt(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),oe=null,Se=null,je=!0,Re=!0,Xe=!1,Ze=!0,V=!1,pe=!0,q=!1,Le=!1,Pe=!1,j=!1,ue=!1,fe=!1,Qe=!0,Je=!1;const Kt="user-content-";let Ne=!0,re=!1,X={},Z=null;const et=u({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let tt=null;const nt=u({},["audio","video","img","source","image","track"]);let Ie=null;const ot=u({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),he="http://www.w3.org/1998/Math/MathML",ge="http://www.w3.org/2000/svg",H="http://www.w3.org/1999/xhtml";let Q=H,Ce=!1,De=null;const Wt=u({},[he,ge,H],ze);let be=u({},["mi","mo","mn","ms","mtext"]),ye=u({},["annotation-xml"]);const Gt=u({},["title","style","font","a","script"]);let ie=null;const Bt=["application/xhtml+xml","text/html"],Yt="text/html";let w=null,J=null;const qt=t.createElement("form"),rt=function(e){return e instanceof RegExp||e instanceof Function},Oe=function(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(!(J&&J===e)){if((!e||typeof e!="object")&&(e={}),e=G(e),ie=Bt.indexOf(e.PARSER_MEDIA_TYPE)===-1?Yt:e.PARSER_MEDIA_TYPE,w=ie==="application/xhtml+xml"?ze:Ee,A=z(e,"ALLOWED_TAGS")?u({},e.ALLOWED_TAGS,w):qe,_=z(e,"ALLOWED_ATTR")?u({},e.ALLOWED_ATTR,w):Ve,De=z(e,"ALLOWED_NAMESPACES")?u({},e.ALLOWED_NAMESPACES,ze):Wt,Ie=z(e,"ADD_URI_SAFE_ATTR")?u(G(ot),e.ADD_URI_SAFE_ATTR,w):ot,tt=z(e,"ADD_DATA_URI_TAGS")?u(G(nt),e.ADD_DATA_URI_TAGS,w):nt,Z=z(e,"FORBID_CONTENTS")?u({},e.FORBID_CONTENTS,w):et,oe=z(e,"FORBID_TAGS")?u({},e.FORBID_TAGS,w):G({}),Se=z(e,"FORBID_ATTR")?u({},e.FORBID_ATTR,w):G({}),X=z(e,"USE_PROFILES")?e.USE_PROFILES:!1,je=e.ALLOW_ARIA_ATTR!==!1,Re=e.ALLOW_DATA_ATTR!==!1,Xe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,Ze=e.ALLOW_SELF_CLOSE_IN_ATTR!==!1,V=e.SAFE_FOR_TEMPLATES||!1,pe=e.SAFE_FOR_XML!==!1,q=e.WHOLE_DOCUMENT||!1,j=e.RETURN_DOM||!1,ue=e.RETURN_DOM_FRAGMENT||!1,fe=e.RETURN_TRUSTED_TYPE||!1,Pe=e.FORCE_BODY||!1,Qe=e.SANITIZE_DOM!==!1,Je=e.SANITIZE_NAMED_PROPS||!1,Ne=e.KEEP_CONTENT!==!1,re=e.IN_PLACE||!1,Ye=e.ALLOWED_URI_REGEXP||Nt,Q=e.NAMESPACE||H,be=e.MATHML_TEXT_INTEGRATION_POINTS||be,ye=e.HTML_INTEGRATION_POINTS||ye,v=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(v.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&rt(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(v.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements=="boolean"&&(v.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),V&&(Re=!1),ue&&(j=!0),X&&(A=u({},Tt),_=[],X.html===!0&&(u(A,vt),u(_,Et)),X.svg===!0&&(u(A,Fe),u(_,Ke),u(_,Te)),X.svgFilters===!0&&(u(A,$e),u(_,Ke),u(_,Te)),X.mathMl===!0&&(u(A,He),u(_,At),u(_,Te))),e.ADD_TAGS&&(A===qe&&(A=G(A)),u(A,e.ADD_TAGS,w)),e.ADD_ATTR&&(_===Ve&&(_=G(_)),u(_,e.ADD_ATTR,w)),e.ADD_URI_SAFE_ATTR&&u(Ie,e.ADD_URI_SAFE_ATTR,w),e.FORBID_CONTENTS&&(Z===et&&(Z=G(Z)),u(Z,e.FORBID_CONTENTS,w)),Ne&&(A["#text"]=!0),q&&u(A,["html","head","body"]),A.table&&(u(A,["tbody"]),delete oe.tbody),e.TRUSTED_TYPES_POLICY){if(typeof e.TRUSTED_TYPES_POLICY.createHTML!="function")throw ce('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof e.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw ce('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');L=e.TRUSTED_TYPES_POLICY,ne=L.createHTML("")}else L===void 0&&(L=Ln(Y,a)),L!==null&&typeof ne=="string"&&(ne=L.createHTML(""));I&&I(e),J=e}},it=u({},[...Fe,...$e,...yn]),at=u({},[...He,...xn]),Vt=function(e){let i=$(e);(!i||!i.tagName)&&(i={namespaceURI:Q,tagName:"template"});const l=Ee(e.tagName),b=Ee(i.tagName);return De[e.namespaceURI]?e.namespaceURI===ge?i.namespaceURI===H?l==="svg":i.namespaceURI===he?l==="svg"&&(b==="annotation-xml"||be[b]):!!it[l]:e.namespaceURI===he?i.namespaceURI===H?l==="math":i.namespaceURI===ge?l==="math"&&ye[b]:!!at[l]:e.namespaceURI===H?i.namespaceURI===ge&&!ye[b]||i.namespaceURI===he&&!be[b]?!1:!at[l]&&(Gt[l]||!it[l]):!!(ie==="application/xhtml+xml"&&De[e.namespaceURI]):!1},F=function(e){se(r.removed,{element:e});try{$(e).removeChild(e)}catch{k(e)}},ee=function(e,i){try{se(r.removed,{attribute:i.getAttributeNode(e),from:i})}catch{se(r.removed,{attribute:null,from:i})}if(i.removeAttribute(e),e==="is")if(j||ue)try{F(i)}catch{}else try{i.setAttribute(e,"")}catch{}},st=function(e){let i=null,l=null;if(Pe)e="<remove></remove>"+e;else{const T=xt(e,/^[\r\n\t ]+/);l=T&&T[0]}ie==="application/xhtml+xml"&&Q===H&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");const b=L?L.createHTML(e):e;if(Q===H)try{i=new D().parseFromString(b,ie)}catch{}if(!i||!i.documentElement){i=Ae.createDocument(Q,"template",null);try{i.documentElement.innerHTML=Ce?ne:b}catch{}}const S=i.body||i.documentElement;return e&&l&&S.insertBefore(t.createTextNode(l),S.childNodes[0]||null),Q===H?Mt.call(i,q?"html":"body")[0]:q?i.documentElement:S},lt=function(e){return Dt.call(e.ownerDocument||e,e,y.SHOW_ELEMENT|y.SHOW_COMMENT|y.SHOW_TEXT|y.SHOW_PROCESSING_INSTRUCTION|y.SHOW_CDATA_SECTION,null)},Me=function(e){return e instanceof E&&(typeof e.nodeName!="string"||typeof e.textContent!="string"||typeof e.removeChild!="function"||!(e.attributes instanceof d)||typeof e.removeAttribute!="function"||typeof e.setAttribute!="function"||typeof e.namespaceURI!="string"||typeof e.insertBefore!="function"||typeof e.hasChildNodes!="function")},ct=function(e){return typeof h=="function"&&e instanceof h};function K(m,e,i){ve(m,l=>{l.call(r,e,i,J)})}const mt=function(e){let i=null;if(K(P.beforeSanitizeElements,e,null),Me(e))return F(e),!0;const l=w(e.nodeName);if(K(P.uponSanitizeElement,e,{tagName:l,allowedTags:A}),pe&&e.hasChildNodes()&&!ct(e.firstElementChild)&&N(/<[/\w!]/g,e.innerHTML)&&N(/<[/\w!]/g,e.textContent)||e.nodeType===de.progressingInstruction||pe&&e.nodeType===de.comment&&N(/<[/\w]/g,e.data))return F(e),!0;if(!A[l]||oe[l]){if(!oe[l]&&pt(l)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l)))return!1;if(Ne&&!Z[l]){const b=$(e)||e.parentNode,S=U(e)||e.childNodes;if(S&&b){const T=S.length;for(let O=T-1;O>=0;--O){const W=x(S[O],!0);W.__removalCount=(e.__removalCount||0)+1,b.insertBefore(W,te(e))}}}return F(e),!0}return e instanceof g&&!Vt(e)||(l==="noscript"||l==="noembed"||l==="noframes")&&N(/<\/no(script|embed|frames)/i,e.innerHTML)?(F(e),!0):(V&&e.nodeType===de.text&&(i=e.textContent,ve([we,_e,ke],b=>{i=le(i,b," ")}),e.textContent!==i&&(se(r.removed,{element:e.cloneNode()}),e.textContent=i)),K(P.afterSanitizeElements,e,null),!1)},dt=function(e,i,l){if(Qe&&(i==="id"||i==="name")&&(l in t||l in qt))return!1;if(!(Re&&!Se[i]&&N(zt,i))){if(!(je&&N(Ft,i))){if(!_[i]||Se[i]){if(!(pt(e)&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,e)||v.tagNameCheck instanceof Function&&v.tagNameCheck(e))&&(v.attributeNameCheck instanceof RegExp&&N(v.attributeNameCheck,i)||v.attributeNameCheck instanceof Function&&v.attributeNameCheck(i))||i==="is"&&v.allowCustomizedBuiltInElements&&(v.tagNameCheck instanceof RegExp&&N(v.tagNameCheck,l)||v.tagNameCheck instanceof Function&&v.tagNameCheck(l))))return!1}else if(!Ie[i]){if(!N(Ye,le(l,Be,""))){if(!((i==="src"||i==="xlink:href"||i==="href")&&e!=="script"&&fn(l,"data:")===0&&tt[e])){if(!(Xe&&!N($t,le(l,Be,"")))){if(l)return!1}}}}}}return!0},pt=function(e){return e!=="annotation-xml"&&xt(e,Ht)},ut=function(e){K(P.beforeSanitizeAttributes,e,null);const{attributes:i}=e;if(!i||Me(e))return;const l={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:_,forceKeepAttr:void 0};let b=i.length;for(;b--;){const S=i[b],{name:T,namespaceURI:O,value:W}=S,ae=w(T),Ue=W;let R=T==="value"?Ue:hn(Ue);if(l.attrName=ae,l.attrValue=R,l.keepAttr=!0,l.forceKeepAttr=void 0,K(P.uponSanitizeAttribute,e,l),R=l.attrValue,Je&&(ae==="id"||ae==="name")&&(ee(T,e),R=Kt+R),pe&&N(/((--!?|])>)|<\/(style|title)/i,R)){ee(T,e);continue}if(l.forceKeepAttr)continue;if(!l.keepAttr){ee(T,e);continue}if(!Ze&&N(/\/>/i,R)){ee(T,e);continue}V&&ve([we,_e,ke],ht=>{R=le(R,ht," ")});const ft=w(e.nodeName);if(!dt(ft,ae,R)){ee(T,e);continue}if(L&&typeof Y=="object"&&typeof Y.getAttributeType=="function"&&!O)switch(Y.getAttributeType(ft,ae)){case"TrustedHTML":{R=L.createHTML(R);break}case"TrustedScriptURL":{R=L.createScriptURL(R);break}}if(R!==Ue)try{O?e.setAttributeNS(O,T,R):e.setAttribute(T,R),Me(e)?F(e):yt(r.removed)}catch{ee(T,e)}}K(P.afterSanitizeAttributes,e,null)},jt=function m(e){let i=null;const l=lt(e);for(K(P.beforeSanitizeShadowDOM,e,null);i=l.nextNode();)K(P.uponSanitizeShadowNode,i,null),mt(i),ut(i),i.content instanceof s&&m(i.content);K(P.afterSanitizeShadowDOM,e,null)};return r.sanitize=function(m){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},i=null,l=null,b=null,S=null;if(Ce=!m,Ce&&(m="<!-->"),typeof m!="string"&&!ct(m))if(typeof m.toString=="function"){if(m=m.toString(),typeof m!="string")throw ce("dirty is not a string, aborting")}else throw ce("toString is not a function");if(!r.isSupported)return m;if(Le||Oe(e),r.removed=[],typeof m=="string"&&(re=!1),re){if(m.nodeName){const W=w(m.nodeName);if(!A[W]||oe[W])throw ce("root node is forbidden and cannot be sanitized in-place")}}else if(m instanceof h)i=st("<!---->"),l=i.ownerDocument.importNode(m,!0),l.nodeType===de.element&&l.nodeName==="BODY"||l.nodeName==="HTML"?i=l:i.appendChild(l);else{if(!j&&!V&&!q&&m.indexOf("<")===-1)return L&&fe?L.createHTML(m):m;if(i=st(m),!i)return j?null:fe?ne:""}i&&Pe&&F(i.firstChild);const T=lt(re?m:i);for(;b=T.nextNode();)mt(b),ut(b),b.content instanceof s&&jt(b.content);if(re)return m;if(j){if(ue)for(S=Ot.call(i.ownerDocument);i.firstChild;)S.appendChild(i.firstChild);else S=i;return(_.shadowroot||_.shadowrootmode)&&(S=Ut.call(n,S,!0)),S}let O=q?i.outerHTML:i.innerHTML;return q&&A["!doctype"]&&i.ownerDocument&&i.ownerDocument.doctype&&i.ownerDocument.doctype.name&&N(It,i.ownerDocument.doctype.name)&&(O="<!DOCTYPE "+i.ownerDocument.doctype.name+`>
904
- `+O),V&&ve([we,_e,ke],W=>{O=le(O,W," ")}),L&&fe?L.createHTML(O):O},r.setConfig=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Oe(m),Le=!0},r.clearConfig=function(){J=null,Le=!1},r.isValidAttribute=function(m,e,i){J||Oe({});const l=w(m),b=w(e);return dt(l,b,i)},r.addHook=function(m,e){typeof e=="function"&&se(P[m],e)},r.removeHook=function(m,e){if(e!==void 0){const i=pn(P[m],e);return i===-1?void 0:un(P[m],i,1)[0]}return yt(P[m])},r.removeHooks=function(m){P[m]=[]},r.removeAllHooks=function(){P=_t()},r}var Pn=Ct();class Nn extends HTMLElement{constructor(){super();f(this,"rendered",!1);f(this,"nostrService",Qt.getInstance());f(this,"shadow");f(this,"theme","light");f(this,"isLoading",!0);f(this,"isError",!1);f(this,"errorMessage","");f(this,"comments",[]);f(this,"baseUrl","");f(this,"userPublicKey",null);f(this,"userPrivateKey",null);f(this,"currentUserProfile",null);f(this,"isSubmitting",!1);f(this,"replyingToComment",null);f(this,"commentAs","user");f(this,"hasNip07",!1);f(this,"anonPrivateKeyHex",null);f(this,"eventListeners",[]);f(this,"nip07MonitoringInterval",null);f(this,"loadVersion",0);f(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(n=>n.trim()):Jt});f(this,"getTheme",()=>{this.theme="light";const t=this.getAttribute("theme");t&&(["light","dark"].includes(t)?this.theme=t:console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'`))});f(this,"getBaseUrl",()=>{const t=this.getAttribute("url");return t?gt(t):gt(window.location.href)});f(this,"detectNip07Extension",()=>{const t=window.nostr;return t?typeof t.getPublicKey=="function"&&typeof t.signEvent=="function"?!0:(console.warn("NIP-07 extension detected but missing required methods"),!1):!1});f(this,"handleNip07StateChange",async()=>{const t=this.hasNip07,n=this.detectNip07Extension();if(t!==n&&(console.log("NIP-07 extension state changed:",n),this.hasNip07=n,n&&this.commentAs==="user"))try{await this.initializeUser(),this.render()}catch(a){console.warn("Failed to reconnect to NIP-07 extension:",a)}});f(this,"setupNip07StateMonitoring",()=>{const t=setInterval(async()=>{document.contains(this)&&await this.handleNip07StateChange()},2e3);this.nip07MonitoringInterval=t});f(this,"loadComments",async()=>{this.loadVersion++;const t=this.loadVersion;try{this.isLoading=!0,this.isError=!1,this.render();const n=this.getRelays();await this.nostrService.connectToNostr(n);const a={kinds:[1111],"#I":[this.baseUrl],limit:200},s=await this.nostrService.getNDK().fetchEvents(a),c=Array.from(s),h=new Map;c.forEach(p=>h.set(p.id,{content:p.content,id:p.id,tags:p.tags}));const g=[],y=new Set;for(const p of c){let x;const k=(p.tags||[]).filter(U=>U[0]==="e");for(let U=k.length-1;U>=0;U--){const $=k[U];if($[3]==="reply"){x=$[1];break}}if(!x&&k.length>0){const U=k.filter($=>$[3]!=="root");U.length>0?x=U[U.length-1][1]:x=k[k.length-1][1]}const te={id:p.id,pubkey:p.pubkey,content:p.content,created_at:p.created_at,replies:[],replyTo:x,depth:0};y.add(p.pubkey),g.push(te)}const d=Array.from(y).map(async p=>{try{console.log("Fetching profile for pubkey:",p);const x=await this.nostrService.getProfile({pubkey:p});return console.log("Profile fetched for",p,":",x),{pubkey:p,profile:x}}catch(x){return console.warn("Failed to fetch profile for:",p,x),{pubkey:p,profile:null}}}),E=await Promise.allSettled(d),D=new Map;if(E.forEach(p=>{if(p.status==="fulfilled"){const{pubkey:x,profile:k}=p.value;D.set(x,k)}}),g.forEach(p=>{p.userProfile=D.get(p.pubkey)||void 0,console.log("Attached profile to comment:",p.pubkey,"Profile:",p.userProfile)}),t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting");return}this.comments=this.buildCommentTree(g);const Y=new Map;this.comments.forEach(p=>{const x=[p];for(;x.length;){const k=x.pop();Y.set(k.id,k),k.replies.forEach(te=>x.push(te))}}),g.forEach(p=>{const x=p.replyTo?Y.get(p.replyTo):void 0,k=x?x.content:"(no parent)";console.log(`[nostr-comment] recv: "${p.content}" -> parent: ${k}`)})}catch(n){if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting error handling");return}this.isError=!0,this.errorMessage=n instanceof Error?n.message:"Failed to load comments",console.error("Error loading comments:",n)}finally{if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting final state update");return}this.isLoading=!1,this.render()}});f(this,"buildCommentTree",t=>{const n=new Map,a=[];t.forEach(c=>{n.set(c.id,c)}),t.forEach(c=>{if(c.replyTo&&n.has(c.replyTo)){const h=n.get(c.replyTo);h.replies.push(c),h.replies.sort((g,y)=>g.created_at-y.created_at)}else a.push(c)});const s=(c,h)=>{for(const g of c)g.depth=h,g.replies&&g.replies.length&&s(g.replies,h+1)};return s(a,0),a.sort((c,h)=>h.created_at-c.created_at)});f(this,"initializeUser",async()=>{if(this.hasNip07=this.detectNip07Extension(),console.log("NIP-07 extension detected:",this.hasNip07),this.hasNip07&&this.commentAs==="user")try{this.userPublicKey=await window.nostr.getPublicKey(),console.log("Successfully connected to NIP-07 extension, public key:",this.userPublicKey),this.userPrivateKey=null,this.anonPrivateKeyHex=null}catch(t){console.warn("NIP-07 extension available but failed to get public key:",t),this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null}if(!this.userPublicKey){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,this.userPrivateKey=t;const{getPublicKey:n}=await xe(async()=>{const{getPublicKey:a}=await import("../assets/pure-jrVhRVpB.js");return{getPublicKey:a}},__vite__mapDeps([0,1]));this.userPublicKey=n(new Uint8Array(t.match(/.{1,2}/g).map(a=>parseInt(a,16)))),console.log("Using anonymous key for user:",this.userPublicKey)}if(this.commentAs==="anon"&&!this.anonPrivateKeyHex){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,console.log("Ensured anonymous key is available")}if(this.userPublicKey){try{console.log("Fetching profile for user:",this.userPublicKey);const t=await this.nostrService.getProfile({pubkey:this.userPublicKey});console.log("Profile fetched for current user:",t),t?(this.currentUserProfile=t,console.log("Set currentUserProfile to:",this.currentUserProfile)):(this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set fallback currentUserProfile to:",this.currentUserProfile))}catch(t){console.error("Error fetching current user profile:",t),this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set error fallback currentUserProfile to:",this.currentUserProfile)}this.render()}});f(this,"submitComment",async t=>{if(t.trim()){this.userPublicKey||await this.initializeUser(),this.isSubmitting=!0,this.render();try{const n=[];if(n.push(["I",this.baseUrl]),this.replyingToComment){const{rootId:d}=this.findRootAndParent(this.replyingToComment);n.push(["e",d||this.replyingToComment,"","root"]),n.push(["e",this.replyingToComment,"","reply"]),n.push(["k","1111"])}const a={kind:1111,pubkey:this.userPublicKey,content:t.trim(),created_at:Math.floor(Date.now()/1e3),tags:n};let s;if(console.log(`[nostr-comment] Signing attempt - commentAs: ${this.commentAs}, hasNip07: ${!!window.nostr}, anonKey: ${!!this.anonPrivateKeyHex}, userKey: ${!!this.userPrivateKey}`),this.commentAs==="user"&&this.hasNip07&&window.nostr){console.log("[nostr-comment] Using NIP-07 extension to sign");try{s=await window.nostr.signEvent(a),console.log("[nostr-comment] Successfully signed with NIP-07 extension")}catch(d){throw console.error("[nostr-comment] Failed to sign with NIP-07 extension:",d),new Error("Failed to sign with NIP-07 extension. Please check if your extension is unlocked.")}}else if(this.commentAs==="anon"&&this.anonPrivateKeyHex){console.log("[nostr-comment] Using anonymous private key to sign");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-jrVhRVpB.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.anonPrivateKeyHex.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else if(this.userPrivateKey){console.log("[nostr-comment] Using local private key to sign (fallback)");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-jrVhRVpB.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.userPrivateKey.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else throw console.error("[nostr-comment] No signing method available - commentAs:",this.commentAs,"hasNip07:",this.hasNip07,"anonKey:",!!this.anonPrivateKeyHex,"userKey:",!!this.userPrivateKey),new Error("No signing method available. Please check your NIP-07 extension or switch to anonymous mode.");await new en(this.nostrService.getNDK(),s).publish();const h={id:s.id,pubkey:s.pubkey,content:s.content,created_at:s.created_at,replies:[],replyTo:this.replyingToComment||void 0,depth:0};if(this.currentUserProfile)h.userProfile=this.currentUserProfile;else{try{const d=await this.nostrService.getProfile({pubkey:s.pubkey});d&&(h.userProfile=d,this.currentUserProfile=d)}catch{console.warn("Could not fetch profile for new comment")}h.userProfile||(h.userProfile={name:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,image:"../../assets/default_dp.png"})}this.replyingToComment?this.addReplyToComment(h,this.replyingToComment):this.comments.unshift(h);const g=n.find(d=>d[0]==="e"&&d[3]==="root"),y=n.find(d=>d[0]==="e"&&d[3]==="reply");if(console.log(`[nostr-comment] send: "${a.content}" root=${g?g[1]:"(none)"} parent=${y?y[1]:"(none)"} `),this.replyingToComment){const d=this.shadow.querySelector(".inline-reply-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}else{const d=this.shadow.querySelector(".modern-comment-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}this.replyingToComment=null}catch(n){console.error("Failed to submit comment:",n);let a="Failed to submit comment: "+(n instanceof Error?n.message:"Unknown error");n instanceof Error&&n.message.includes("NIP-07")&&(n.message.includes("extension is unlocked")?a="Please unlock your Nostr extension (nos2x/Alby) and try again.":n.message.includes("getPublicKey")?a="Please authorize this website in your Nostr extension.":a="Nostr extension error. Please check if your extension is working properly."),this.showError(a)}finally{this.isSubmitting=!1,this.render()}}});f(this,"addReplyToComment",(t,n)=>{const a=s=>{for(const c of s){if(c.id===n)return t.depth=(c.depth||0)+1,c.replies.push(t),c.replies.sort((h,g)=>h.created_at-g.created_at),!0;if(c.replies.length>0&&a(c.replies))return!0}return!1};a(this.comments)});f(this,"startReply",t=>{this.replyingToComment=null,this.render(),setTimeout(()=>{this.replyingToComment=t,this.render(),setTimeout(()=>{const n=this.shadow.querySelector(".inline-reply-form"),a=n==null?void 0:n.querySelector('[data-role="comment-input"]');a&&a.focus()},100)},10)});f(this,"cancelReply",()=>{this.replyingToComment=null,this.render()});this.shadow=this.attachShadow({mode:"open"})}findRootAndParent(t){let n,a;const s=(c,h,g)=>{var y;for(const d of c){const E=h??d.id;if(d.id===t)return n=E,a=g,!0;if((y=d.replies)!=null&&y.length&&s(d.replies,E,d.id))return!0}return!1};return s(this.comments),{rootId:n,parentId:a}}async connectedCallback(){if(!this.rendered)try{this.getTheme(),this.baseUrl=this.getBaseUrl(),await this.initializeUser(),await this.loadComments(),this.setupNip07StateMonitoring(),this.rendered=!0}catch(t){console.error("Error in connectedCallback:",t),this.isError=!0,this.errorMessage="Failed to initialize comment component",this.render()}}static get observedAttributes(){return["relays","theme","url","readonly","placeholder"]}async attributeChangedCallback(t,n,a){t==="relays"&&(this.nostrService.connectToNostr(this.getRelays()),await this.loadComments()),t==="theme"&&(this.getTheme(),this.render()),t==="url"&&(this.baseUrl=this.getBaseUrl(),await this.loadComments()),["readonly","placeholder"].includes(t)&&this.render()}disconnectedCallback(){this.removeEventListeners(),this.nip07MonitoringInterval&&(clearInterval(this.nip07MonitoringInterval),this.nip07MonitoringInterval=null)}attachEventListeners(){this.removeEventListeners(),this.shadow.querySelectorAll('[data-role="submit-comment"]').forEach(t=>{const n=a=>{a.preventDefault();const s=a.target.closest(".modern-comment-form, .inline-reply-form"),c=s==null?void 0:s.querySelector('[data-role="comment-input"]');c&&this.submitComment(c.value)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="comment-input"]').forEach(t=>{const n=a=>{const s=a;s.key==="Enter"&&(s.ctrlKey||s.metaKey)&&(s.preventDefault(),this.submitComment(t.value))};t.addEventListener("keydown",n),this.eventListeners.push({element:t,type:"keydown",handler:n})}),this.shadow.querySelectorAll('[data-role="cancel-reply"]').forEach(t=>{const n=a=>{a.preventDefault(),this.cancelReply()};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll(".reply-btn").forEach(t=>{const n=a=>{a.preventDefault();const s=a.currentTarget.getAttribute("data-comment-id");s&&this.startReply(s)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="toggle-as-user"]').forEach(t=>{if(!this.hasNip07)t.disabled=!0,t.title="NIP-07 extension not detected";else{const n=async a=>{a.preventDefault(),this.commentAs!=="user"&&(this.commentAs="user",this.userPrivateKey=null,this.anonPrivateKeyHex=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}}),this.shadow.querySelectorAll('[data-role="toggle-as-anon"]').forEach(t=>{t.disabled=!1;const n=async a=>{a.preventDefault(),this.commentAs!=="anon"&&(this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})})}attachAvatarErrorHandlers(){this.shadow.querySelectorAll("img[src]").forEach(t=>{const n=a=>{const s=a.target;if(s.src===this.getDefaultAvatarUrl()){console.warn("Avatar fallback also failed, preventing infinite loop");return}s.src=this.getDefaultAvatarUrl()};t.addEventListener("error",n),this.eventListeners.push({element:t,type:"error",handler:n})})}removeEventListeners(){this.eventListeners.forEach(({element:t,type:n,handler:a})=>{t.removeEventListener(n,a)}),this.eventListeners=[]}showError(t){const n=document.createElement("div");n.className="nostr-comment-error",n.style.cssText=`
904
+ `+O),V&&ve([we,_e,ke],W=>{O=le(O,W," ")}),L&&fe?L.createHTML(O):O},r.setConfig=function(){let m=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Oe(m),Le=!0},r.clearConfig=function(){J=null,Le=!1},r.isValidAttribute=function(m,e,i){J||Oe({});const l=w(m),b=w(e);return dt(l,b,i)},r.addHook=function(m,e){typeof e=="function"&&se(P[m],e)},r.removeHook=function(m,e){if(e!==void 0){const i=pn(P[m],e);return i===-1?void 0:un(P[m],i,1)[0]}return yt(P[m])},r.removeHooks=function(m){P[m]=[]},r.removeAllHooks=function(){P=_t()},r}var Pn=Ct();class Nn extends HTMLElement{constructor(){super();f(this,"rendered",!1);f(this,"nostrService",Qt.getInstance());f(this,"shadow");f(this,"theme","light");f(this,"isLoading",!0);f(this,"isError",!1);f(this,"errorMessage","");f(this,"comments",[]);f(this,"baseUrl","");f(this,"userPublicKey",null);f(this,"userPrivateKey",null);f(this,"currentUserProfile",null);f(this,"isSubmitting",!1);f(this,"replyingToComment",null);f(this,"commentAs","user");f(this,"hasNip07",!1);f(this,"anonPrivateKeyHex",null);f(this,"eventListeners",[]);f(this,"nip07MonitoringInterval",null);f(this,"loadVersion",0);f(this,"getRelays",()=>{const t=this.getAttribute("relays");return t?t.split(",").map(n=>n.trim()):Jt});f(this,"getTheme",()=>{this.theme="light";const t=this.getAttribute("theme");t&&(["light","dark"].includes(t)?this.theme=t:console.warn(`Invalid theme '${t}'. Accepted values are 'light', 'dark'`))});f(this,"getBaseUrl",()=>{const t=this.getAttribute("url");return t?gt(t):gt(window.location.href)});f(this,"detectNip07Extension",()=>{const t=window.nostr;return t?typeof t.getPublicKey=="function"&&typeof t.signEvent=="function"?!0:(console.warn("NIP-07 extension detected but missing required methods"),!1):!1});f(this,"handleNip07StateChange",async()=>{const t=this.hasNip07,n=this.detectNip07Extension();if(t!==n&&(console.log("NIP-07 extension state changed:",n),this.hasNip07=n,n&&this.commentAs==="user"))try{await this.initializeUser(),this.render()}catch(a){console.warn("Failed to reconnect to NIP-07 extension:",a)}});f(this,"setupNip07StateMonitoring",()=>{const t=setInterval(async()=>{document.contains(this)&&await this.handleNip07StateChange()},2e3);this.nip07MonitoringInterval=t});f(this,"loadComments",async()=>{this.loadVersion++;const t=this.loadVersion;try{this.isLoading=!0,this.isError=!1,this.render();const n=this.getRelays();await this.nostrService.connectToNostr(n);const a={kinds:[1111],"#I":[this.baseUrl],limit:200},s=await this.nostrService.getNDK().fetchEvents(a),c=Array.from(s),h=new Map;c.forEach(p=>h.set(p.id,{content:p.content,id:p.id,tags:p.tags}));const g=[],y=new Set;for(const p of c){let x;const k=(p.tags||[]).filter(U=>U[0]==="e");for(let U=k.length-1;U>=0;U--){const $=k[U];if($[3]==="reply"){x=$[1];break}}if(!x&&k.length>0){const U=k.filter($=>$[3]!=="root");U.length>0?x=U[U.length-1][1]:x=k[k.length-1][1]}const te={id:p.id,pubkey:p.pubkey,content:p.content,created_at:p.created_at,replies:[],replyTo:x,depth:0};y.add(p.pubkey),g.push(te)}const d=Array.from(y).map(async p=>{try{console.log("Fetching profile for pubkey:",p);const x=await this.nostrService.getProfile({pubkey:p});return console.log("Profile fetched for",p,":",x),{pubkey:p,profile:x}}catch(x){return console.warn("Failed to fetch profile for:",p,x),{pubkey:p,profile:null}}}),E=await Promise.allSettled(d),D=new Map;if(E.forEach(p=>{if(p.status==="fulfilled"){const{pubkey:x,profile:k}=p.value;D.set(x,k)}}),g.forEach(p=>{p.userProfile=D.get(p.pubkey)||void 0,console.log("Attached profile to comment:",p.pubkey,"Profile:",p.userProfile)}),t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting");return}this.comments=this.buildCommentTree(g);const Y=new Map;this.comments.forEach(p=>{const x=[p];for(;x.length;){const k=x.pop();Y.set(k.id,k),k.replies.forEach(te=>x.push(te))}}),g.forEach(p=>{const x=p.replyTo?Y.get(p.replyTo):void 0,k=x?x.content:"(no parent)";console.log(`[nostr-comment] recv: "${p.content}" -> parent: ${k}`)})}catch(n){if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting error handling");return}this.isError=!0,this.errorMessage=n instanceof Error?n.message:"Failed to load comments",console.error("Error loading comments:",n)}finally{if(t!==this.loadVersion){console.log("Load operation superseded by newer request, aborting final state update");return}this.isLoading=!1,this.render()}});f(this,"buildCommentTree",t=>{const n=new Map,a=[];t.forEach(c=>{n.set(c.id,c)}),t.forEach(c=>{if(c.replyTo&&n.has(c.replyTo)){const h=n.get(c.replyTo);h.replies.push(c),h.replies.sort((g,y)=>g.created_at-y.created_at)}else a.push(c)});const s=(c,h)=>{for(const g of c)g.depth=h,g.replies&&g.replies.length&&s(g.replies,h+1)};return s(a,0),a.sort((c,h)=>h.created_at-c.created_at)});f(this,"initializeUser",async()=>{if(this.hasNip07=this.detectNip07Extension(),console.log("NIP-07 extension detected:",this.hasNip07),this.hasNip07&&this.commentAs==="user")try{this.userPublicKey=await window.nostr.getPublicKey(),console.log("Successfully connected to NIP-07 extension, public key:",this.userPublicKey),this.userPrivateKey=null,this.anonPrivateKeyHex=null}catch(t){console.warn("NIP-07 extension available but failed to get public key:",t),this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null}if(!this.userPublicKey){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,this.userPrivateKey=t;const{getPublicKey:n}=await xe(async()=>{const{getPublicKey:a}=await import("../assets/pure-DPo-pzxM.js");return{getPublicKey:a}},__vite__mapDeps([0,1]));this.userPublicKey=n(new Uint8Array(t.match(/.{1,2}/g).map(a=>parseInt(a,16)))),console.log("Using anonymous key for user:",this.userPublicKey)}if(this.commentAs==="anon"&&!this.anonPrivateKeyHex){const t=await this.ensureAnonKey();this.anonPrivateKeyHex=t,console.log("Ensured anonymous key is available")}if(this.userPublicKey){try{console.log("Fetching profile for user:",this.userPublicKey);const t=await this.nostrService.getProfile({pubkey:this.userPublicKey});console.log("Profile fetched for current user:",t),t?(this.currentUserProfile=t,console.log("Set currentUserProfile to:",this.currentUserProfile)):(this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set fallback currentUserProfile to:",this.currentUserProfile))}catch(t){console.error("Error fetching current user profile:",t),this.currentUserProfile={name:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${this.userPublicKey.slice(0,8)}`,image:"../../assets/default_dp.png"},console.log("Set error fallback currentUserProfile to:",this.currentUserProfile)}this.render()}});f(this,"submitComment",async t=>{if(t.trim()){this.userPublicKey||await this.initializeUser(),this.isSubmitting=!0,this.render();try{const n=[];if(n.push(["I",this.baseUrl]),this.replyingToComment){const{rootId:d}=this.findRootAndParent(this.replyingToComment);n.push(["e",d||this.replyingToComment,"","root"]),n.push(["e",this.replyingToComment,"","reply"]),n.push(["k","1111"])}const a={kind:1111,pubkey:this.userPublicKey,content:t.trim(),created_at:Math.floor(Date.now()/1e3),tags:n};let s;if(console.log(`[nostr-comment] Signing attempt - commentAs: ${this.commentAs}, hasNip07: ${!!window.nostr}, anonKey: ${!!this.anonPrivateKeyHex}, userKey: ${!!this.userPrivateKey}`),this.commentAs==="user"&&this.hasNip07&&window.nostr){console.log("[nostr-comment] Using NIP-07 extension to sign");try{s=await window.nostr.signEvent(a),console.log("[nostr-comment] Successfully signed with NIP-07 extension")}catch(d){throw console.error("[nostr-comment] Failed to sign with NIP-07 extension:",d),new Error("Failed to sign with NIP-07 extension. Please check if your extension is unlocked.")}}else if(this.commentAs==="anon"&&this.anonPrivateKeyHex){console.log("[nostr-comment] Using anonymous private key to sign");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-DPo-pzxM.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.anonPrivateKeyHex.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else if(this.userPrivateKey){console.log("[nostr-comment] Using local private key to sign (fallback)");const{finalizeEvent:d}=await xe(async()=>{const{finalizeEvent:D}=await import("../assets/pure-DPo-pzxM.js");return{finalizeEvent:D}},__vite__mapDeps([0,1])),E=new Uint8Array(this.userPrivateKey.match(/.{1,2}/g).map(D=>parseInt(D,16)));s=d(a,E)}else throw console.error("[nostr-comment] No signing method available - commentAs:",this.commentAs,"hasNip07:",this.hasNip07,"anonKey:",!!this.anonPrivateKeyHex,"userKey:",!!this.userPrivateKey),new Error("No signing method available. Please check your NIP-07 extension or switch to anonymous mode.");await new en(this.nostrService.getNDK(),s).publish();const h={id:s.id,pubkey:s.pubkey,content:s.content,created_at:s.created_at,replies:[],replyTo:this.replyingToComment||void 0,depth:0};if(this.currentUserProfile)h.userProfile=this.currentUserProfile;else{try{const d=await this.nostrService.getProfile({pubkey:s.pubkey});d&&(h.userProfile=d,this.currentUserProfile=d)}catch{console.warn("Could not fetch profile for new comment")}h.userProfile||(h.userProfile={name:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,displayName:this.commentAs==="anon"?"Anonymous":`User ${s.pubkey.slice(0,8)}`,image:"../../assets/default_dp.png"})}this.replyingToComment?this.addReplyToComment(h,this.replyingToComment):this.comments.unshift(h);const g=n.find(d=>d[0]==="e"&&d[3]==="root"),y=n.find(d=>d[0]==="e"&&d[3]==="reply");if(console.log(`[nostr-comment] send: "${a.content}" root=${g?g[1]:"(none)"} parent=${y?y[1]:"(none)"} `),this.replyingToComment){const d=this.shadow.querySelector(".inline-reply-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}else{const d=this.shadow.querySelector(".modern-comment-form"),E=d==null?void 0:d.querySelector('[data-role="comment-input"]');E&&(E.value="")}this.replyingToComment=null}catch(n){console.error("Failed to submit comment:",n);let a="Failed to submit comment: "+(n instanceof Error?n.message:"Unknown error");n instanceof Error&&n.message.includes("NIP-07")&&(n.message.includes("extension is unlocked")?a="Please unlock your Nostr extension (nos2x/Alby) and try again.":n.message.includes("getPublicKey")?a="Please authorize this website in your Nostr extension.":a="Nostr extension error. Please check if your extension is working properly."),this.showError(a)}finally{this.isSubmitting=!1,this.render()}}});f(this,"addReplyToComment",(t,n)=>{const a=s=>{for(const c of s){if(c.id===n)return t.depth=(c.depth||0)+1,c.replies.push(t),c.replies.sort((h,g)=>h.created_at-g.created_at),!0;if(c.replies.length>0&&a(c.replies))return!0}return!1};a(this.comments)});f(this,"startReply",t=>{this.replyingToComment=null,this.render(),setTimeout(()=>{this.replyingToComment=t,this.render(),setTimeout(()=>{const n=this.shadow.querySelector(".inline-reply-form"),a=n==null?void 0:n.querySelector('[data-role="comment-input"]');a&&a.focus()},100)},10)});f(this,"cancelReply",()=>{this.replyingToComment=null,this.render()});this.shadow=this.attachShadow({mode:"open"})}findRootAndParent(t){let n,a;const s=(c,h,g)=>{var y;for(const d of c){const E=h??d.id;if(d.id===t)return n=E,a=g,!0;if((y=d.replies)!=null&&y.length&&s(d.replies,E,d.id))return!0}return!1};return s(this.comments),{rootId:n,parentId:a}}async connectedCallback(){if(!this.rendered)try{this.getTheme(),this.baseUrl=this.getBaseUrl(),await this.initializeUser(),await this.loadComments(),this.setupNip07StateMonitoring(),this.rendered=!0}catch(t){console.error("Error in connectedCallback:",t),this.isError=!0,this.errorMessage="Failed to initialize comment component",this.render()}}static get observedAttributes(){return["relays","theme","url","readonly","placeholder"]}async attributeChangedCallback(t,n,a){t==="relays"&&(this.nostrService.connectToNostr(this.getRelays()),await this.loadComments()),t==="theme"&&(this.getTheme(),this.render()),t==="url"&&(this.baseUrl=this.getBaseUrl(),await this.loadComments()),["readonly","placeholder"].includes(t)&&this.render()}disconnectedCallback(){this.removeEventListeners(),this.nip07MonitoringInterval&&(clearInterval(this.nip07MonitoringInterval),this.nip07MonitoringInterval=null)}attachEventListeners(){this.removeEventListeners(),this.shadow.querySelectorAll('[data-role="submit-comment"]').forEach(t=>{const n=a=>{a.preventDefault();const s=a.target.closest(".modern-comment-form, .inline-reply-form"),c=s==null?void 0:s.querySelector('[data-role="comment-input"]');c&&this.submitComment(c.value)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="comment-input"]').forEach(t=>{const n=a=>{const s=a;s.key==="Enter"&&(s.ctrlKey||s.metaKey)&&(s.preventDefault(),this.submitComment(t.value))};t.addEventListener("keydown",n),this.eventListeners.push({element:t,type:"keydown",handler:n})}),this.shadow.querySelectorAll('[data-role="cancel-reply"]').forEach(t=>{const n=a=>{a.preventDefault(),this.cancelReply()};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll(".reply-btn").forEach(t=>{const n=a=>{a.preventDefault();const s=a.currentTarget.getAttribute("data-comment-id");s&&this.startReply(s)};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}),this.shadow.querySelectorAll('[data-role="toggle-as-user"]').forEach(t=>{if(!this.hasNip07)t.disabled=!0,t.title="NIP-07 extension not detected";else{const n=async a=>{a.preventDefault(),this.commentAs!=="user"&&(this.commentAs="user",this.userPrivateKey=null,this.anonPrivateKeyHex=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})}}),this.shadow.querySelectorAll('[data-role="toggle-as-anon"]').forEach(t=>{t.disabled=!1;const n=async a=>{a.preventDefault(),this.commentAs!=="anon"&&(this.commentAs="anon",this.userPublicKey=null,this.userPrivateKey=null,await this.initializeUser())};t.addEventListener("click",n),this.eventListeners.push({element:t,type:"click",handler:n})})}attachAvatarErrorHandlers(){this.shadow.querySelectorAll("img[src]").forEach(t=>{const n=a=>{const s=a.target;if(s.src===this.getDefaultAvatarUrl()){console.warn("Avatar fallback also failed, preventing infinite loop");return}s.src=this.getDefaultAvatarUrl()};t.addEventListener("error",n),this.eventListeners.push({element:t,type:"error",handler:n})})}removeEventListeners(){this.eventListeners.forEach(({element:t,type:n,handler:a})=>{t.removeEventListener(n,a)}),this.eventListeners=[]}showError(t){const n=document.createElement("div");n.className="nostr-comment-error",n.style.cssText=`
905
905
  position: fixed;
906
906
  top: 20px;
907
907
  right: 20px;
@@ -915,10 +915,10 @@ var Xt=Object.defineProperty;var Zt=(o,r,t)=>r in o?Xt(o,r,{enumerable:!0,config
915
915
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
916
916
  font-size: 14px;
917
917
  line-height: 1.4;
918
- `,n.textContent=t,document.body.appendChild(n);const a=t.includes("NIP-07")?8e3:5e3;setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n)},a)}getDefaultAvatarUrl(){try{return new URL("/assets/default_dp-NQ3TGrtT.png",import.meta.url).toString()}catch(t){return console.warn("Failed to resolve default avatar URL with import.meta.url, using relative path:",t),"../../assets/default_dp.png"}}async ensureAnonKey(){const t="nostr-comment-anon-private-key";try{const s=localStorage.getItem(t);if(s&&s.match(/^[a-f0-9]{64}$/))return s}catch(s){console.warn("Failed to read from localStorage:",s)}const{generateSecretKey:n}=await xe(async()=>{const{generateSecretKey:s}=await import("../assets/pure-jrVhRVpB.js");return{generateSecretKey:s}},__vite__mapDeps([0,1])),a=Array.from(n()).map(s=>s.toString(16).padStart(2,"0")).join("");try{localStorage.setItem(t,a)}catch(s){console.warn("Failed to write to localStorage, using ephemeral key:",s)}return a}render(){this.classList.toggle("dark",this.theme==="dark"),this.classList.toggle("loading",this.isLoading),this.classList.toggle("error-container",this.isError);const t=this.hasAttribute("readonly"),n=this.getAttribute("placeholder")||"Write a comment...",a=sn(this.isLoading,this.isError,this.errorMessage,this.comments,t,n,this.isSubmitting,this.currentUserProfile,this.replyingToComment,this.commentAs,this.hasNip07),s=Pn.sanitize(a,{ALLOWED_TAGS:["div","span","button","textarea","img","a","h3","h4","p","ul","li","small","strong","em"],ALLOWED_ATTR:["class","data-role","data-comment-id","data-depth","src","alt","href","target","rel","placeholder","rows","disabled"],ALLOW_DATA_ATTR:!1});this.shadow.innerHTML=`
918
+ `,n.textContent=t,document.body.appendChild(n);const a=t.includes("NIP-07")?8e3:5e3;setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n)},a)}getDefaultAvatarUrl(){try{return new URL("/assets/default_dp-NQ3TGrtT.png",import.meta.url).toString()}catch(t){return console.warn("Failed to resolve default avatar URL with import.meta.url, using relative path:",t),"../../assets/default_dp.png"}}async ensureAnonKey(){const t="nostr-comment-anon-private-key";try{const s=localStorage.getItem(t);if(s&&s.match(/^[a-f0-9]{64}$/))return s}catch(s){console.warn("Failed to read from localStorage:",s)}const{generateSecretKey:n}=await xe(async()=>{const{generateSecretKey:s}=await import("../assets/pure-DPo-pzxM.js");return{generateSecretKey:s}},__vite__mapDeps([0,1])),a=Array.from(n()).map(s=>s.toString(16).padStart(2,"0")).join("");try{localStorage.setItem(t,a)}catch(s){console.warn("Failed to write to localStorage, using ephemeral key:",s)}return a}render(){this.classList.toggle("dark",this.theme==="dark"),this.classList.toggle("loading",this.isLoading),this.classList.toggle("error-container",this.isError);const t=this.hasAttribute("readonly"),n=this.getAttribute("placeholder")||"Write a comment...",a=sn(this.isLoading,this.isError,this.errorMessage,this.comments,t,n,this.isSubmitting,this.currentUserProfile,this.replyingToComment,this.commentAs,this.hasNip07),s=Pn.sanitize(a,{ALLOWED_TAGS:["div","span","button","textarea","img","a","h3","h4","p","ul","li","small","strong","em"],ALLOWED_ATTR:["class","data-role","data-comment-id","data-depth","src","alt","href","target","rel","placeholder","rows","disabled"],ALLOW_DATA_ATTR:!1});this.shadow.innerHTML=`
919
919
  ${ln(this.theme)}
920
920
  <div class="nostr-comment-wrapper">
921
921
  ${s}
922
922
  </div>
923
- `,this.attachEventListeners(),this.attachAvatarErrorHandlers()}}customElements.get("nostr-comment")||customElements.define("nostr-comment",Nn);
923
+ `,this.attachEventListeners(),this.attachAvatarErrorHandlers()}}customElements.get("nostr-comment")||customElements.define("nostr-comment",Nn);export{Nn as default};
924
924
  //# sourceMappingURL=nostr-comment.es.js.map
@@ -1,4 +1,4 @@
1
- var v=Object.defineProperty;var x=(s,o,e)=>o in s?v(s,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[o]=e;var i=(s,o,e)=>x(s,typeof o!="symbol"?o+"":o,e);import{_ as m}from"../assets/preload-helper-D7HrI6pR.js";import{N as y,D as k,c as w,d as F,e as S,g as E}from"../assets/nostr-service-pr_crY62.js";import{g as b,a as g}from"../assets/theme-C1r1Zw8r.js";import{r as N}from"../assets/nip05-utils-BNBHUmkr.js";import"../assets/icons-Dr_d9MII.js";function $({theme:s,recipientNpub:o,recipientName:e,recipientPicture:t,message:r,isLoading:n,isFinding:a,isError:d,errorMessage:h,isSent:p}){const c=n?"Sending...":"Send DM",u=24,f=o?"Type your message here...":"Enter recipient npub/nip05 address...";return`
1
+ var v=Object.defineProperty;var x=(s,o,e)=>o in s?v(s,o,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[o]=e;var i=(s,o,e)=>x(s,typeof o!="symbol"?o+"":o,e);import{_ as m}from"../assets/preload-helper-D7HrI6pR.js";import{b as y,c as k,a as w,N as F,d as S,e as E}from"../assets/nostr-service-CnaPxjc6.js";import{a as b,b as g}from"../assets/theme-BN1Bvweb.js";import{r as N}from"../assets/nip05-utils-BNBHUmkr.js";import"../assets/icons-Dr_d9MII.js";function $({theme:s,recipientNpub:o,recipientName:e,recipientPicture:t,message:r,isLoading:n,isFinding:a,isError:d,errorMessage:h,isSent:p}){const c=n?"Sending...":"Send DM",u=24,f=o?"Type your message here...":"Enter recipient npub/nip05 address...";return`
2
2
  ${D(s)}
3
3
  <div class="nostr-dm-container ${d?"nostr-dm-error":""}">
4
4
  <div class="nostr-dm-header">
@@ -213,5 +213,5 @@ var v=Object.defineProperty;var x=(s,o,e)=>o in s?v(s,o,{enumerable:!0,configura
213
213
  padding: 0 16px 16px;
214
214
  }
215
215
  </style>
216
- `}function l(s,o,e){s.getAttribute("debug")==="true"&&(e?console.log(`[NostrDm] ${o}`,e):console.log(`[NostrDm] ${o}`))}class R extends HTMLElement{constructor(){super();i(this,"rendered",!1);i(this,"nostrService",y.getInstance());i(this,"theme","light");i(this,"recipientNpub",null);i(this,"recipientNip05",null);i(this,"recipientName",null);i(this,"recipientPicture",null);i(this,"recipientPubkey",null);i(this,"message","");i(this,"isLoading",!1);i(this,"isFinding",!1);i(this,"isError",!1);i(this,"errorMessage","");i(this,"isSent",!1);i(this,"boundHandleFind",null);i(this,"boundHandleSend",null);i(this,"boundHandleTextareaChange",null);i(this,"getRelays",()=>{const e=this.getAttribute("relays");return e?e.split(","):k});i(this,"getTheme",async()=>{this.theme="light";const e=this.getAttribute("theme");if(e){if(!["light","dark"].includes(e))throw new Error(`Invalid theme '${e}'. Accepted values are 'light', 'dark'`);this.theme=e}});i(this,"getRecipient",()=>{const e=this.getAttribute("nip05");if(e){this.recipientNip05=e,this.lookupRecipientByNip05();return}const t=this.getAttribute("recipient-npub");t&&(this.recipientNpub=t,this.lookupRecipient())});this.attachShadow({mode:"open"})}connectedCallback(){this.rendered||(this.rendered=!0,this.getTheme(),this.getRecipient(),this.nostrService.connectToNostr(this.getRelays()),this.render())}static get observedAttributes(){return["relays","recipient-npub","nip05","theme","debug"]}attributeChangedCallback(e,t,r){e==="relays"&&this.nostrService.connectToNostr(this.getRelays()),e==="theme"&&this.getTheme(),e==="nip05"&&r&&(this.recipientNip05=r,this.lookupRecipientByNip05()),e==="recipient-npub"&&r&&(this.recipientNpub=r,this.lookupRecipient()),this.render()}async lookupRecipient(e){const t=e||this.recipientNpub;if(t){this.isFinding=!0,this.render();try{const n=this.nostrService.getNDK().getUser({npub:t});await n.fetchProfile(),n.profile?(this.recipientName=n.profile.displayName||n.profile.name||"Unknown",this.recipientPicture=n.profile.image||null,this.recipientPubkey=n.pubkey,this.recipientNpub=t):(this.recipientName="Unknown",this.recipientPicture=null,this.recipientPubkey=n.pubkey,this.recipientNpub=t)}catch(r){this.isError=!0,this.errorMessage=`Failed to find recipient: ${r.message}`}finally{this.isFinding=!1,this.render()}}}async lookupRecipientByNip05(e){const t=e||this.recipientNip05;if(t){this.isFinding=!0,this.render();try{const r=await N(t);if(!r)throw new Error("Failed to resolve nip05");const n=w.npubEncode(r);await this.lookupRecipient(n)}catch(r){this.isError=!0,this.errorMessage=`Failed to resolve nip05: ${r.message}`}finally{this.isFinding=!1,this.render()}}}async handleFindClick(){const e=this.shadowRoot.querySelector(".nostr-dm-npub-input");if(!e||!e.value){this.isError=!0,this.errorMessage="Please enter a valid npub",this.render();return}const t=e.value.trim();t.includes("@")?await this.lookupRecipientByNip05(t):await this.lookupRecipient(t)}async handleSendClick(){if(l(this,"Send button clicked!"),!this.recipientPubkey||!this.message.trim()){this.isError=!0,this.errorMessage=this.recipientPubkey?"Please enter a message":"Recipient not found",this.render();return}if(this.isError=!1,this.isSent=!1,this.isLoading=!0,this.render(),!this.nostrService.hasSigner()){this.isError=!0,this.errorMessage="No Nostr signer available. Please ensure your Nostr extension is installed or provide a private key.",this.isLoading=!1,this.render();return}let e=null;if(typeof window<"u"&&window.nostr)e=new F;else if(typeof localStorage<"u"){const t=localStorage.getItem("nostr_nsec");if(t){const{NDKPrivateKeySigner:r}=await m(async()=>{const{NDKPrivateKeySigner:n}=await import("../assets/nostr-service-pr_crY62.js").then(a=>a.k);return{NDKPrivateKeySigner:n}},[]);e=new r(t)}}if(!e){this.isError=!0,this.errorMessage="Failed to create signer. Please ensure your Nostr signer (extension or private key) is configured.",this.render();return}this.render();try{const t=this.nostrService.getNDK();t.signer=e;const{nip04:r}=await m(async()=>{const{nip04:d}=await import("../assets/nostr-service-pr_crY62.js").then(h=>h.j);return{nip04:d}},[]),n=new S(t,{kind:E.EncryptedDirectMessage,tags:[["p",this.recipientPubkey]],created_at:Math.floor(Date.now()/1e3)});if(typeof window<"u"&&window.nostr){const d=await window.nostr.nip04.encrypt(this.recipientPubkey,this.message.trim());n.content=d}else if(typeof localStorage<"u"){const d=localStorage.getItem("nostr_nsec");if(!d)throw new Error("No private key available");const{nip19:h}=await m(async()=>{const{nip19:c}=await import("../assets/nostr-service-pr_crY62.js").then(u=>u.j);return{nip19:c}},[]);let p=d;if(d.startsWith("nsec"))try{p=h.decode(d).data}catch(c){throw console.error("Failed to decode nsec:",c),new Error("Invalid private key format")}try{n.content=await r.encrypt(p,this.recipientPubkey,this.message.trim())}catch(c){throw console.error("Encryption error:",c),new Error(`Encryption failed: ${c.message}`)}}l(this,"Sending encrypted DM:",{to:this.recipientPubkey,encryptedContent:n.content}),await n.publish(),l(this,"DM sent with encrypted content:",n),this.isSent=!0,this.message="";const a=this.shadowRoot.querySelector(".nostr-dm-textarea");a&&(a.value="")}catch(t){this.isError=!0,this.errorMessage=`Failed to send message: ${t.message}`,this.isSent=!1}finally{this.isLoading=!1,this.isFinding=!1,this.render()}}handleTextareaChange(e){const t=e.target;this.message=t.value}attachEventListeners(){const e=this.shadowRoot.querySelector(".nostr-dm-find-btn");e?(this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind),this.boundHandleFind=this.handleFindClick.bind(this),e.addEventListener("click",this.boundHandleFind),l(this,"Find button event listener attached")):l(this,"Find button not found in DOM");const t=this.shadowRoot.querySelector(".nostr-dm-send-btn");t?(l(this,"Send button found, disabled:",t.hasAttribute("disabled")),this.boundHandleSend&&t.removeEventListener("click",this.boundHandleSend),this.boundHandleSend=this.handleSendClick.bind(this),t.addEventListener("click",this.boundHandleSend),this.recipientPubkey&&!this.isLoading&&t.removeAttribute("disabled"),l(this,"Send button event listener attached")):l(this,"Send button not found in DOM");const r=this.shadowRoot.querySelector(".nostr-dm-textarea");r&&(this.boundHandleTextareaChange&&r.removeEventListener("input",this.boundHandleTextareaChange),this.boundHandleTextareaChange=this.handleTextareaChange.bind(this),r.addEventListener("input",this.boundHandleTextareaChange));const n=this.shadowRoot.querySelector(".nostr-dm-npub-input");n&&n.addEventListener("keydown",a=>{a.key==="Enter"&&this.handleFindClick()})}disconnectedCallback(){var n,a,d;const e=(n=this.shadowRoot)==null?void 0:n.querySelector(".nostr-dm-find-btn");e&&this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind);const t=(a=this.shadowRoot)==null?void 0:a.querySelector(".nostr-dm-send-btn");t&&this.boundHandleSend&&t.removeEventListener("click",this.boundHandleSend);const r=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-dm-textarea");r&&this.boundHandleTextareaChange&&r.removeEventListener("input",this.boundHandleTextareaChange)}render(){l(this,"Rendering with state:",{recipientNpub:this.recipientNpub,recipientPubkey:this.recipientPubkey,message:this.message?"[message content]":"[empty]",isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,isSent:this.isSent});const e={theme:this.theme,recipientNpub:this.recipientNpub,recipientName:this.recipientName,recipientPicture:this.recipientPicture,message:this.message,isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,errorMessage:this.errorMessage,isSent:this.isSent};this.shadowRoot.innerHTML=$(e),this.attachEventListeners()}}customElements.define("nostr-dm",R);
216
+ `}function l(s,o,e){s.getAttribute("debug")==="true"&&(e?console.log(`[NostrDm] ${o}`,e):console.log(`[NostrDm] ${o}`))}class R extends HTMLElement{constructor(){super();i(this,"rendered",!1);i(this,"nostrService",y.getInstance());i(this,"theme","light");i(this,"recipientNpub",null);i(this,"recipientNip05",null);i(this,"recipientName",null);i(this,"recipientPicture",null);i(this,"recipientPubkey",null);i(this,"message","");i(this,"isLoading",!1);i(this,"isFinding",!1);i(this,"isError",!1);i(this,"errorMessage","");i(this,"isSent",!1);i(this,"boundHandleFind",null);i(this,"boundHandleSend",null);i(this,"boundHandleTextareaChange",null);i(this,"getRelays",()=>{const e=this.getAttribute("relays");return e?e.split(","):k});i(this,"getTheme",async()=>{this.theme="light";const e=this.getAttribute("theme");if(e){if(!["light","dark"].includes(e))throw new Error(`Invalid theme '${e}'. Accepted values are 'light', 'dark'`);this.theme=e}});i(this,"getRecipient",()=>{const e=this.getAttribute("nip05");if(e){this.recipientNip05=e,this.lookupRecipientByNip05();return}const t=this.getAttribute("recipient-npub");t&&(this.recipientNpub=t,this.lookupRecipient())});this.attachShadow({mode:"open"})}connectedCallback(){this.rendered||(this.rendered=!0,this.getTheme(),this.getRecipient(),this.nostrService.connectToNostr(this.getRelays()),this.render())}static get observedAttributes(){return["relays","recipient-npub","nip05","theme","debug"]}attributeChangedCallback(e,t,r){e==="relays"&&this.nostrService.connectToNostr(this.getRelays()),e==="theme"&&this.getTheme(),e==="nip05"&&r&&(this.recipientNip05=r,this.lookupRecipientByNip05()),e==="recipient-npub"&&r&&(this.recipientNpub=r,this.lookupRecipient()),this.render()}async lookupRecipient(e){const t=e||this.recipientNpub;if(t){this.isFinding=!0,this.render();try{const n=this.nostrService.getNDK().getUser({npub:t});await n.fetchProfile(),n.profile?(this.recipientName=n.profile.displayName||n.profile.name||"Unknown",this.recipientPicture=n.profile.image||null,this.recipientPubkey=n.pubkey,this.recipientNpub=t):(this.recipientName="Unknown",this.recipientPicture=null,this.recipientPubkey=n.pubkey,this.recipientNpub=t)}catch(r){this.isError=!0,this.errorMessage=`Failed to find recipient: ${r.message}`}finally{this.isFinding=!1,this.render()}}}async lookupRecipientByNip05(e){const t=e||this.recipientNip05;if(t){this.isFinding=!0,this.render();try{const r=await N(t);if(!r)throw new Error("Failed to resolve nip05");const n=w.npubEncode(r);await this.lookupRecipient(n)}catch(r){this.isError=!0,this.errorMessage=`Failed to resolve nip05: ${r.message}`}finally{this.isFinding=!1,this.render()}}}async handleFindClick(){const e=this.shadowRoot.querySelector(".nostr-dm-npub-input");if(!e||!e.value){this.isError=!0,this.errorMessage="Please enter a valid npub",this.render();return}const t=e.value.trim();t.includes("@")?await this.lookupRecipientByNip05(t):await this.lookupRecipient(t)}async handleSendClick(){if(l(this,"Send button clicked!"),!this.recipientPubkey||!this.message.trim()){this.isError=!0,this.errorMessage=this.recipientPubkey?"Please enter a message":"Recipient not found",this.render();return}if(this.isError=!1,this.isSent=!1,this.isLoading=!0,this.render(),!this.nostrService.hasSigner()){this.isError=!0,this.errorMessage="No Nostr signer available. Please ensure your Nostr extension is installed or provide a private key.",this.isLoading=!1,this.render();return}let e=null;if(typeof window<"u"&&window.nostr)e=new F;else if(typeof localStorage<"u"){const t=localStorage.getItem("nostr_nsec");if(t){const{NDKPrivateKeySigner:r}=await m(async()=>{const{NDKPrivateKeySigner:n}=await import("../assets/nostr-service-CnaPxjc6.js").then(a=>a.k);return{NDKPrivateKeySigner:n}},[]);e=new r(t)}}if(!e){this.isError=!0,this.errorMessage="Failed to create signer. Please ensure your Nostr signer (extension or private key) is configured.",this.render();return}this.render();try{const t=this.nostrService.getNDK();t.signer=e;const{nip04:r}=await m(async()=>{const{nip04:d}=await import("../assets/nostr-service-CnaPxjc6.js").then(h=>h.j);return{nip04:d}},[]),n=new S(t,{kind:E.EncryptedDirectMessage,tags:[["p",this.recipientPubkey]],created_at:Math.floor(Date.now()/1e3)});if(typeof window<"u"&&window.nostr){const d=await window.nostr.nip04.encrypt(this.recipientPubkey,this.message.trim());n.content=d}else if(typeof localStorage<"u"){const d=localStorage.getItem("nostr_nsec");if(!d)throw new Error("No private key available");const{nip19:h}=await m(async()=>{const{nip19:c}=await import("../assets/nostr-service-CnaPxjc6.js").then(u=>u.j);return{nip19:c}},[]);let p=d;if(d.startsWith("nsec"))try{p=h.decode(d).data}catch(c){throw console.error("Failed to decode nsec:",c),new Error("Invalid private key format")}try{n.content=await r.encrypt(p,this.recipientPubkey,this.message.trim())}catch(c){throw console.error("Encryption error:",c),new Error(`Encryption failed: ${c.message}`)}}l(this,"Sending encrypted DM:",{to:this.recipientPubkey,encryptedContent:n.content}),await n.publish(),l(this,"DM sent with encrypted content:",n),this.isSent=!0,this.message="";const a=this.shadowRoot.querySelector(".nostr-dm-textarea");a&&(a.value="")}catch(t){this.isError=!0,this.errorMessage=`Failed to send message: ${t.message}`,this.isSent=!1}finally{this.isLoading=!1,this.isFinding=!1,this.render()}}handleTextareaChange(e){const t=e.target;this.message=t.value}attachEventListeners(){const e=this.shadowRoot.querySelector(".nostr-dm-find-btn");e?(this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind),this.boundHandleFind=this.handleFindClick.bind(this),e.addEventListener("click",this.boundHandleFind),l(this,"Find button event listener attached")):l(this,"Find button not found in DOM");const t=this.shadowRoot.querySelector(".nostr-dm-send-btn");t?(l(this,"Send button found, disabled:",t.hasAttribute("disabled")),this.boundHandleSend&&t.removeEventListener("click",this.boundHandleSend),this.boundHandleSend=this.handleSendClick.bind(this),t.addEventListener("click",this.boundHandleSend),this.recipientPubkey&&!this.isLoading&&t.removeAttribute("disabled"),l(this,"Send button event listener attached")):l(this,"Send button not found in DOM");const r=this.shadowRoot.querySelector(".nostr-dm-textarea");r&&(this.boundHandleTextareaChange&&r.removeEventListener("input",this.boundHandleTextareaChange),this.boundHandleTextareaChange=this.handleTextareaChange.bind(this),r.addEventListener("input",this.boundHandleTextareaChange));const n=this.shadowRoot.querySelector(".nostr-dm-npub-input");n&&n.addEventListener("keydown",a=>{a.key==="Enter"&&this.handleFindClick()})}disconnectedCallback(){var n,a,d;const e=(n=this.shadowRoot)==null?void 0:n.querySelector(".nostr-dm-find-btn");e&&this.boundHandleFind&&e.removeEventListener("click",this.boundHandleFind);const t=(a=this.shadowRoot)==null?void 0:a.querySelector(".nostr-dm-send-btn");t&&this.boundHandleSend&&t.removeEventListener("click",this.boundHandleSend);const r=(d=this.shadowRoot)==null?void 0:d.querySelector(".nostr-dm-textarea");r&&this.boundHandleTextareaChange&&r.removeEventListener("input",this.boundHandleTextareaChange)}render(){l(this,"Rendering with state:",{recipientNpub:this.recipientNpub,recipientPubkey:this.recipientPubkey,message:this.message?"[message content]":"[empty]",isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,isSent:this.isSent});const e={theme:this.theme,recipientNpub:this.recipientNpub,recipientName:this.recipientName,recipientPicture:this.recipientPicture,message:this.message,isLoading:this.isLoading,isFinding:this.isFinding,isError:this.isError,errorMessage:this.errorMessage,isSent:this.isSent};this.shadowRoot.innerHTML=$(e),this.attachEventListeners()}}customElements.define("nostr-dm",R);export{R as default};
217
217
  //# sourceMappingURL=nostr-dm.es.js.map
@@ -1,4 +1,4 @@
1
- var v=Object.defineProperty;var w=(n,e,o)=>e in n?v(n,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):n[e]=o;var f=(n,e,o)=>w(n,typeof e!="symbol"?e+"":e,o);import{d as m}from"../assets/nostr-service-pr_crY62.js";import{N as p}from"../assets/nostr-user-component-BOdux8_6.js";import{b as y,g as k,a as b}from"../assets/theme-C1r1Zw8r.js";import{e as c,g as S,a as l}from"../assets/base-styles-CBypR3FR.js";import"../assets/user-resolver-C-E6KdwY.js";import"../assets/icons-Dr_d9MII.js";function C({isLoading:n,isError:e,errorMessage:o,isFollowed:t,isFollowing:r,showAvatar:i=!1,user:s,profile:a,customText:h="Follow me on nostr"}){if(r)return F();if(n)return x();if(e)return N(o||"");const u=t?y("light"):i&&s&&(a!=null&&a.image)?`<img src="${c(a.image)}" alt="${c(a.name||s.npub)}" class="user-avatar" />`:k(),g=t?"Followed":`<span>${c(h)}</span>`;return d(u,g)}function x(){return d(b(),"<span>Loading...</span>")}function F(){return d(b(),"<span>Following...</span>")}function N(n){return d('<div class="error-icon">&#9888;</div>',c(n))}function d(n,e){return`
1
+ var v=Object.defineProperty;var w=(n,e,o)=>e in n?v(n,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):n[e]=o;var f=(n,e,o)=>w(n,typeof e!="symbol"?e+"":e,o);import{N as m}from"../assets/nostr-service-CnaPxjc6.js";import{N as p}from"../assets/nostr-user-component-Cbs97dlK.js";import{g as y,a as k,b}from"../assets/theme-BN1Bvweb.js";import{e as c,g as S,N as l}from"../assets/base-styles-BSEzBDsk.js";import"../assets/user-resolver-CMmbtY9Y.js";import"../assets/icons-Dr_d9MII.js";function C({isLoading:n,isError:e,errorMessage:o,isFollowed:t,isFollowing:r,showAvatar:i=!1,user:s,profile:a,customText:h="Follow me on nostr"}){if(r)return F();if(n)return x();if(e)return N(o||"");const u=t?y("light"):i&&s&&(a!=null&&a.image)?`<img src="${c(a.image)}" alt="${c(a.name||s.npub)}" class="user-avatar" />`:k(),g=t?"Followed":`<span>${c(h)}</span>`;return d(u,g)}function x(){return d(b(),"<span>Loading...</span>")}function F(){return d(b(),"<span>Following...</span>")}function N(n){return d('<div class="error-icon">&#9888;</div>',c(n))}function d(n,e){return`
2
2
  <div class='nostr-follow-button-container'>
3
3
  <div class='nostr-follow-button-left-container'>
4
4
  ${n}
@@ -99,5 +99,5 @@ var v=Object.defineProperty;var w=(n,e,o)=>e in n?v(n,e,{enumerable:!0,configura
99
99
  Please checkout the following video to setup a signer extension - <a href="https://youtu.be/8thRYn14nB0?t=310" target="_blank">Video</a>`:s="Please authorize, click the button to try again!",this.followStatus.set(l.Error,s)}finally{this.render()}}attachDelegatedListeners(){this.delegateEvent("click",".nostr-follow-button-container",o=>{var t,r;(t=o.preventDefault)==null||t.call(o),(r=o.stopPropagation)==null||r.call(o),this.handleFollowClick()})}renderContent(){const o=this.computeOverall()==l.Loading,t=this.followStatus.get()==l.Loading,r=this.computeOverall()===l.Error,i=super.renderError(this.errorMessage),s=this.hasAttribute("show-avatar"),a=this.getAttribute("text")||"Follow me on nostr",h={isLoading:o,isError:r,errorMessage:i,isFollowed:this.isFollowed,isFollowing:t,showAvatar:s,user:this.user,profile:this.profile,customText:a};this.shadowRoot.innerHTML=`
100
100
  ${L()}
101
101
  ${C(h)}
102
- `}}customElements.define("nostr-follow-button",E);
102
+ `}}customElements.define("nostr-follow-button",E);export{E as default};
103
103
  //# sourceMappingURL=nostr-follow-button.es.js.map