@welshman/util 0.0.1

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 (57) hide show
  1. package/README.md +14 -0
  2. package/build/Address.cjs +44 -0
  3. package/build/Address.cjs.map +1 -0
  4. package/build/Address.d.ts +21 -0
  5. package/build/Address.mjs +32 -0
  6. package/build/Address.mjs.map +1 -0
  7. package/build/Events.cjs +58 -0
  8. package/build/Events.cjs.map +1 -0
  9. package/build/Events.d.ts +34 -0
  10. package/build/Events.mjs +42 -0
  11. package/build/Events.mjs.map +1 -0
  12. package/build/Filters.cjs +139 -0
  13. package/build/Filters.cjs.map +1 -0
  14. package/build/Filters.d.ts +39 -0
  15. package/build/Filters.mjs +127 -0
  16. package/build/Filters.mjs.map +1 -0
  17. package/build/Kinds.cjs +83 -0
  18. package/build/Kinds.cjs.map +1 -0
  19. package/build/Kinds.d.ts +77 -0
  20. package/build/Kinds.mjs +78 -0
  21. package/build/Kinds.mjs.map +1 -0
  22. package/build/Links.cjs +8 -0
  23. package/build/Links.cjs.map +1 -0
  24. package/build/Links.d.ts +2 -0
  25. package/build/Links.mjs +3 -0
  26. package/build/Links.mjs.map +1 -0
  27. package/build/Relay.cjs +148 -0
  28. package/build/Relay.cjs.map +1 -0
  29. package/build/Relay.d.ts +23 -0
  30. package/build/Relay.mjs +144 -0
  31. package/build/Relay.mjs.map +1 -0
  32. package/build/Relays.cjs +36 -0
  33. package/build/Relays.cjs.map +1 -0
  34. package/build/Relays.d.ts +6 -0
  35. package/build/Relays.mjs +31 -0
  36. package/build/Relays.mjs.map +1 -0
  37. package/build/Router.cjs +205 -0
  38. package/build/Router.cjs.map +1 -0
  39. package/build/Router.d.ts +128 -0
  40. package/build/Router.mjs +200 -0
  41. package/build/Router.mjs.map +1 -0
  42. package/build/Tags.cjs +149 -0
  43. package/build/Tags.cjs.map +1 -0
  44. package/build/Tags.d.ts +77 -0
  45. package/build/Tags.mjs +144 -0
  46. package/build/Tags.mjs.map +1 -0
  47. package/build/Zaps.cjs +96 -0
  48. package/build/Zaps.cjs.map +1 -0
  49. package/build/Zaps.d.ts +19 -0
  50. package/build/Zaps.mjs +89 -0
  51. package/build/Zaps.mjs.map +1 -0
  52. package/build/index.cjs +27 -0
  53. package/build/index.cjs.map +1 -0
  54. package/build/index.d.ts +10 -0
  55. package/build/index.mjs +11 -0
  56. package/build/index.mjs.map +1 -0
  57. package/package.json +38 -0
package/README.md ADDED
@@ -0,0 +1,14 @@
1
+ # @welshman/util [![version](https://badgen.net/npm/v/@welshman/util)](https://npmjs.com/package/@welshman/util)
2
+
3
+ Some nostr-specific utilities. For the most part, these will not have side effects or manage state.
4
+
5
+ - `Address` utilities for dealing with nostr addresses.
6
+ - `Events` utilities for dealing with nostr events.
7
+ - `Filters` utilities for dealing with nostr filters.
8
+ - `Kinds` kind constants and related utility functions.
9
+ - `Links` utilities for encoding and decoding nostr links.
10
+ - `Relay` an implementation of an in-memory nostr relay.
11
+ - `Relays` utilities related to relay urls.
12
+ - `Router` is a utility for selecting relay urls based on user preferences and protocol hints.
13
+ - `Tags` convenient way to access and modify tags.
14
+ - `Zaps` utilities related to zaps.
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isContextAddress = exports.isCommunityAddress = exports.isGroupAddress = exports.addressFromEvent = exports.getIdentifier = exports.addressToNaddr = exports.addressFromNaddr = exports.encodeAddress = exports.decodeAddress = void 0;
4
+ const nostr_tools_1 = require("nostr-tools");
5
+ const Kinds_1 = require("./Kinds.cjs");
6
+ // Plain text format
7
+ const decodeAddress = (a, relays = []) => {
8
+ const [kind, pubkey, identifier = ""] = a.split(":");
9
+ return { kind: parseInt(kind), pubkey, identifier, relays };
10
+ };
11
+ exports.decodeAddress = decodeAddress;
12
+ const encodeAddress = (a) => [a.kind, a.pubkey, a.identifier].join(":");
13
+ exports.encodeAddress = encodeAddress;
14
+ // Naddr encoding
15
+ const addressFromNaddr = (naddr) => {
16
+ let type;
17
+ let data = {};
18
+ try {
19
+ ({ type, data } = nostr_tools_1.nip19.decode(naddr));
20
+ }
21
+ catch (e) {
22
+ // pass
23
+ }
24
+ if (type !== "naddr") {
25
+ throw new Error(`Invalid naddr ${naddr}`);
26
+ }
27
+ return data;
28
+ };
29
+ exports.addressFromNaddr = addressFromNaddr;
30
+ const addressToNaddr = (a) => nostr_tools_1.nip19.naddrEncode(a);
31
+ exports.addressToNaddr = addressToNaddr;
32
+ // Get from event, encode to filter
33
+ const getIdentifier = (e) => { var _a; return ((_a = e.tags.find(t => t[0] === "d")) === null || _a === void 0 ? void 0 : _a[1]) || ""; };
34
+ exports.getIdentifier = getIdentifier;
35
+ const addressFromEvent = (e, relays = []) => ({ kind: e.kind, pubkey: e.pubkey, identifier: (0, exports.getIdentifier)(e), relays });
36
+ exports.addressFromEvent = addressFromEvent;
37
+ // Utils
38
+ const isGroupAddress = (a) => a.kind === Kinds_1.GROUP_DEFINITION;
39
+ exports.isGroupAddress = isGroupAddress;
40
+ const isCommunityAddress = (a) => a.kind === Kinds_1.COMMUNITY_DEFINITION;
41
+ exports.isCommunityAddress = isCommunityAddress;
42
+ const isContextAddress = (a) => [Kinds_1.GROUP_DEFINITION, Kinds_1.COMMUNITY_DEFINITION].includes(a.kind);
43
+ exports.isContextAddress = isContextAddress;
44
+ //# sourceMappingURL=Address.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Address.cjs","sourceRoot":"","sources":["../Address.ts"],"names":[],"mappings":";;;AACA,6CAAiC;AACjC,uCAA8D;AAS9D,oBAAoB;AAEb,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,SAAmB,EAAE,EAAW,EAAE;IACzE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEpD,OAAO,EAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAC,CAAA;AAC3D,CAAC,CAAA;AAJY,QAAA,aAAa,iBAIzB;AAEM,MAAM,aAAa,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAA1E,QAAA,aAAa,iBAA6D;AAEvF,iBAAiB;AAEV,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAW,EAAE;IACzD,IAAI,IAAI,CAAA;IACR,IAAI,IAAI,GAAG,EAAS,CAAA;IACpB,IAAI;QACF,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,GAAG,mBAAK,CAAC,MAAM,CAAC,KAAK,CAGjC,CAAC,CAAA;KACH;IAAC,OAAO,CAAC,EAAE;QACV,OAAO;KACR;IAED,IAAI,IAAI,KAAK,OAAO,EAAE;QACpB,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAA;KAC1C;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAjBY,QAAA,gBAAgB,oBAiB5B;AAEM,MAAM,cAAc,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,mBAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AAA7D,QAAA,cAAc,kBAA+C;AAE1E,mCAAmC;AAE5B,MAAM,aAAa,GAAG,CAAC,CAAgB,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,0CAAG,CAAC,CAAC,KAAI,EAAE,CAAA,EAAA,CAAA;AAA/E,QAAA,aAAa,iBAAkE;AAErF,MAAM,gBAAgB,GAAG,CAAC,CAAgB,EAAE,SAAmB,EAAE,EAAE,EAAE,CAC1E,CAAC,EAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,IAAA,qBAAa,EAAC,CAAC,CAAC,EAAE,MAAM,EAAC,CAAC,CAAA;AAD7D,QAAA,gBAAgB,oBAC6C;AAE1E,QAAQ;AAED,MAAM,cAAc,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,wBAAgB,CAAA;AAA5D,QAAA,cAAc,kBAA8C;AAElE,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,4BAAoB,CAAA;AAApE,QAAA,kBAAkB,sBAAkD;AAE1E,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,wBAAgB,EAAE,4BAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAA5F,QAAA,gBAAgB,oBAA4E"}
@@ -0,0 +1,21 @@
1
+ import type { UnsignedEvent } from 'nostr-tools';
2
+ export type Address = {
3
+ kind: number;
4
+ pubkey: string;
5
+ identifier: string;
6
+ relays: string[];
7
+ };
8
+ export declare const decodeAddress: (a: string, relays?: string[]) => Address;
9
+ export declare const encodeAddress: (a: Address) => string;
10
+ export declare const addressFromNaddr: (naddr: string) => Address;
11
+ export declare const addressToNaddr: (a: Address) => string;
12
+ export declare const getIdentifier: (e: UnsignedEvent) => string;
13
+ export declare const addressFromEvent: (e: UnsignedEvent, relays?: string[]) => {
14
+ kind: number;
15
+ pubkey: string;
16
+ identifier: string;
17
+ relays: string[];
18
+ };
19
+ export declare const isGroupAddress: (a: Address) => boolean;
20
+ export declare const isCommunityAddress: (a: Address) => boolean;
21
+ export declare const isContextAddress: (a: Address) => boolean;
@@ -0,0 +1,32 @@
1
+ import { nip19 } from 'nostr-tools';
2
+ import { GROUP_DEFINITION, COMMUNITY_DEFINITION } from "./Kinds.mjs";
3
+ // Plain text format
4
+ export const decodeAddress = (a, relays = []) => {
5
+ const [kind, pubkey, identifier = ""] = a.split(":");
6
+ return { kind: parseInt(kind), pubkey, identifier, relays };
7
+ };
8
+ export const encodeAddress = (a) => [a.kind, a.pubkey, a.identifier].join(":");
9
+ // Naddr encoding
10
+ export const addressFromNaddr = (naddr) => {
11
+ let type;
12
+ let data = {};
13
+ try {
14
+ ({ type, data } = nip19.decode(naddr));
15
+ }
16
+ catch (e) {
17
+ // pass
18
+ }
19
+ if (type !== "naddr") {
20
+ throw new Error(`Invalid naddr ${naddr}`);
21
+ }
22
+ return data;
23
+ };
24
+ export const addressToNaddr = (a) => nip19.naddrEncode(a);
25
+ // Get from event, encode to filter
26
+ export const getIdentifier = (e) => { var _a; return ((_a = e.tags.find(t => t[0] === "d")) === null || _a === void 0 ? void 0 : _a[1]) || ""; };
27
+ export const addressFromEvent = (e, relays = []) => ({ kind: e.kind, pubkey: e.pubkey, identifier: getIdentifier(e), relays });
28
+ // Utils
29
+ export const isGroupAddress = (a) => a.kind === GROUP_DEFINITION;
30
+ export const isCommunityAddress = (a) => a.kind === COMMUNITY_DEFINITION;
31
+ export const isContextAddress = (a) => [GROUP_DEFINITION, COMMUNITY_DEFINITION].includes(a.kind);
32
+ //# sourceMappingURL=Address.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Address.mjs","sourceRoot":"","sources":["../Address.ts"],"names":[],"mappings":"OACO,EAAC,KAAK,EAAC,MAAM,aAAa;OAC1B,EAAC,gBAAgB,EAAE,oBAAoB,EAAC;AAS/C,oBAAoB;AAEpB,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAS,EAAE,SAAmB,EAAE,EAAW,EAAE;IACzE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAEpD,OAAO,EAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAC,CAAA;AAC3D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAEvF,iBAAiB;AAEjB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAW,EAAE;IACzD,IAAI,IAAI,CAAA;IACR,IAAI,IAAI,GAAG,EAAS,CAAA;IACpB,IAAI;QACF,CAAC,EAAC,IAAI,EAAE,IAAI,EAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAGjC,CAAC,CAAA;KACH;IAAC,OAAO,CAAC,EAAE;QACV,OAAO;KACR;IAED,IAAI,IAAI,KAAK,OAAO,EAAE;QACpB,MAAM,IAAI,KAAK,CAAC,iBAAiB,KAAK,EAAE,CAAC,CAAA;KAC1C;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;AAE1E,mCAAmC;AAEnC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAgB,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,0CAAG,CAAC,CAAC,KAAI,EAAE,CAAA,EAAA,CAAA;AAE5F,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAgB,EAAE,SAAmB,EAAE,EAAE,EAAE,CAC1E,CAAC,EAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAC,CAAC,CAAA;AAE1E,QAAQ;AAER,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAA;AAEzE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,oBAAoB,CAAA;AAEjF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAU,EAAE,EAAE,CAAC,CAAC,gBAAgB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA"}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isChildOf = exports.isParameterizedReplaceable = exports.isPlainReplaceable = exports.isReplaceable = exports.isEphemeral = exports.getIdAndAddress = exports.getIdOrAddress = exports.getAddress = exports.hasValidSignature = exports.asEvent = exports.asRumor = exports.asUnsignedEvent = exports.asEventTemplate = exports.createEvent = void 0;
4
+ const nostr_tools_1 = require("nostr-tools");
5
+ const lib_1 = require("@welshman/lib");
6
+ const Tags_1 = require("./Tags.cjs");
7
+ const Address_1 = require("./Address.cjs");
8
+ const Kinds_1 = require("./Kinds.cjs");
9
+ const createEvent = (kind, { content = "", tags = [], created_at = (0, lib_1.now)() }) => ({ kind, content, tags, created_at });
10
+ exports.createEvent = createEvent;
11
+ const asEventTemplate = ({ kind, tags, content, created_at }) => ({ kind, tags, content, created_at });
12
+ exports.asEventTemplate = asEventTemplate;
13
+ const asUnsignedEvent = ({ kind, tags, content, created_at, pubkey }) => ({ kind, tags, content, created_at, pubkey });
14
+ exports.asUnsignedEvent = asUnsignedEvent;
15
+ const asRumor = ({ kind, tags, content, created_at, pubkey, id }) => ({ kind, tags, content, created_at, pubkey, id });
16
+ exports.asRumor = asRumor;
17
+ const asEvent = ({ kind, tags, content, created_at, pubkey, id, sig }) => ({ kind, tags, content, created_at, pubkey, id, sig });
18
+ exports.asEvent = asEvent;
19
+ exports.hasValidSignature = (0, lib_1.cached)({
20
+ maxSize: 10000,
21
+ getKey: ([e]) => {
22
+ try {
23
+ return [(0, nostr_tools_1.getEventHash)(e), e.sig].join(":");
24
+ }
25
+ catch (err) {
26
+ return 'invalid';
27
+ }
28
+ },
29
+ getValue: ([e]) => {
30
+ try {
31
+ return (0, nostr_tools_1.verifyEvent)(e);
32
+ }
33
+ catch (err) {
34
+ return false;
35
+ }
36
+ },
37
+ });
38
+ const getAddress = (e) => (0, Address_1.encodeAddress)((0, Address_1.addressFromEvent)(e));
39
+ exports.getAddress = getAddress;
40
+ const getIdOrAddress = (e) => (0, exports.isReplaceable)(e) ? (0, exports.getAddress)(e) : e.id;
41
+ exports.getIdOrAddress = getIdOrAddress;
42
+ const getIdAndAddress = (e) => (0, exports.isReplaceable)(e) ? [e.id, (0, exports.getAddress)(e)] : [e.id];
43
+ exports.getIdAndAddress = getIdAndAddress;
44
+ const isEphemeral = (e) => (0, Kinds_1.isEphemeralKind)(e.kind);
45
+ exports.isEphemeral = isEphemeral;
46
+ const isReplaceable = (e) => (0, Kinds_1.isReplaceableKind)(e.kind);
47
+ exports.isReplaceable = isReplaceable;
48
+ const isPlainReplaceable = (e) => (0, Kinds_1.isPlainReplaceableKind)(e.kind);
49
+ exports.isPlainReplaceable = isPlainReplaceable;
50
+ const isParameterizedReplaceable = (e) => (0, Kinds_1.isParameterizedReplaceableKind)(e.kind);
51
+ exports.isParameterizedReplaceable = isParameterizedReplaceable;
52
+ const isChildOf = (child, parent) => {
53
+ const { roots, replies } = Tags_1.Tags.fromEvent(child).ancestors();
54
+ const parentIds = (replies.exists() ? replies : roots).values().valueOf();
55
+ return (0, exports.getIdAndAddress)(parent).some(x => parentIds.includes(x));
56
+ };
57
+ exports.isChildOf = isChildOf;
58
+ //# sourceMappingURL=Events.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Events.cjs","sourceRoot":"","sources":["../Events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import type { Event, EventTemplate, UnsignedEvent } from 'nostr-tools';
2
+ export type { Event, EventTemplate, UnsignedEvent } from 'nostr-tools';
3
+ export type Rumor = Pick<Event, 'kind' | 'tags' | 'content' | 'created_at' | 'pubkey' | 'id'> & {
4
+ wrap?: Event;
5
+ };
6
+ export type CreateEventOpts = {
7
+ content?: string;
8
+ tags?: string[][];
9
+ created_at?: number;
10
+ };
11
+ export declare const createEvent: (kind: number, { content, tags, created_at }: CreateEventOpts) => {
12
+ kind: number;
13
+ content: string;
14
+ tags: string[][];
15
+ created_at: number;
16
+ };
17
+ export declare const asEventTemplate: ({ kind, tags, content, created_at }: EventTemplate) => EventTemplate;
18
+ export declare const asUnsignedEvent: ({ kind, tags, content, created_at, pubkey }: UnsignedEvent) => UnsignedEvent;
19
+ export declare const asRumor: ({ kind, tags, content, created_at, pubkey, id }: Rumor) => Rumor;
20
+ export declare const asEvent: ({ kind, tags, content, created_at, pubkey, id, sig }: Event) => Event;
21
+ export declare const hasValidSignature: {
22
+ (args_0: Event): boolean;
23
+ cache: import("@welshman/lib").LRUCache<string, boolean>;
24
+ getKey: (args: [Event]) => string;
25
+ getValue: (args: [Event]) => boolean;
26
+ };
27
+ export declare const getAddress: (e: UnsignedEvent) => string;
28
+ export declare const getIdOrAddress: (e: Rumor) => string;
29
+ export declare const getIdAndAddress: (e: Rumor) => string[];
30
+ export declare const isEphemeral: (e: EventTemplate) => boolean;
31
+ export declare const isReplaceable: (e: EventTemplate) => boolean;
32
+ export declare const isPlainReplaceable: (e: EventTemplate) => boolean;
33
+ export declare const isParameterizedReplaceable: (e: EventTemplate) => boolean;
34
+ export declare const isChildOf: (child: EventTemplate, parent: Rumor) => boolean;
@@ -0,0 +1,42 @@
1
+ import { verifyEvent, getEventHash } from 'nostr-tools';
2
+ import { cached, now } from '@welshman/lib';
3
+ import { Tags } from "./Tags.mjs";
4
+ import { addressFromEvent, encodeAddress } from "./Address.mjs";
5
+ import { isEphemeralKind, isReplaceableKind, isPlainReplaceableKind, isParameterizedReplaceableKind } from "./Kinds.mjs";
6
+ export const createEvent = (kind, { content = "", tags = [], created_at = now() }) => ({ kind, content, tags, created_at });
7
+ export const asEventTemplate = ({ kind, tags, content, created_at }) => ({ kind, tags, content, created_at });
8
+ export const asUnsignedEvent = ({ kind, tags, content, created_at, pubkey }) => ({ kind, tags, content, created_at, pubkey });
9
+ export const asRumor = ({ kind, tags, content, created_at, pubkey, id }) => ({ kind, tags, content, created_at, pubkey, id });
10
+ export const asEvent = ({ kind, tags, content, created_at, pubkey, id, sig }) => ({ kind, tags, content, created_at, pubkey, id, sig });
11
+ export const hasValidSignature = cached({
12
+ maxSize: 10000,
13
+ getKey: ([e]) => {
14
+ try {
15
+ return [getEventHash(e), e.sig].join(":");
16
+ }
17
+ catch (err) {
18
+ return 'invalid';
19
+ }
20
+ },
21
+ getValue: ([e]) => {
22
+ try {
23
+ return verifyEvent(e);
24
+ }
25
+ catch (err) {
26
+ return false;
27
+ }
28
+ },
29
+ });
30
+ export const getAddress = (e) => encodeAddress(addressFromEvent(e));
31
+ export const getIdOrAddress = (e) => isReplaceable(e) ? getAddress(e) : e.id;
32
+ export const getIdAndAddress = (e) => isReplaceable(e) ? [e.id, getAddress(e)] : [e.id];
33
+ export const isEphemeral = (e) => isEphemeralKind(e.kind);
34
+ export const isReplaceable = (e) => isReplaceableKind(e.kind);
35
+ export const isPlainReplaceable = (e) => isPlainReplaceableKind(e.kind);
36
+ export const isParameterizedReplaceable = (e) => isParameterizedReplaceableKind(e.kind);
37
+ export const isChildOf = (child, parent) => {
38
+ const { roots, replies } = Tags.fromEvent(child).ancestors();
39
+ const parentIds = (replies.exists() ? replies : roots).values().valueOf();
40
+ return getIdAndAddress(parent).some(x => parentIds.includes(x));
41
+ };
42
+ //# sourceMappingURL=Events.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Events.mjs","sourceRoot":"","sources":["../Events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.guessFilterDelta = exports.getFilterGenerality = exports.getReplyFilters = exports.getIdFilters = exports.mergeFilters = exports.calculateFilterGroup = exports.getFilterId = exports.matchFilters = exports.matchFilter = exports.EPOCH = void 0;
4
+ const nostr_tools_1 = require("nostr-tools");
5
+ const lib_1 = require("@welshman/lib");
6
+ const Address_1 = require("./Address.cjs");
7
+ const Kinds_1 = require("./Kinds.cjs");
8
+ exports.EPOCH = 1609459200;
9
+ const matchFilter = (filter, event) => {
10
+ if (!(0, nostr_tools_1.matchFilter)(filter, event)) {
11
+ return false;
12
+ }
13
+ if (filter.search) {
14
+ const content = event.content.toLowerCase();
15
+ const terms = filter.search.toLowerCase().split(/\s+/g);
16
+ for (const term of terms) {
17
+ if (content.includes(term)) {
18
+ return true;
19
+ }
20
+ return false;
21
+ }
22
+ }
23
+ return true;
24
+ };
25
+ exports.matchFilter = matchFilter;
26
+ const matchFilters = (filters, event) => {
27
+ for (const filter of filters) {
28
+ if ((0, exports.matchFilter)(filter, event)) {
29
+ return true;
30
+ }
31
+ }
32
+ return false;
33
+ };
34
+ exports.matchFilters = matchFilters;
35
+ const getFilterId = (filter) => {
36
+ const keys = Object.keys(filter);
37
+ keys.sort();
38
+ const parts = [];
39
+ for (const k of keys) {
40
+ const v = filter[k];
41
+ const s = Array.isArray(v) ? v.join(',') : v;
42
+ parts.push([k, s].join(':'));
43
+ }
44
+ return (0, lib_1.hash)(parts.join('|'));
45
+ };
46
+ exports.getFilterId = getFilterId;
47
+ const calculateFilterGroup = ({ since, until, limit, search, ...filter }) => {
48
+ const group = Object.keys(filter);
49
+ if (since)
50
+ group.push(`since:${since}`);
51
+ if (until)
52
+ group.push(`until:${until}`);
53
+ if (limit)
54
+ group.push(`limit:${(0, lib_1.randomId)()}`);
55
+ if (search)
56
+ group.push(`search:${search}`);
57
+ return group.sort().join("-");
58
+ };
59
+ exports.calculateFilterGroup = calculateFilterGroup;
60
+ const mergeFilters = (filters) => {
61
+ const result = [];
62
+ for (const group of Object.values((0, lib_1.groupBy)(exports.calculateFilterGroup, filters))) {
63
+ const newFilter = {};
64
+ for (const k of Object.keys(group[0])) {
65
+ if (["since", "until", "limit", "search"].includes(k)) {
66
+ newFilter[k] = group[0][k];
67
+ }
68
+ else {
69
+ newFilter[k] = (0, lib_1.uniq)(group.flatMap((0, lib_1.prop)(k)));
70
+ }
71
+ }
72
+ result.push(newFilter);
73
+ }
74
+ return result;
75
+ };
76
+ exports.mergeFilters = mergeFilters;
77
+ const getIdFilters = (idsOrAddresses) => {
78
+ const ids = [];
79
+ const aFilters = [];
80
+ for (const idOrAddress of idsOrAddresses) {
81
+ if (idOrAddress.includes(":")) {
82
+ const { kind, pubkey, identifier } = (0, Address_1.decodeAddress)(idOrAddress);
83
+ if (identifier) {
84
+ aFilters.push({ kinds: [kind], authors: [pubkey], "#d": [identifier] });
85
+ }
86
+ else {
87
+ aFilters.push({ kinds: [kind], authors: [pubkey] });
88
+ }
89
+ }
90
+ else {
91
+ ids.push(idOrAddress);
92
+ }
93
+ }
94
+ const filters = (0, exports.mergeFilters)(aFilters);
95
+ if (ids.length > 0) {
96
+ filters.push({ ids });
97
+ }
98
+ return filters;
99
+ };
100
+ exports.getIdFilters = getIdFilters;
101
+ const getReplyFilters = (events, filter) => {
102
+ const a = [];
103
+ const e = [];
104
+ for (const event of events) {
105
+ e.push(event.id);
106
+ if ((0, Kinds_1.isReplaceableKind)(event.kind)) {
107
+ a.push((0, Address_1.encodeAddress)((0, Address_1.addressFromEvent)(event)));
108
+ }
109
+ if (event.wrap) {
110
+ e.push(event.wrap.id);
111
+ }
112
+ }
113
+ const filters = [];
114
+ if (a.length > 0) {
115
+ filters.push({ ...filter, "#a": a });
116
+ }
117
+ if (e.length > 0) {
118
+ filters.push({ ...filter, "#e": e });
119
+ }
120
+ return filters;
121
+ };
122
+ exports.getReplyFilters = getReplyFilters;
123
+ const getFilterGenerality = (filter) => {
124
+ if (filter.ids || filter["#e"] || filter["#a"]) {
125
+ return 0;
126
+ }
127
+ const hasTags = Object.keys(filter).find((k) => k.startsWith("#"));
128
+ if (filter.authors && hasTags) {
129
+ return 0.2;
130
+ }
131
+ if (filter.authors) {
132
+ return Math.min(1, filter.authors.length / 100);
133
+ }
134
+ return 1;
135
+ };
136
+ exports.getFilterGenerality = getFilterGenerality;
137
+ const guessFilterDelta = (filters, max = 60 * 60 * 24 * 7) => Math.round(max * Math.max(0.005, 1 - (0, lib_1.avg)(filters.map(exports.getFilterGenerality))));
138
+ exports.guessFilterDelta = guessFilterDelta;
139
+ //# sourceMappingURL=Filters.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filters.cjs","sourceRoot":"","sources":["../Filters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { Rumor } from './Events';
2
+ export declare const EPOCH = 1609459200;
3
+ export type Filter = {
4
+ ids?: string[];
5
+ kinds?: number[];
6
+ authors?: string[];
7
+ since?: number;
8
+ until?: number;
9
+ limit?: number;
10
+ search?: string;
11
+ [key: `#${string}`]: string[];
12
+ };
13
+ export declare const matchFilter: <E extends Rumor>(filter: Filter, event: E) => boolean;
14
+ export declare const matchFilters: <E extends Rumor>(filters: Filter[], event: E) => boolean;
15
+ export declare const getFilterId: (filter: Filter) => string;
16
+ export declare const calculateFilterGroup: ({ since, until, limit, search, ...filter }: Filter) => string;
17
+ export declare const mergeFilters: (filters: Filter[]) => Filter[];
18
+ export declare const getIdFilters: (idsOrAddresses: Iterable<string>) => Filter[];
19
+ export declare const getReplyFilters: (events: Rumor[], filter: Filter) => ({
20
+ "#a": string[];
21
+ ids?: string[] | undefined;
22
+ kinds?: number[] | undefined;
23
+ authors?: string[] | undefined;
24
+ since?: number | undefined;
25
+ until?: number | undefined;
26
+ limit?: number | undefined;
27
+ search?: string | undefined;
28
+ } | {
29
+ "#e": string[];
30
+ ids?: string[] | undefined;
31
+ kinds?: number[] | undefined;
32
+ authors?: string[] | undefined;
33
+ since?: number | undefined;
34
+ until?: number | undefined;
35
+ limit?: number | undefined;
36
+ search?: string | undefined;
37
+ })[];
38
+ export declare const getFilterGenerality: (filter: Filter) => number;
39
+ export declare const guessFilterDelta: (filters: Filter[], max?: number) => number;
@@ -0,0 +1,127 @@
1
+ import { matchFilter as nostrToolsMatchFilter } from 'nostr-tools';
2
+ import { prop, avg, hash, groupBy, randomId, uniq } from '@welshman/lib';
3
+ import { decodeAddress, addressFromEvent, encodeAddress } from "./Address.mjs";
4
+ import { isReplaceableKind } from "./Kinds.mjs";
5
+ export const EPOCH = 1609459200;
6
+ export const matchFilter = (filter, event) => {
7
+ if (!nostrToolsMatchFilter(filter, event)) {
8
+ return false;
9
+ }
10
+ if (filter.search) {
11
+ const content = event.content.toLowerCase();
12
+ const terms = filter.search.toLowerCase().split(/\s+/g);
13
+ for (const term of terms) {
14
+ if (content.includes(term)) {
15
+ return true;
16
+ }
17
+ return false;
18
+ }
19
+ }
20
+ return true;
21
+ };
22
+ export const matchFilters = (filters, event) => {
23
+ for (const filter of filters) {
24
+ if (matchFilter(filter, event)) {
25
+ return true;
26
+ }
27
+ }
28
+ return false;
29
+ };
30
+ export const getFilterId = (filter) => {
31
+ const keys = Object.keys(filter);
32
+ keys.sort();
33
+ const parts = [];
34
+ for (const k of keys) {
35
+ const v = filter[k];
36
+ const s = Array.isArray(v) ? v.join(',') : v;
37
+ parts.push([k, s].join(':'));
38
+ }
39
+ return hash(parts.join('|'));
40
+ };
41
+ export const calculateFilterGroup = ({ since, until, limit, search, ...filter }) => {
42
+ const group = Object.keys(filter);
43
+ if (since)
44
+ group.push(`since:${since}`);
45
+ if (until)
46
+ group.push(`until:${until}`);
47
+ if (limit)
48
+ group.push(`limit:${randomId()}`);
49
+ if (search)
50
+ group.push(`search:${search}`);
51
+ return group.sort().join("-");
52
+ };
53
+ export const mergeFilters = (filters) => {
54
+ const result = [];
55
+ for (const group of Object.values(groupBy(calculateFilterGroup, filters))) {
56
+ const newFilter = {};
57
+ for (const k of Object.keys(group[0])) {
58
+ if (["since", "until", "limit", "search"].includes(k)) {
59
+ newFilter[k] = group[0][k];
60
+ }
61
+ else {
62
+ newFilter[k] = uniq(group.flatMap(prop(k)));
63
+ }
64
+ }
65
+ result.push(newFilter);
66
+ }
67
+ return result;
68
+ };
69
+ export const getIdFilters = (idsOrAddresses) => {
70
+ const ids = [];
71
+ const aFilters = [];
72
+ for (const idOrAddress of idsOrAddresses) {
73
+ if (idOrAddress.includes(":")) {
74
+ const { kind, pubkey, identifier } = decodeAddress(idOrAddress);
75
+ if (identifier) {
76
+ aFilters.push({ kinds: [kind], authors: [pubkey], "#d": [identifier] });
77
+ }
78
+ else {
79
+ aFilters.push({ kinds: [kind], authors: [pubkey] });
80
+ }
81
+ }
82
+ else {
83
+ ids.push(idOrAddress);
84
+ }
85
+ }
86
+ const filters = mergeFilters(aFilters);
87
+ if (ids.length > 0) {
88
+ filters.push({ ids });
89
+ }
90
+ return filters;
91
+ };
92
+ export const getReplyFilters = (events, filter) => {
93
+ const a = [];
94
+ const e = [];
95
+ for (const event of events) {
96
+ e.push(event.id);
97
+ if (isReplaceableKind(event.kind)) {
98
+ a.push(encodeAddress(addressFromEvent(event)));
99
+ }
100
+ if (event.wrap) {
101
+ e.push(event.wrap.id);
102
+ }
103
+ }
104
+ const filters = [];
105
+ if (a.length > 0) {
106
+ filters.push({ ...filter, "#a": a });
107
+ }
108
+ if (e.length > 0) {
109
+ filters.push({ ...filter, "#e": e });
110
+ }
111
+ return filters;
112
+ };
113
+ export const getFilterGenerality = (filter) => {
114
+ if (filter.ids || filter["#e"] || filter["#a"]) {
115
+ return 0;
116
+ }
117
+ const hasTags = Object.keys(filter).find((k) => k.startsWith("#"));
118
+ if (filter.authors && hasTags) {
119
+ return 0.2;
120
+ }
121
+ if (filter.authors) {
122
+ return Math.min(1, filter.authors.length / 100);
123
+ }
124
+ return 1;
125
+ };
126
+ export const guessFilterDelta = (filters, max = 60 * 60 * 24 * 7) => Math.round(max * Math.max(0.005, 1 - avg(filters.map(getFilterGenerality))));
127
+ //# sourceMappingURL=Filters.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Filters.mjs","sourceRoot":"","sources":["../Filters.ts"],"names":[],"mappings":"OACO,EAAC,WAAW,IAAI,qBAAqB,EAAC,MAAM,aAAa;OACzD,EAAC,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAC,MAAM,eAAe;OAE/D,EAAC,aAAa,EAAE,gBAAgB,EAAE,aAAa,EAAC;OAChD,EAAC,iBAAiB,EAAC;AAE1B,MAAM,CAAC,MAAM,KAAK,GAAG,UAAU,CAAA;AAa/B,MAAM,CAAC,MAAM,WAAW,GAAG,CAAkB,MAAc,EAAE,KAAQ,EAAE,EAAE;IACvE,IAAI,CAAC,qBAAqB,CAAC,MAAM,EAAE,KAAyB,CAAC,EAAE;QAC7D,OAAO,KAAK,CAAA;KACb;IAED,IAAI,MAAM,CAAC,MAAM,EAAE;QACjB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAA;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAEvD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;YACxB,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;gBAC1B,OAAO,IAAI,CAAA;aACZ;YAED,OAAO,KAAK,CAAA;SACb;KACF;IAED,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAkB,OAAiB,EAAE,KAAQ,EAAE,EAAE;IAC3E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,IAAI,WAAW,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE;YAC9B,OAAO,IAAI,CAAA;SACZ;KACF;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAc,EAAE,EAAE;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEhC,IAAI,CAAC,IAAI,EAAE,CAAA;IAEX,MAAM,KAAK,GAAG,EAAE,CAAA;IAChB,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;QACpB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAiB,CAAC,CAAA;QACnC,MAAM,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAE5C,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;KAC7B;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAC9B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAS,EAAE,EAAE;IACvF,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAEjC,IAAI,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAA;IACvC,IAAI,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAA;IACvC,IAAI,KAAK;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,EAAE,EAAE,CAAC,CAAA;IAC5C,IAAI,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,EAAE,CAAC,CAAA;IAE1C,OAAO,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAiB,EAAE,EAAE;IAChD,MAAM,MAAM,GAAG,EAAE,CAAA;IAEjB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,EAAE;QACzE,MAAM,SAAS,GAAwB,EAAE,CAAA;QAEzC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE;YACrC,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;gBACrD,SAAS,CAAC,CAAC,CAAC,GAAI,KAAK,CAAC,CAAC,CAAyB,CAAC,CAAC,CAAC,CAAA;aACpD;iBAAM;gBACL,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;aAC5C;SACF;QAED,MAAM,CAAC,IAAI,CAAC,SAAmB,CAAC,CAAA;KACjC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,cAAgC,EAAE,EAAE;IAC/D,MAAM,GAAG,GAAG,EAAE,CAAA;IACd,MAAM,QAAQ,GAAG,EAAE,CAAA;IAEnB,KAAK,MAAM,WAAW,IAAI,cAAc,EAAE;QACxC,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;YAC7B,MAAM,EAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAC,GAAG,aAAa,CAAC,WAAW,CAAC,CAAA;YAE7D,IAAI,UAAU,EAAE;gBACd,QAAQ,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,EAAC,CAAC,CAAA;aACtE;iBAAM;gBACL,QAAQ,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAC,CAAC,CAAA;aAClD;SACF;aAAM;YACL,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;SACtB;KACF;IAED,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAA;IAEtC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;QAClB,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,EAAC,CAAC,CAAA;KACpB;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,MAAc,EAAE,EAAE;IACjE,MAAM,CAAC,GAAG,EAAE,CAAA;IACZ,MAAM,CAAC,GAAG,EAAE,CAAA;IAEZ,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;QAC1B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAEhB,IAAI,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE;YACjC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;SAC/C;QAED,IAAI,KAAK,CAAC,IAAI,EAAE;YACd,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;SACtB;KACF;IAED,MAAM,OAAO,GAAG,EAAE,CAAA;IAElB,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;QAChB,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,EAAC,CAAC,CAAA;KACnC;IAED,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;QAChB,OAAO,CAAC,IAAI,CAAC,EAAC,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,EAAC,CAAC,CAAA;KACnC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,MAAc,EAAE,EAAE;IACpD,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE;QAC9C,OAAO,CAAC,CAAA;KACT;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAA;IAE1E,IAAI,MAAM,CAAC,OAAO,IAAI,OAAO,EAAE;QAC7B,OAAO,GAAG,CAAA;KACX;IAED,IAAI,MAAM,CAAC,OAAO,EAAE;QAClB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;KAChD;IAED,OAAO,CAAC,CAAA;AACV,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,OAAiB,EAAE,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,CAC5E,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAA"}