@everipedia/iq-utils 2.0.0 → 2.0.2

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.
package/dist/index.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import axios from 'axios';
2
3
 
3
4
  // src/data/constants.ts
4
5
  var WIKI_SUMMARY_MAX_LENGTH = 255;
@@ -35,9 +36,9 @@ var WHITELISTED_DOMAINS = [
35
36
  "ipfs.everipedia.org/ipfs"
36
37
  ];
37
38
  var WHITELISTED_LINK_NAMES = ["YOUTUBE@VID", "DUNE@EMBED"];
38
-
39
- // src/lib/wiki-helpers.ts
40
- var countWords = (text) => text.split(" ").filter((word) => word !== "").length;
39
+ var countWords = (text) => {
40
+ return text.split(" ").filter((word) => word !== "").length;
41
+ };
41
42
  var isValidUrl = (urlString) => {
42
43
  try {
43
44
  return Boolean(new URL(urlString));
@@ -45,7 +46,23 @@ var isValidUrl = (urlString) => {
45
46
  return false;
46
47
  }
47
48
  };
48
- var validateMediaContent = (media) => {
49
+ var containsOnlyVerifiedLinks = (content) => {
50
+ const markdownLinks = content.match(/\[(.*?)\]\((.*?)\)/g);
51
+ return markdownLinks?.every((link) => {
52
+ const [, linkText, linkUrl] = RegExp(/\[(.*?)\]\((.*?)\)/).exec(link) || [];
53
+ if (linkText && linkUrl && WHITELISTED_LINK_NAMES.includes(linkText) && !isValidUrl(linkUrl)) {
54
+ return true;
55
+ }
56
+ if (linkUrl && !linkUrl.startsWith("#")) {
57
+ const validDomainPattern = new RegExp(
58
+ `^https?://(www\\.)?(${WHITELISTED_DOMAINS.join("|")})`
59
+ );
60
+ return validDomainPattern.test(linkUrl);
61
+ }
62
+ return true;
63
+ }) ?? true;
64
+ };
65
+ var isMediaContentValid = (media) => {
49
66
  return media.every((item) => {
50
67
  if (item.source === MediaSource.Enum.IPFS_IMG || item.source === MediaSource.Enum.IPFS_VID) {
51
68
  return item.id.length === IPFS_HASH_LENGTH;
@@ -60,15 +77,20 @@ var validateMediaContent = (media) => {
60
77
  return item.type ? item.type in MediaType : true;
61
78
  });
62
79
  };
63
- var validateMediaCount = (media) => {
80
+ var isMediaCountWithinLimits = (media) => {
64
81
  const iconMediaCount = media.filter(
65
82
  (item) => item.type === MediaType.Enum.ICON
66
83
  ).length;
67
84
  return media.length <= MAX_MEDIA_COUNT && iconMediaCount <= 1;
68
85
  };
69
- var validateEventWiki = (wiki) => {
86
+ var isMediaContentAndCountValid = (media) => {
87
+ return isMediaContentValid(media) && isMediaCountWithinLimits(media);
88
+ };
89
+ var isEventWikiValid = (wiki) => {
70
90
  if (wiki.tags.some((tag) => tag.id === "Events")) {
71
- const referencesData = wiki.metadata.find((meta) => meta.id === CommonMetaIds.Enum.references)?.value || "[]";
91
+ const referencesData = wiki.metadata.find(
92
+ (meta) => meta.id === CommonMetaIds.Enum.references
93
+ )?.value || "[]";
72
94
  const references = JSON.parse(
73
95
  referencesData
74
96
  );
@@ -79,22 +101,54 @@ var validateEventWiki = (wiki) => {
79
101
  }
80
102
  return true;
81
103
  };
82
- var areContentLinksVerified = (content) => {
83
- const markdownLinks = content.match(/\[(.*?)\]\((.*?)\)/g);
84
- return markdownLinks?.every((link) => {
85
- const [, linkText, linkUrl] = RegExp(/\[(.*?)\]\((.*?)\)/).exec(link) || [];
86
- if (linkText && linkUrl && WHITELISTED_LINK_NAMES.includes(linkText) && !isValidUrl(linkUrl)) {
87
- return true;
104
+ var hasMinimumWordCount = (content) => {
105
+ return countWords(content) >= WIKI_CONTENT_MIN_WORDS;
106
+ };
107
+ var hasAtLeastOneReference = (metadata) => {
108
+ const referencesData = metadata.find((meta) => meta.id === CommonMetaIds.Enum.references)?.value || "[]";
109
+ const references = JSON.parse(referencesData);
110
+ return references.length > 0;
111
+ };
112
+ var areMetadataAndExplorerValid = async (metadata) => {
113
+ const explorers = await getExplorers();
114
+ const validIds = /* @__PURE__ */ new Set([
115
+ ...CommonMetaIds.options,
116
+ ...EditSpecificMetaIds.options,
117
+ ...explorers.map((e) => e.id)
118
+ ]);
119
+ return metadata.every(
120
+ (meta) => validIds.has(meta.id) && (!explorers.some((e) => e.id === meta.id) || isValidUrl(meta.value) && new URL(meta.value).origin === new URL(explorers.find((e) => e.id === meta.id)?.baseUrl || "").origin)
121
+ );
122
+ };
123
+ var transformAndFilterTags = (tags) => {
124
+ return tags.filter((tag) => Tag.safeParse(tag.id).success).map((tag) => ({ id: tag.id }));
125
+ };
126
+ async function getExplorers() {
127
+ const query = `
128
+ query ExplorersList($offset: Int!, $limit: Int!) {
129
+ explorers(offset: $offset, limit: $limit) {
130
+ id
131
+ baseUrl
132
+ explorer
133
+ hidden
134
+ }
88
135
  }
89
- if (linkUrl && !linkUrl.startsWith("#")) {
90
- const validDomainPattern = new RegExp(
91
- `^https?://(www\\.)?(${WHITELISTED_DOMAINS.join("|")})`
92
- );
93
- return validDomainPattern.test(linkUrl);
136
+ `;
137
+ const client = axios.create({
138
+ baseURL: "https://graph.everipedia.org/graphql",
139
+ headers: {
140
+ "Content-Type": "application/json"
94
141
  }
95
- return true;
96
- }) ?? true;
97
- };
142
+ });
143
+ const { data } = await client.post("", {
144
+ query,
145
+ variables: {
146
+ offset: 0,
147
+ limit: 30
148
+ }
149
+ });
150
+ return data;
151
+ }
98
152
 
99
153
  // src/schema/index.ts
100
154
  var MediaType = z.enum(["GALLERY", "ICON"]);
@@ -120,34 +174,9 @@ var CommonMetaIds = z.enum([
120
174
  "medium_profile",
121
175
  "mirror_profile",
122
176
  "tiktok_profile",
123
- "etherscan_profile",
124
- "arbiscan_profile",
125
- "polygonscan_profile",
126
- "bscscan_profile",
127
- "optimistic_etherscan_profile",
128
- "basescan_profile",
129
- "ftmscan_profile",
130
- "solscan_profile",
131
- "avascan_profile",
132
- "nearblocks_profile",
133
- "troscan_profile",
134
- "xrpscan_profile",
135
- "kavascan_profile",
136
- "tonscan_profile",
137
- "celoscan_profile",
138
- "cronoscan_profile",
139
- "zkscan_profile",
140
- "explorer_injective_profile",
141
- "blastscan_profile"
142
- ]);
143
- var EditSpecificMetaIds = z.enum([
144
- "previous_cid",
145
- "commit-message",
146
- "words-changed",
147
- "percent-changed",
148
- "blocks-changed",
149
- "wiki-score"
177
+ "explorer_injective_profile"
150
178
  ]);
179
+ var EditSpecificMetaIds = z.enum(["previous_cid", "commit-message"]);
151
180
  var ValidatorCodes = z.enum([
152
181
  "VALID_WIKI",
153
182
  "ID_ERROR",
@@ -238,7 +267,7 @@ var Media = z.object({
238
267
  source: MediaSource
239
268
  });
240
269
  var MetaData = z.object({
241
- id: z.union([CommonMetaIds, EditSpecificMetaIds]),
270
+ id: z.string(),
242
271
  value: z.any()
243
272
  });
244
273
  var BaseCategory = z.object({
@@ -246,21 +275,17 @@ var BaseCategory = z.object({
246
275
  title: z.string()
247
276
  });
248
277
  var BaseEvents = z.object({
249
- id: z.string().optional().nullable(),
278
+ id: z.string().nullish(),
250
279
  date: z.string().nullable(),
251
- title: z.string().optional().nullable(),
280
+ title: z.string().nullish(),
252
281
  type: EventType.nullable(),
253
- description: z.string().optional().nullable(),
254
- link: z.string().optional().nullable(),
255
- multiDateStart: z.string().optional().nullable(),
256
- multiDateEnd: z.string().optional().nullable(),
257
- continent: z.string().optional().nullable(),
258
- country: z.string().optional().nullable(),
259
- action: z.enum(["DELETE", "EDIT", "CREATE"]).optional().nullable()
260
- });
261
- var WikiReference = z.object({
262
- id: z.string(),
263
- title: z.string()
282
+ description: z.string().nullish(),
283
+ link: z.string().nullish(),
284
+ multiDateStart: z.string().nullish(),
285
+ multiDateEnd: z.string().nullish(),
286
+ continent: z.string().nullish(),
287
+ country: z.string().nullish(),
288
+ action: z.enum(["DELETE", "EDIT", "CREATE"]).nullish()
264
289
  });
265
290
  var Wiki = z.object({
266
291
  id: z.string(),
@@ -268,12 +293,11 @@ var Wiki = z.object({
268
293
  WIKI_TITLE_MAX_LENGTH,
269
294
  `Title should be less than ${WIKI_TITLE_MAX_LENGTH} characters`
270
295
  ),
271
- ipfs: z.string().optional(),
272
296
  content: z.string().min(1, "Add a Content section to continue").refine(
273
- (content) => countWords(content) >= WIKI_CONTENT_MIN_WORDS,
297
+ hasMinimumWordCount,
274
298
  `Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue`
275
299
  ).refine(
276
- areContentLinksVerified,
300
+ containsOnlyVerifiedLinks,
277
301
  "Please remove all external links from the content"
278
302
  ),
279
303
  summary: z.string().max(
@@ -282,70 +306,26 @@ var Wiki = z.object({
282
306
  ),
283
307
  images: z.array(Image).min(1, "Add a main image on the right column to continue"),
284
308
  categories: z.array(BaseCategory).min(1, "Add one category to continue"),
285
- tags: z.array(
286
- z.object({
287
- id: z.string()
288
- })
289
- ).transform(
290
- (tags) => tags.map((tag) => ({
291
- id: Tag.parse(tag.id)
292
- }))
293
- ).refine(
294
- (tags) => {
295
- const invalidTags = tags.filter(
296
- (tag) => !Tag.safeParse(tag.id).success
297
- );
298
- if (invalidTags.length > 0) {
299
- throw new Error(
300
- `Invalid tag(s) found: ${invalidTags.map((tag) => tag.id).join(", ")}`
301
- );
302
- }
303
- return true;
304
- },
305
- {
306
- message: "Invalid tag(s) found"
307
- }
309
+ tags: z.array(z.object({ id: z.string() })).transform(transformAndFilterTags),
310
+ media: z.array(Media).max(MAX_MEDIA_COUNT).refine(isMediaContentAndCountValid, "Media is invalid").optional(),
311
+ metadata: z.array(MetaData).refine(hasAtLeastOneReference, "Please add at least one citation").refine(
312
+ areMetadataAndExplorerValid,
313
+ "Invalid metadata Ids or explorer metadata"
308
314
  ),
309
- media: z.array(Media).max(MAX_MEDIA_COUNT).refine((media) => {
310
- if (!media) return true;
311
- return validateMediaContent(media) && validateMediaCount(media);
312
- }, "Media is invalid").optional(),
313
- metadata: z.array(MetaData).refine((metadata) => {
314
- const references = metadata.find(
315
- (meta) => meta.id === CommonMetaIds.Enum.references
316
- );
317
- return !references?.value || references.value.length > 0;
318
- }, "Please add at least one citation"),
319
- events: z.array(BaseEvents).optional().nullable(),
320
- user: z.object({
321
- id: z.string(),
322
- profile: ProfileData.nullable()
323
- }),
324
- author: z.object({
325
- id: z.string(),
326
- profile: ProfileData.nullable()
327
- }),
315
+ events: z.array(BaseEvents).nullish(),
316
+ user: z.object({ id: z.string() }),
317
+ author: z.object({ id: z.string() }),
328
318
  language: LanguagesISO.default(LanguagesISO.Enum.en),
329
319
  version: z.number().default(1),
330
- hidden: z.boolean().default(false),
331
- promoted: z.number().default(0),
332
- views: z.number().optional().default(0),
333
320
  linkedWikis: z.object({
334
- [LinkedWikiKey.Enum.blockchains]: z.array(z.string()).optional().nullable(),
335
- [LinkedWikiKey.Enum.founders]: z.array(z.string()).optional().nullable(),
336
- [LinkedWikiKey.Enum.speakers]: z.array(z.string()).optional().nullable()
337
- }).nullable().optional().default({}),
338
- founderWikis: z.array(WikiReference).optional().default([]),
339
- blockchainWikis: z.array(WikiReference).optional().default([])
340
- }).refine(
341
- (arg) => validateEventWiki(
342
- arg
343
- ),
344
- {
345
- message: "Event wikis must have an event link citation and at least one event date",
346
- path: ["events"]
347
- }
348
- );
321
+ [LinkedWikiKey.Enum.blockchains]: z.array(z.string()).nullish(),
322
+ [LinkedWikiKey.Enum.founders]: z.array(z.string()).nullish(),
323
+ [LinkedWikiKey.Enum.speakers]: z.array(z.string()).nullish()
324
+ }).nullish().default({})
325
+ }).refine(isEventWikiValid, {
326
+ message: "Event wikis must have an event link citation and at least one event date",
327
+ path: ["events"]
328
+ });
349
329
  var Reference = z.object({
350
330
  id: z.string(),
351
331
  description: z.string(),
@@ -469,7 +449,7 @@ var isValidUrl2 = (urlString) => {
469
449
  return false;
470
450
  }
471
451
  };
472
- var areContentLinksVerified2 = (content) => {
452
+ var areContentLinksVerified = (content) => {
473
453
  const markdownLinks = content.match(/\[(.*?)\]\((.*?)\)/g);
474
454
  return markdownLinks?.every((link) => {
475
455
  const [, linkText, linkUrl] = RegExp(/\[(.*?)\]\((.*?)\)/).exec(link) || [];
@@ -487,7 +467,7 @@ var areContentLinksVerified2 = (content) => {
487
467
  };
488
468
  var isMediaValid = (wiki) => {
489
469
  if (!wiki.media) return true;
490
- const isMediaContentValid = wiki.media.every((media) => {
470
+ const isMediaContentValid2 = wiki.media.every((media) => {
491
471
  if (media.source === MediaSource.Enum.IPFS_IMG || media.source === MediaSource.Enum.IPFS_VID) {
492
472
  return media.id.length === IPFS_HASH_LENGTH;
493
473
  }
@@ -503,7 +483,7 @@ var isMediaValid = (wiki) => {
503
483
  const iconMediaCount = wiki.media.filter(
504
484
  (media) => media.type === MediaType.Enum.ICON
505
485
  ).length;
506
- return wiki.media.length <= MAX_MEDIA_COUNT && isMediaContentValid && iconMediaCount <= 1;
486
+ return wiki.media.length <= MAX_MEDIA_COUNT && isMediaContentValid2 && iconMediaCount <= 1;
507
487
  };
508
488
  var isAnyMediaUploading = (wiki) => wiki.media?.some((media) => media.id.endsWith(MEDIA_UPLOAD_PENDING_SUFFIX)) ?? false;
509
489
  var isEventUrlMissing = (wiki) => {
@@ -547,7 +527,7 @@ var validateWiki = (wiki) => {
547
527
  error: `Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue. You have written ${wordCount}`
548
528
  };
549
529
  }
550
- if (!areContentLinksVerified2(wiki.content)) {
530
+ if (!areContentLinksVerified(wiki.content)) {
551
531
  return {
552
532
  isValid: false,
553
533
  error: "Please remove all external links from the content"
@@ -595,6 +575,6 @@ var validateWiki = (wiki) => {
595
575
  return { isValid: true };
596
576
  };
597
577
 
598
- export { BaseEvents, CITATIONS_SCORE_WEIGHT, CONTENT_SCORE_WEIGHT, Category, CommonMetaIds, CreateNewWikiSlug, EditSpecificMetaIds, EditorContentOverride, GOOD_CONTENT_WORD_COUNT, IDEAL_CITATIONS_COUNT, IDEAL_CONTENT_WORD_COUNT, IDEAL_INTERNAL_LINKS_COUNT, IDEAL_MEDIA_COUNT, IDEAL_SOCIAL_MEDIA_COUNT, IDEAL_SUMMARY_LENGTH, IDEAL_TAGS_COUNT, INTERNAL_LINKS_SCORE_WEIGHT, IPFS_HASH_LENGTH, Image, MAX_MEDIA_COUNT, MEDIA_SCORE_WEIGHT, MEDIA_UPLOAD_PENDING_SUFFIX, MIN_CONTENT_WORD_COUNT, Media, MediaSource, MediaType, Reference, SOCIAL_SCORE_WEIGHT, SUMMARY_SCORE_WEIGHT, TAGS_SCORE_WEIGHT, Tag, ValidatorCodes, WHITELISTED_DOMAINS, WHITELISTED_LINK_NAMES, WIKI_CONTENT_MIN_WORDS, WIKI_SUMMARY_MAX_LENGTH, WIKI_TITLE_MAX_LENGTH, Wiki, areContentLinksVerified2 as areContentLinksVerified, calculateWikiScore, countWords2 as countWords, hasNoCitations, isAnyMediaUploading, isEventDateMissing, isEventUrlMissing, isMediaValid, isSummaryTooLong, isValidUrl2 as isValidUrl, validateWiki };
578
+ export { BaseCategory, BaseEvents, CITATIONS_SCORE_WEIGHT, CONTENT_SCORE_WEIGHT, Category, CommonMetaIds, CreateNewWikiSlug, EditSpecificMetaIds, EditorContentOverride, EventType, GOOD_CONTENT_WORD_COUNT, IDEAL_CITATIONS_COUNT, IDEAL_CONTENT_WORD_COUNT, IDEAL_INTERNAL_LINKS_COUNT, IDEAL_MEDIA_COUNT, IDEAL_SOCIAL_MEDIA_COUNT, IDEAL_SUMMARY_LENGTH, IDEAL_TAGS_COUNT, INTERNAL_LINKS_SCORE_WEIGHT, IPFS_HASH_LENGTH, Image, LanguagesISO, LinkedWikiKey, MAX_MEDIA_COUNT, MEDIA_SCORE_WEIGHT, MEDIA_UPLOAD_PENDING_SUFFIX, MIN_CONTENT_WORD_COUNT, Media, MediaSource, MediaType, ProfileData, ProfileLinks, Reference, SOCIAL_SCORE_WEIGHT, SUMMARY_SCORE_WEIGHT, TAGS_SCORE_WEIGHT, Tag, ValidatorCodes, WHITELISTED_DOMAINS, WHITELISTED_LINK_NAMES, WIKI_CONTENT_MIN_WORDS, WIKI_SUMMARY_MAX_LENGTH, WIKI_TITLE_MAX_LENGTH, Wiki, areContentLinksVerified, calculateWikiScore, countWords2 as countWords, hasNoCitations, isAnyMediaUploading, isEventDateMissing, isEventUrlMissing, isMediaValid, isSummaryTooLong, isValidUrl2 as isValidUrl, validateWiki };
599
579
  //# sourceMappingURL=index.mjs.map
600
580
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/data/constants.ts","../src/lib/wiki-helpers.ts","../src/schema/index.ts","../src/lib/wiki-score.ts","../src/lib/check-wiki-validity.ts"],"names":["countWords","isValidUrl","areContentLinksVerified"],"mappings":"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","file":"index.mjs","sourcesContent":["export const WIKI_SUMMARY_MAX_LENGTH = 255;\nexport const WIKI_CONTENT_MIN_WORDS = 100;\nexport const WIKI_TITLE_MAX_LENGTH = 60;\nexport const MEDIA_UPLOAD_PENDING_SUFFIX = \"default\";\nexport const MAX_MEDIA_COUNT = 25;\nexport const IPFS_HASH_LENGTH = 46;\nexport const EditorContentOverride = \"%OVERRIDE@EDITOR@MARKDOWN%\";\nexport const CreateNewWikiSlug = \"/*CREATE+NEW+WIKI*/\";\n\nexport const MIN_CONTENT_WORD_COUNT = 10;\nexport const GOOD_CONTENT_WORD_COUNT = 500;\nexport const IDEAL_CONTENT_WORD_COUNT = 1500;\n\nexport const CONTENT_SCORE_WEIGHT = 0.8;\nexport const INTERNAL_LINKS_SCORE_WEIGHT = 0.5;\nexport const CITATIONS_SCORE_WEIGHT = 0.5;\nexport const MEDIA_SCORE_WEIGHT = 0.3;\nexport const TAGS_SCORE_WEIGHT = 0.3;\nexport const SUMMARY_SCORE_WEIGHT = 0.5;\nexport const SOCIAL_SCORE_WEIGHT = 0.5;\n\nexport const IDEAL_INTERNAL_LINKS_COUNT = 10;\nexport const IDEAL_CITATIONS_COUNT = 10;\nexport const IDEAL_MEDIA_COUNT = 5;\nexport const IDEAL_TAGS_COUNT = 3;\nexport const IDEAL_SUMMARY_LENGTH = 100;\nexport const IDEAL_SOCIAL_MEDIA_COUNT = 4;\n\nexport const WHITELISTED_DOMAINS = [\n\t\"youtube.com/watch\",\n\t\"youtu.be\",\n\t\"vimeo.com\",\n\t\"alpha.everipedia.org/wiki\",\n\t\"beta.everipedia.org/wiki\",\n\t\"iq.wiki/wiki\",\n\t\"ipfs.everipedia.org/ipfs\",\n];\n\nexport const WHITELISTED_LINK_NAMES = [\"YOUTUBE@VID\", \"DUNE@EMBED\"];\n","import type { z } from \"zod\";\n\nimport {\n\tIPFS_HASH_LENGTH,\n\tMAX_MEDIA_COUNT,\n\tWHITELISTED_DOMAINS,\n\tWHITELISTED_LINK_NAMES,\n} from \"../data/constants\";\nimport {\n\tCommonMetaIds,\n\ttype Media,\n\tMediaSource,\n\tMediaType,\n\ttype Tag,\n} from \"../schema\";\n\n/**\n * Counts the number of words in a given string.\n * @param text - The input string to count words from.\n * @returns The number of words in the string.\n */\nexport const countWords = (text: string) =>\n\ttext.split(\" \").filter((word) => word !== \"\").length;\n\n/**\n * Checks if a given string is a valid URL.\n * @param urlString - The string to check.\n * @returns True if the string is a valid URL, false otherwise.\n */\nexport const isValidUrl = (urlString: string) => {\n\ttry {\n\t\treturn Boolean(new URL(urlString));\n\t} catch (_e) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Validates the media content in a wiki, ensuring that the media items have valid IDs and sources.\n * @param media - The array of media items to validate.\n * @returns True if all media items have valid content, false otherwise.\n */\nexport const validateMediaContent = (media: Media[]) => {\n\treturn media.every((item) => {\n\t\tif (\n\t\t\titem.source === MediaSource.Enum.IPFS_IMG ||\n\t\t\titem.source === MediaSource.Enum.IPFS_VID\n\t\t) {\n\t\t\treturn item.id.length === IPFS_HASH_LENGTH;\n\t\t}\n\n\t\tif (item.source === MediaSource.Enum.YOUTUBE) {\n\t\t\tconst youtubePattern =\n\t\t\t\t/^.*(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/|watch\\?v=)([^#&?]*).*/;\n\t\t\treturn (\n\t\t\t\titem.id === `https://www.youtube.com/watch?v=${item.name}` &&\n\t\t\t\tyoutubePattern.test(item.id)\n\t\t\t);\n\t\t}\n\n\t\tif (item.source === MediaSource.Enum.VIMEO) {\n\t\t\treturn item.id === `https://vimeo.com/${item.name}`;\n\t\t}\n\n\t\treturn item.type ? item.type in MediaType : true;\n\t});\n};\n\n/**\n * Validates the count of media items in a wiki, ensuring that the total count does not exceed a maximum limit and that there is at most one icon media item.\n * @param media - The array of media items to validate.\n * @returns True if the media count is valid, false otherwise.\n */\nexport const validateMediaCount = (media: Media[]) => {\n\tconst iconMediaCount = media.filter(\n\t\t(item) => item.type === MediaType.Enum.ICON,\n\t).length;\n\treturn media.length <= MAX_MEDIA_COUNT && iconMediaCount <= 1;\n};\n\n/**\n * Validates the event wiki data, ensuring that if the wiki has a \"Events\" tag, it also has a reference with the description \"Event Link\" and at least one event.\n * @param wiki - The wiki data to validate.\n * @returns True if the event wiki data is valid, false otherwise.\n */\nexport const validateEventWiki = (wiki: {\n\ttags: { id: z.infer<typeof Tag> }[];\n\tmetadata: { id: string; value?: string }[];\n\tevents?: unknown[];\n}): boolean => {\n\tif (wiki.tags.some((tag) => tag.id === \"Events\")) {\n\t\tconst referencesData =\n\t\t\twiki.metadata.find((meta) => meta.id === CommonMetaIds.Enum.references)\n\t\t\t\t?.value || \"[]\";\n\t\tconst references: { description: string }[] = JSON.parse(\n\t\t\treferencesData,\n\t\t) as { description: string }[];\n\t\tconst hasEventLink = references.some(\n\t\t\t(item) => item.description.toLowerCase() === \"event link\",\n\t\t);\n\t\treturn hasEventLink && Array.isArray(wiki.events) && wiki.events.length > 0;\n\t}\n\treturn true;\n};\n\n/**\n * Checks if all content links in the given text are verified.\n * @param content - The content to check for links.\n * @returns True if all links are verified, false otherwise.\n */\nexport const areContentLinksVerified = (content: string) => {\n\tconst markdownLinks = content.match(/\\[(.*?)\\]\\((.*?)\\)/g);\n\treturn (\n\t\tmarkdownLinks?.every((link) => {\n\t\t\tconst [, linkText, linkUrl] =\n\t\t\t\tRegExp(/\\[(.*?)\\]\\((.*?)\\)/).exec(link) || [];\n\n\t\t\tif (\n\t\t\t\tlinkText &&\n\t\t\t\tlinkUrl &&\n\t\t\t\tWHITELISTED_LINK_NAMES.includes(linkText) &&\n\t\t\t\t!isValidUrl(linkUrl)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (linkUrl && !linkUrl.startsWith(\"#\")) {\n\t\t\t\tconst validDomainPattern = new RegExp(\n\t\t\t\t\t`^https?://(www\\\\.)?(${WHITELISTED_DOMAINS.join(\"|\")})`,\n\t\t\t\t);\n\t\t\t\treturn validDomainPattern.test(linkUrl);\n\t\t\t}\n\t\t\treturn true;\n\t\t}) ?? true\n\t);\n};\n","import { z } from \"zod\";\n\nimport {\n\tMAX_MEDIA_COUNT,\n\tWIKI_CONTENT_MIN_WORDS,\n\tWIKI_SUMMARY_MAX_LENGTH,\n\tWIKI_TITLE_MAX_LENGTH,\n} from \"../data/constants\";\nimport {\n\tareContentLinksVerified,\n\tcountWords,\n\tvalidateEventWiki,\n\tvalidateMediaContent,\n\tvalidateMediaCount,\n} from \"../lib/wiki-helpers\";\n\n/**\n * ========================\n * ===== Enum Schemas =====\n * ========================\n */\nexport const MediaType = z.enum([\"GALLERY\", \"ICON\"]);\nexport type MediaType = z.infer<typeof MediaType>;\n\nexport const MediaSource = z.enum([\"IPFS_IMG\", \"VIMEO\", \"YOUTUBE\", \"IPFS_VID\"]);\nexport type MediaSource = z.infer<typeof MediaSource>;\n\nexport const CommonMetaIds = z.enum([\n\t\"references\",\n\t\"website\",\n\t\"contract_url\",\n\t\"location\",\n\t\"email_url\",\n\t\"facebook_profile\",\n\t\"instagram_profile\",\n\t\"twitter_profile\",\n\t\"linkedin_profile\",\n\t\"youtube_profile\",\n\t\"discord_profile\",\n\t\"reddit_profile\",\n\t\"telegram_profile\",\n\t\"github_profile\",\n\t\"coinmarketcap_url\",\n\t\"coingecko_profile\",\n\t\"opensea_profile\",\n\t\"medium_profile\",\n\t\"mirror_profile\",\n\t\"tiktok_profile\",\n\t\"etherscan_profile\",\n\t\"arbiscan_profile\",\n\t\"polygonscan_profile\",\n\t\"bscscan_profile\",\n\t\"optimistic_etherscan_profile\",\n\t\"basescan_profile\",\n\t\"ftmscan_profile\",\n\t\"solscan_profile\",\n\t\"avascan_profile\",\n\t\"nearblocks_profile\",\n\t\"troscan_profile\",\n\t\"xrpscan_profile\",\n\t\"kavascan_profile\",\n\t\"tonscan_profile\",\n\t\"celoscan_profile\",\n\t\"cronoscan_profile\",\n\t\"zkscan_profile\",\n\t\"explorer_injective_profile\",\n\t\"blastscan_profile\",\n]);\nexport type CommonMetaIds = z.infer<typeof CommonMetaIds>;\n\nexport const EditSpecificMetaIds = z.enum([\n\t\"previous_cid\",\n\t\"commit-message\",\n\t\"words-changed\",\n\t\"percent-changed\",\n\t\"blocks-changed\",\n\t\"wiki-score\",\n]);\nexport type EditSpecificMetaIds = z.infer<typeof EditSpecificMetaIds>;\n\nexport const ValidatorCodes = z.enum([\n\t\"VALID_WIKI\",\n\t\"ID_ERROR\",\n\t\"LANGUAGE_ERROR\",\n\t\"USER_ERROR\",\n\t\"WORD_COUNT_ERROR\",\n\t\"CATEGORY_ERROR\",\n\t\"SUMMARY_ERROR\",\n\t\"IMAGE_ERROR\",\n\t\"TAG_ERROR\",\n\t\"EXTERNAL_URL_ERROR\",\n\t\"METADATA_ERROR\",\n\t\"MEDIA_ERROR\",\n\t\"GLOBAL_RATE_LIMIT\",\n\t\"LINKED_WIKIS\",\n\t\"EVENTS_ERROR\",\n]);\nexport type ValidatorCodes = z.infer<typeof ValidatorCodes>;\n\nconst LanguagesISO = z.enum([\"en\", \"es\", \"zh\", \"ko\"]);\nexport type LanguagesISO = z.infer<typeof LanguagesISO>;\n\nconst LinkedWikiKey = z.enum([\"founders\", \"blockchains\", \"speakers\"]);\nexport type LinkedWikiKey = z.infer<typeof LinkedWikiKey>;\n\nconst EventType = z.enum([\"CREATED\", \"DEFAULT\", \"MULTIDATE\"]);\nexport type EventType = z.infer<typeof EventType>;\n\nexport const Tag = z.enum([\n\t\"Artists\",\n\t\"AI\",\n\t\"BinanceSmartChain\",\n\t\"Blockchains\",\n\t\"CEXes\",\n\t\"Collections\",\n\t\"Collectors\",\n\t\"Conference\",\n\t\"DEXes\",\n\t\"Developers\",\n\t\"Entertainment\",\n\t\"Ethereum\",\n\t\"Events\",\n\t\"Forum\",\n\t\"Founders\",\n\t\"Festival\",\n\t\"Games\",\n\t\"Glossary\",\n\t\"Hackathon\",\n\t\"Marketplaces\",\n\t\"Memecoins\",\n\t\"Organizations\",\n\t\"Online\",\n\t\"PeopleInDeFi\",\n\t\"Polkadot\",\n\t\"Polygon\",\n\t\"Protocols\",\n\t\"Solana\",\n\t\"Speakers\",\n\t\"Stablecoins\",\n\t\"Venture\",\n]);\nexport type Tag = z.infer<typeof Tag>;\n\nexport const Category = z.enum([\n\t\"nfts\",\n\t\"defi\",\n\t\"exchanges\",\n\t\"cryptocurrencies\",\n\t\"daos\",\n\t\"people\",\n\t\"dapps\",\n\t\"organizations\",\n]);\nexport type Category = z.infer<typeof Category>;\n\n/**\n * ==============================\n * ===== Supporting Schemas =====\n * ==============================\n */\n\nconst ProfileLinks = z.object({\n\ttwitter: z.string().nullable(),\n\twebsite: z.string().nullable(),\n\tinstagram: z.string().nullable(),\n});\nexport type ProfileLinks = z.infer<typeof ProfileLinks>;\n\nconst ProfileData = z.object({\n\tid: z.string().nullable(),\n\tusername: z.string().nullable(),\n\tbio: z.string().nullable(),\n\tlinks: z.array(ProfileLinks).nullable(),\n\tbanner: z.string().nullable(),\n\tavatar: z.string().nullable(),\n});\nexport type ProfileData = z.infer<typeof ProfileData>;\n\nexport const Image = z.object({\n\tid: z.string(),\n\ttype: z.string(),\n});\nexport type Image = z.infer<typeof Image>;\n\nexport const Media = z.object({\n\tid: z.string(),\n\tsize: z.string().nullish(),\n\tname: z.string().nullish(),\n\ttype: MediaType.nullish(),\n\tcaption: z.string().nullish(),\n\tthumbnail: z.string().nullish(),\n\tsource: MediaSource,\n});\nexport type Media = z.infer<typeof Media>;\n\nconst MetaData = z.object({\n\tid: z.union([CommonMetaIds, EditSpecificMetaIds]),\n\tvalue: z.any(),\n});\nexport type MetaData = z.infer<typeof MetaData>;\n\nconst BaseCategory = z.object({\n\tid: Category,\n\ttitle: z.string(),\n});\nexport type BaseCategory = z.infer<typeof BaseCategory>;\n\nexport const BaseEvents = z.object({\n\tid: z.string().optional().nullable(),\n\tdate: z.string().nullable(),\n\ttitle: z.string().optional().nullable(),\n\ttype: EventType.nullable(),\n\tdescription: z.string().optional().nullable(),\n\tlink: z.string().optional().nullable(),\n\tmultiDateStart: z.string().optional().nullable(),\n\tmultiDateEnd: z.string().optional().nullable(),\n\tcontinent: z.string().optional().nullable(),\n\tcountry: z.string().optional().nullable(),\n\taction: z.enum([\"DELETE\", \"EDIT\", \"CREATE\"]).optional().nullable(),\n});\nexport type BaseEvents = z.infer<typeof BaseEvents>;\n\nconst WikiReference = z.object({\n\tid: z.string(),\n\ttitle: z.string(),\n});\nexport type WikiReference = z.infer<typeof WikiReference>;\n\n/**\n * ========================\n * ===== Core Schemas =====\n * ========================\n */\n\nexport const Wiki = z\n\t.object({\n\t\tid: z.string(),\n\t\ttitle: z\n\t\t\t.string()\n\t\t\t.min(1, \"Add a Title at the top for this Wiki to continue\")\n\t\t\t.max(\n\t\t\t\tWIKI_TITLE_MAX_LENGTH,\n\t\t\t\t`Title should be less than ${WIKI_TITLE_MAX_LENGTH} characters`,\n\t\t\t),\n\t\tipfs: z.string().optional(),\n\t\tcontent: z\n\t\t\t.string()\n\t\t\t.min(1, \"Add a Content section to continue\")\n\t\t\t.refine(\n\t\t\t\t(content) => countWords(content) >= WIKI_CONTENT_MIN_WORDS,\n\t\t\t\t`Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue`,\n\t\t\t)\n\t\t\t.refine(\n\t\t\t\tareContentLinksVerified,\n\t\t\t\t\"Please remove all external links from the content\",\n\t\t\t),\n\t\tsummary: z\n\t\t\t.string()\n\t\t\t.max(\n\t\t\t\tWIKI_SUMMARY_MAX_LENGTH,\n\t\t\t\t`Summary exceeds maximum limit of ${WIKI_SUMMARY_MAX_LENGTH}`,\n\t\t\t),\n\t\timages: z\n\t\t\t.array(Image)\n\t\t\t.min(1, \"Add a main image on the right column to continue\"),\n\t\tcategories: z.array(BaseCategory).min(1, \"Add one category to continue\"),\n\t\ttags: z\n\t\t\t.array(\n\t\t\t\tz.object({\n\t\t\t\t\tid: z.string(),\n\t\t\t\t}),\n\t\t\t)\n\t\t\t.transform((tags) =>\n\t\t\t\ttags.map((tag) => ({\n\t\t\t\t\tid: Tag.parse(tag.id),\n\t\t\t\t})),\n\t\t\t)\n\t\t\t.refine(\n\t\t\t\t(tags) => {\n\t\t\t\t\tconst invalidTags = tags.filter(\n\t\t\t\t\t\t(tag) => !Tag.safeParse(tag.id).success,\n\t\t\t\t\t);\n\t\t\t\t\tif (invalidTags.length > 0) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Invalid tag(s) found: ${invalidTags.map((tag) => tag.id).join(\", \")}`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tmessage: \"Invalid tag(s) found\",\n\t\t\t\t},\n\t\t\t),\n\n\t\tmedia: z\n\t\t\t.array(Media)\n\t\t\t.max(MAX_MEDIA_COUNT)\n\t\t\t.refine((media) => {\n\t\t\t\tif (!media) return true;\n\t\t\t\treturn validateMediaContent(media) && validateMediaCount(media);\n\t\t\t}, \"Media is invalid\")\n\t\t\t.optional(),\n\t\tmetadata: z.array(MetaData).refine((metadata) => {\n\t\t\tconst references = metadata.find(\n\t\t\t\t(meta) => meta.id === CommonMetaIds.Enum.references,\n\t\t\t);\n\t\t\treturn !references?.value || references.value.length > 0;\n\t\t}, \"Please add at least one citation\"),\n\t\tevents: z.array(BaseEvents).optional().nullable(),\n\t\tuser: z.object({\n\t\t\tid: z.string(),\n\t\t\tprofile: ProfileData.nullable(),\n\t\t}),\n\t\tauthor: z.object({\n\t\t\tid: z.string(),\n\t\t\tprofile: ProfileData.nullable(),\n\t\t}),\n\t\tlanguage: LanguagesISO.default(LanguagesISO.Enum.en),\n\t\tversion: z.number().default(1),\n\t\thidden: z.boolean().default(false),\n\t\tpromoted: z.number().default(0),\n\t\tviews: z.number().optional().default(0),\n\t\tlinkedWikis: z\n\t\t\t.object({\n\t\t\t\t[LinkedWikiKey.Enum.blockchains]: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable(),\n\t\t\t\t[LinkedWikiKey.Enum.founders]: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable(),\n\t\t\t\t[LinkedWikiKey.Enum.speakers]: z\n\t\t\t\t\t.array(z.string())\n\t\t\t\t\t.optional()\n\t\t\t\t\t.nullable(),\n\t\t\t})\n\t\t\t.nullable()\n\t\t\t.optional()\n\t\t\t.default({}),\n\t\tfounderWikis: z.array(WikiReference).optional().default([]),\n\t\tblockchainWikis: z.array(WikiReference).optional().default([]),\n\t})\n\t.refine(\n\t\t(arg) =>\n\t\t\tvalidateEventWiki(\n\t\t\t\targ as {\n\t\t\t\t\ttags: { id: z.infer<typeof Tag> }[];\n\t\t\t\t\tmetadata: { id: string; value?: string }[];\n\t\t\t\t\tevents?: unknown[];\n\t\t\t\t},\n\t\t\t),\n\t\t{\n\t\t\tmessage:\n\t\t\t\t\"Event wikis must have an event link citation and at least one event date\",\n\t\t\tpath: [\"events\"],\n\t\t},\n\t);\nexport type Wiki = z.infer<typeof Wiki>;\n\nexport const Reference = z.object({\n\tid: z.string(),\n\tdescription: z.string(),\n\ttimestamp: z.number(),\n\turl: z.string(),\n});\nexport type Reference = z.infer<typeof Reference>;\n","import {\n\tCITATIONS_SCORE_WEIGHT,\n\tCONTENT_SCORE_WEIGHT,\n\tGOOD_CONTENT_WORD_COUNT,\n\tIDEAL_CITATIONS_COUNT,\n\tIDEAL_CONTENT_WORD_COUNT,\n\tIDEAL_INTERNAL_LINKS_COUNT,\n\tIDEAL_MEDIA_COUNT,\n\tIDEAL_SOCIAL_MEDIA_COUNT,\n\tIDEAL_SUMMARY_LENGTH,\n\tIDEAL_TAGS_COUNT,\n\tINTERNAL_LINKS_SCORE_WEIGHT,\n\tMEDIA_SCORE_WEIGHT,\n\tMIN_CONTENT_WORD_COUNT,\n\tSOCIAL_SCORE_WEIGHT,\n\tSUMMARY_SCORE_WEIGHT,\n\tTAGS_SCORE_WEIGHT,\n} from \"../data/constants\";\nimport { CommonMetaIds, type Wiki } from \"../schema\";\n\nconst contentQuality = (wordCount: number): number => {\n\tconst scoreMin = 0.0;\n\tconst scoreMax = 1.0;\n\n\tlet score = 0;\n\n\tif (wordCount < MIN_CONTENT_WORD_COUNT) {\n\t\treturn scoreMin;\n\t}\n\n\tif (\n\t\twordCount >= MIN_CONTENT_WORD_COUNT &&\n\t\twordCount <= GOOD_CONTENT_WORD_COUNT\n\t) {\n\t\tscore = wordCount / GOOD_CONTENT_WORD_COUNT;\n\t\tscore *= 0.8;\n\t}\n\n\tif (\n\t\twordCount > GOOD_CONTENT_WORD_COUNT &&\n\t\twordCount < IDEAL_CONTENT_WORD_COUNT\n\t) {\n\t\tconst baseScore = 0.8;\n\t\tconst wordCountAboveGood = wordCount - GOOD_CONTENT_WORD_COUNT;\n\t\tconst extraScoreFactor =\n\t\t\twordCountAboveGood / (IDEAL_CONTENT_WORD_COUNT - GOOD_CONTENT_WORD_COUNT);\n\t\tconst extraScore = Math.sqrt(extraScoreFactor) * 0.2;\n\t\tscore = baseScore + extraScore;\n\t}\n\n\tif (wordCount >= IDEAL_CONTENT_WORD_COUNT) {\n\t\treturn scoreMax;\n\t}\n\n\tif (score < scoreMin) {\n\t\treturn scoreMin;\n\t}\n\n\tif (score > scoreMax) {\n\t\treturn scoreMax;\n\t}\n\n\treturn score;\n};\n\nconst countQuality = (idealCount: number, realCount: number): number => {\n\tconst scoreMin = 0.0;\n\tconst scoreMax = 1.0;\n\n\tconst score = realCount / idealCount;\n\n\tif (score < scoreMin) {\n\t\treturn scoreMin;\n\t}\n\n\tif (score > scoreMax) {\n\t\treturn scoreMax;\n\t}\n\n\treturn score;\n};\n\nconst getHostnameFromRegex = (url: string) => {\n\tconst matches = RegExp(/^https?:\\/\\/([^/?#]+)(?:[/?#]|$)/i).exec(url);\n\treturn matches?.[1];\n};\n\nconst getWikiInternalLinks = (content: string): number => {\n\tconst markdownLinkRegex = /\\[(.*?)\\]\\((.*?)\\)/g;\n\tlet internalLinksCount = 0;\n\tlet match = markdownLinkRegex.exec(content);\n\n\twhile (match !== null) {\n\t\tconst url = match[2];\n\t\tif (url && !url.startsWith(\"#\")) {\n\t\t\tconst hostname = getHostnameFromRegex(url);\n\t\t\tif (\n\t\t\t\thostname === \"everipedia.org\" ||\n\t\t\t\thostname === \"iq.wiki\" ||\n\t\t\t\thostname?.endsWith(\".everipedia.org\")\n\t\t\t) {\n\t\t\t\tinternalLinksCount++;\n\t\t\t}\n\t\t}\n\t\tmatch = markdownLinkRegex.exec(content); // Move assignment here\n\t}\n\n\treturn internalLinksCount;\n};\n\nconst getWikiCitationLinks = (wiki: Wiki) => {\n\tconst rawWikiReferences = wiki.metadata.find(\n\t\t(m) => m.id === CommonMetaIds.Enum.references,\n\t)?.value;\n\n\tif (\n\t\trawWikiReferences === undefined ||\n\t\trawWikiReferences?.trim().length === 0\n\t) {\n\t\treturn 0;\n\t}\n\n\tconst wikiReferences = JSON.parse(rawWikiReferences);\n\n\treturn wikiReferences.length;\n};\n\nconst getSocialsCount = (wiki: Wiki): number => {\n\tlet socialsCount = 0;\n\tfor (const meta of wiki.metadata) {\n\t\tif (\n\t\t\tCommonMetaIds.options.includes(meta.id as keyof typeof CommonMetaIds.enum)\n\t\t) {\n\t\t\tif (meta.value) {\n\t\t\t\tsocialsCount += 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn socialsCount;\n};\n\nexport const calculateWikiScore = (wiki: Wiki): number => {\n\tconst wordCount = wiki.content.split(\" \").length;\n\tconst internalLinksCount = getWikiInternalLinks(wiki.content);\n\tconst citationCount = getWikiCitationLinks(wiki);\n\tconst mediaCount = wiki.media?.length || 0;\n\tconst tagsCount = wiki.tags?.length || 0;\n\tconst summaryWordCount = wiki.summary?.length || 0;\n\tconst socialsCount = getSocialsCount(wiki);\n\n\tconst contentScore = contentQuality(wordCount);\n\tconst internalLinksScore = countQuality(\n\t\tIDEAL_INTERNAL_LINKS_COUNT,\n\t\tinternalLinksCount,\n\t);\n\tconst citationScore = countQuality(IDEAL_CITATIONS_COUNT, citationCount);\n\tconst mediaScore = countQuality(IDEAL_MEDIA_COUNT, mediaCount);\n\tconst tagsScore = countQuality(IDEAL_TAGS_COUNT, tagsCount);\n\tconst summaryScore = countQuality(IDEAL_SUMMARY_LENGTH, summaryWordCount);\n\tconst socialsScore = countQuality(IDEAL_SOCIAL_MEDIA_COUNT, socialsCount);\n\n\tconst sumOfWeights =\n\t\tCONTENT_SCORE_WEIGHT +\n\t\tINTERNAL_LINKS_SCORE_WEIGHT +\n\t\tCITATIONS_SCORE_WEIGHT +\n\t\tMEDIA_SCORE_WEIGHT +\n\t\tTAGS_SCORE_WEIGHT +\n\t\tSUMMARY_SCORE_WEIGHT +\n\t\tSOCIAL_SCORE_WEIGHT;\n\n\tconst score =\n\t\t(contentScore * CONTENT_SCORE_WEIGHT +\n\t\t\tinternalLinksScore * INTERNAL_LINKS_SCORE_WEIGHT +\n\t\t\tcitationScore * CITATIONS_SCORE_WEIGHT +\n\t\t\tmediaScore * MEDIA_SCORE_WEIGHT +\n\t\t\ttagsScore * TAGS_SCORE_WEIGHT +\n\t\t\tsummaryScore * SUMMARY_SCORE_WEIGHT +\n\t\t\tsocialsScore * SOCIAL_SCORE_WEIGHT) /\n\t\tsumOfWeights;\n\n\tconst percentScore = Math.floor(score * 100);\n\treturn percentScore;\n};\n","import {\n\tIPFS_HASH_LENGTH,\n\tMAX_MEDIA_COUNT,\n\tMEDIA_UPLOAD_PENDING_SUFFIX,\n\tWIKI_CONTENT_MIN_WORDS,\n\tWIKI_SUMMARY_MAX_LENGTH,\n\tWIKI_TITLE_MAX_LENGTH,\n\tWHITELISTED_DOMAINS,\n\tWHITELISTED_LINK_NAMES,\n} from \"../data/constants\";\nimport { CommonMetaIds, MediaSource, MediaType, type Wiki } from \"../schema\";\n\n/**\n * Counts the number of words in a given string.\n * @param text - The input string to count words from.\n * @returns The number of words in the string.\n */\nexport const countWords = (text: string) =>\n\ttext.split(\" \").filter((word) => word !== \"\").length;\n\n/**\n * Checks if a given string is a valid URL.\n * @param urlString - The string to check.\n * @returns True if the string is a valid URL, false otherwise.\n */\nexport const isValidUrl = (urlString: string) => {\n\ttry {\n\t\treturn Boolean(new URL(urlString));\n\t} catch (_e) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Checks if all content links in the given text are verified.\n * @param content - The content to check for links.\n * @returns True if all links are verified, false otherwise.\n */\nexport const areContentLinksVerified = (content: string) => {\n\tconst markdownLinks = content.match(/\\[(.*?)\\]\\((.*?)\\)/g);\n\treturn (\n\t\tmarkdownLinks?.every((link) => {\n\t\t\tconst [, linkText, linkUrl] =\n\t\t\t\tRegExp(/\\[(.*?)\\]\\((.*?)\\)/).exec(link) || [];\n\n\t\t\tif (\n\t\t\t\tlinkText &&\n\t\t\t\tlinkUrl &&\n\t\t\t\tWHITELISTED_LINK_NAMES.includes(linkText) &&\n\t\t\t\t!isValidUrl(linkUrl)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (linkUrl && !linkUrl.startsWith(\"#\")) {\n\t\t\t\tconst validDomainPattern = new RegExp(\n\t\t\t\t\t`^https?://(www\\\\.)?(${WHITELISTED_DOMAINS.join(\"|\")})`,\n\t\t\t\t);\n\t\t\t\treturn validDomainPattern.test(linkUrl);\n\t\t\t}\n\t\t\treturn true;\n\t\t}) ?? true\n\t);\n};\n\n/**\n * Checks if the media in the wiki is valid.\n * @param wiki - The wiki object to check.\n * @returns True if the media is valid, false otherwise.\n */\nexport const isMediaValid = (wiki: Wiki) => {\n\tif (!wiki.media) return true;\n\n\tconst isMediaContentValid = wiki.media.every((media) => {\n\t\tif (\n\t\t\tmedia.source === MediaSource.Enum.IPFS_IMG ||\n\t\t\tmedia.source === MediaSource.Enum.IPFS_VID\n\t\t) {\n\t\t\treturn media.id.length === IPFS_HASH_LENGTH;\n\t\t}\n\n\t\tif (media.source === MediaSource.Enum.YOUTUBE) {\n\t\t\tconst youtubePattern =\n\t\t\t\t/^.*(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/|watch\\?v=)([^#&?]*).*/;\n\t\t\treturn (\n\t\t\t\tmedia.id === `https://www.youtube.com/watch?v=${media.name}` &&\n\t\t\t\tyoutubePattern.test(media.id)\n\t\t\t);\n\t\t}\n\n\t\tif (media.source === MediaSource.Enum.VIMEO) {\n\t\t\treturn media.id === `https://vimeo.com/${media.name}`;\n\t\t}\n\n\t\treturn media.type ? MediaType.options.includes(media.type) : true;\n\t});\n\n\tconst iconMediaCount = wiki.media.filter(\n\t\t(media) => media.type === MediaType.Enum.ICON,\n\t).length;\n\n\treturn (\n\t\twiki.media.length <= MAX_MEDIA_COUNT &&\n\t\tisMediaContentValid &&\n\t\ticonMediaCount <= 1\n\t);\n};\n\n/**\n * Checks if any media in the wiki is still uploading.\n * @param wiki - The wiki object to check.\n * @returns True if any media is still uploading, false otherwise.\n */\nexport const isAnyMediaUploading = (wiki: Wiki) =>\n\twiki.media?.some((media) => media.id.endsWith(MEDIA_UPLOAD_PENDING_SUFFIX)) ??\n\tfalse;\n\n/**\n * Checks if the event URL is missing for an event wiki.\n * @param wiki - The wiki object to check.\n * @returns True if the event URL is missing, false otherwise.\n */\nexport const isEventUrlMissing = (wiki: Wiki) => {\n\tif (wiki.tags.some((tag) => tag.id === \"Events\")) {\n\t\tconst referencesData =\n\t\t\twiki.metadata.find((meta) => meta.id === CommonMetaIds.Enum.references)\n\t\t\t\t?.value || \"[]\";\n\t\tconst references = JSON.parse(referencesData);\n\t\treturn !references.some(\n\t\t\t(item: { description: string }) =>\n\t\t\t\titem.description.toLowerCase() === \"event link\",\n\t\t);\n\t}\n\treturn false;\n};\n\n/**\n * Checks if the event date is missing for an event wiki.\n * @param wiki - The wiki object to check.\n * @returns True if the event date is missing, false otherwise.\n */\nexport const isEventDateMissing = (wiki: Wiki) =>\n\twiki.tags.some((tag) => tag.id === \"Events\") && wiki.events?.length === 0;\n\n/**\n * Checks if the wiki summary exceeds the maximum length.\n * @param wiki - The wiki object to check.\n * @returns True if the summary exceeds the limit, false otherwise.\n */\nexport const isSummaryTooLong = (wiki: Wiki) =>\n\t!!(wiki.summary && wiki.summary.length > WIKI_SUMMARY_MAX_LENGTH);\n\n/**\n * Checks if the wiki has no citations.\n * @param wiki - The wiki object to check.\n * @returns True if there are no citations, false otherwise.\n */\nexport const hasNoCitations = (wiki: Wiki) => {\n\tconst references = wiki.metadata.find(\n\t\t(meta) => meta.id === CommonMetaIds.Enum.references,\n\t);\n\treturn !references?.value || references.value.length === 0;\n};\n\n/**\n * Validates a wiki object and returns the validation result.\n * @param wiki - The wiki object to validate.\n * @returns An object containing the validation result and an error message if applicable.\n */\nexport const validateWiki = (wiki: Wiki) => {\n\tconst wordCount = countWords(wiki.content || \"\");\n\n\tif (!wiki.title) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Add a Title at the top for this Wiki to continue\",\n\t\t};\n\t}\n\n\tif (wiki.title.length > WIKI_TITLE_MAX_LENGTH) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Title should be less than ${WIKI_TITLE_MAX_LENGTH} characters`,\n\t\t};\n\t}\n\n\tif (!wiki.content) {\n\t\treturn { isValid: false, error: \"Add a Content section to continue\" };\n\t}\n\n\tif (wordCount < WIKI_CONTENT_MIN_WORDS) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue. You have written ${wordCount}`,\n\t\t};\n\t}\n\n\tif (!areContentLinksVerified(wiki.content)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Please remove all external links from the content\",\n\t\t};\n\t}\n\n\tif (!wiki.images?.length) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Add a main image on the right column to continue\",\n\t\t};\n\t}\n\n\tif (wiki.categories.length === 0) {\n\t\treturn { isValid: false, error: \"Add one category to continue\" };\n\t}\n\n\tif (isSummaryTooLong(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Summary exceeds maximum limit of ${WIKI_SUMMARY_MAX_LENGTH}`,\n\t\t};\n\t}\n\n\tif (isAnyMediaUploading(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Some media are still uploading, please wait\",\n\t\t};\n\t}\n\n\tif (hasNoCitations(wiki)) {\n\t\treturn { isValid: false, error: \"Please add at least one citation\" };\n\t}\n\n\tif (isEventUrlMissing(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror:\n\t\t\t\t\"Please cite the event official website with 'Event Link' description\",\n\t\t};\n\t}\n\n\tif (isEventDateMissing(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror:\n\t\t\t\t'Please open the \"Edit Wiki Details Modal\" and enter a valid event date',\n\t\t};\n\t}\n\n\tif (!isMediaValid(wiki)) {\n\t\treturn { isValid: false, error: \"Media is invalid\" };\n\t}\n\n\treturn { isValid: true };\n};\n"]}
1
+ {"version":3,"sources":["../src/data/constants.ts","../src/lib/wiki-helpers.ts","../src/schema/index.ts","../src/lib/wiki-score.ts","../src/lib/check-wiki-validity.ts"],"names":["countWords","isValidUrl","isMediaContentValid"],"mappings":";;;;AAAO,IAAM,uBAA0B,GAAA,IAAA;AAChC,IAAM,sBAAyB,GAAA,IAAA;AAC/B,IAAM,qBAAwB,GAAA,GAAA;AAC9B,IAAM,2BAA8B,GAAA,UAAA;AACpC,IAAM,eAAkB,GAAA,GAAA;AACxB,IAAM,gBAAmB,GAAA,GAAA;AACzB,IAAM,qBAAwB,GAAA,6BAAA;AAC9B,IAAM,iBAAoB,GAAA,sBAAA;AAE1B,IAAM,sBAAyB,GAAA,GAAA;AAC/B,IAAM,uBAA0B,GAAA,IAAA;AAChC,IAAM,wBAA2B,GAAA,KAAA;AAEjC,IAAM,oBAAuB,GAAA,IAAA;AAC7B,IAAM,2BAA8B,GAAA,IAAA;AACpC,IAAM,sBAAyB,GAAA,IAAA;AAC/B,IAAM,kBAAqB,GAAA,IAAA;AAC3B,IAAM,iBAAoB,GAAA,IAAA;AAC1B,IAAM,oBAAuB,GAAA,IAAA;AAC7B,IAAM,mBAAsB,GAAA,IAAA;AAE5B,IAAM,0BAA6B,GAAA,GAAA;AACnC,IAAM,qBAAwB,GAAA,GAAA;AAC9B,IAAM,iBAAoB,GAAA,EAAA;AAC1B,IAAM,gBAAmB,GAAA,EAAA;AACzB,IAAM,oBAAuB,GAAA,IAAA;AAC7B,IAAM,wBAA2B,GAAA,EAAA;AAEjC,IAAM,mBAAsB,GAAA;AAAA,EAClC,mBAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,2BAAA;AAAA,EACA,0BAAA;AAAA,EACA,cAAA;AAAA,EACA,0BAAA;AACD,EAAA;AAEa,IAAA,sBAAA,GAAyB,CAAC,aAAA,EAAe,YAAY,EAAA;ACd3D,IAAM,UAAA,GAAa,CAAC,IAAyB,KAAA;AACnD,EAAO,OAAA,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,OAAO,CAAC,IAAA,KAAS,IAAS,KAAA,EAAE,CAAE,CAAA,MAAA,CAAA;AACtD,CAAA,CAAA;AAEO,IAAM,UAAA,GAAa,CAAC,SAA+B,KAAA;AACzD,EAAI,IAAA;AACH,IAAA,OAAO,OAAQ,CAAA,IAAI,GAAI,CAAA,SAAS,CAAC,CAAA,CAAA;AAAA,WACzB,EAAI,EAAA;AACZ,IAAO,OAAA,KAAA,CAAA;AAAA,GACR;AACD,CAAA,CAAA;AAEO,IAAM,yBAAA,GAA4B,CAAC,OAA6B,KAAA;AACtE,EAAM,MAAA,aAAA,GAAgB,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA,CAAA;AACzD,EACC,OAAA,aAAA,EAAe,KAAM,CAAA,CAAC,IAAS,KAAA;AAC9B,IAAM,MAAA,GAAG,QAAA,EAAU,OAAO,CAAA,GACzB,MAAO,CAAA,oBAAoB,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA,IAAK,EAAC,CAAA;AAE7C,IACC,IAAA,QAAA,IACA,WACA,sBAAuB,CAAA,QAAA,CAAS,QAAQ,CACxC,IAAA,CAAC,UAAW,CAAA,OAAO,CAClB,EAAA;AACD,MAAO,OAAA,IAAA,CAAA;AAAA,KACR;AAEA,IAAA,IAAI,OAAW,IAAA,CAAC,OAAQ,CAAA,UAAA,CAAW,GAAG,CAAG,EAAA;AACxC,MAAA,MAAM,qBAAqB,IAAI,MAAA;AAAA,QAC9B,CAAuB,oBAAA,EAAA,mBAAA,CAAoB,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,OACrD,CAAA;AACA,MAAO,OAAA,kBAAA,CAAmB,KAAK,OAAO,CAAA,CAAA;AAAA,KACvC;AACA,IAAO,OAAA,IAAA,CAAA;AAAA,GACP,CAAK,IAAA,IAAA,CAAA;AAER,CAAA,CAAA;AAKO,IAAM,mBAAA,GAAsB,CAAC,KAA4B,KAAA;AAC/D,EAAO,OAAA,KAAA,CAAM,KAAM,CAAA,CAAC,IAAS,KAAA;AAC5B,IACC,IAAA,IAAA,CAAK,WAAW,WAAY,CAAA,IAAA,CAAK,YACjC,IAAK,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,QAChC,EAAA;AACD,MAAO,OAAA,IAAA,CAAK,GAAG,MAAW,KAAA,gBAAA,CAAA;AAAA,KAC3B;AAEA,IAAA,IAAI,IAAK,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,OAAS,EAAA;AAC7C,MAAA,MAAM,cACL,GAAA,2EAAA,CAAA;AACD,MACC,OAAA,IAAA,CAAK,OAAO,CAAmC,gCAAA,EAAA,IAAA,CAAK,IAAI,CACxD,CAAA,IAAA,cAAA,CAAe,IAAK,CAAA,IAAA,CAAK,EAAE,CAAA,CAAA;AAAA,KAE7B;AAEA,IAAA,IAAI,IAAK,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,KAAO,EAAA;AAC3C,MAAA,OAAO,IAAK,CAAA,EAAA,KAAO,CAAqB,kBAAA,EAAA,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA;AAAA,KAClD;AAEA,IAAA,OAAO,IAAK,CAAA,IAAA,GAAO,IAAK,CAAA,IAAA,IAAQ,SAAY,GAAA,IAAA,CAAA;AAAA,GAC5C,CAAA,CAAA;AACF,CAAA,CAAA;AAEO,IAAM,wBAAA,GAA2B,CAAC,KAA4B,KAAA;AACpE,EAAA,MAAM,iBAAiB,KAAM,CAAA,MAAA;AAAA,IAC5B,CAAC,IAAA,KAAS,IAAK,CAAA,IAAA,KAAS,UAAU,IAAK,CAAA,IAAA;AAAA,GACtC,CAAA,MAAA,CAAA;AACF,EAAO,OAAA,KAAA,CAAM,MAAU,IAAA,eAAA,IAAmB,cAAkB,IAAA,CAAA,CAAA;AAC7D,CAAA,CAAA;AAEO,IAAM,2BAAA,GAA8B,CAAC,KAA4B,KAAA;AACvE,EAAA,OAAO,mBAAoB,CAAA,KAAK,CAAK,IAAA,wBAAA,CAAyB,KAAK,CAAA,CAAA;AACpE,CAAA,CAAA;AAKO,IAAM,gBAAA,GAAmB,CAAC,IAAuB,KAAA;AACvD,EAAI,IAAA,IAAA,CAAK,KAAK,IAAK,CAAA,CAAC,QAAa,GAAI,CAAA,EAAA,KAAO,QAAQ,CAAG,EAAA;AACtD,IAAM,MAAA,cAAA,GACL,KAAK,QAAS,CAAA,IAAA;AAAA,MACb,CAAC,IAAA,KAAc,IAAK,CAAA,EAAA,KAAO,cAAc,IAAK,CAAA,UAAA;AAAA,OAC5C,KAAS,IAAA,IAAA,CAAA;AACb,IAAA,MAAM,aAAwC,IAAK,CAAA,KAAA;AAAA,MAClD,cAAA;AAAA,KACD,CAAA;AACA,IAAA,MAAM,eAAe,UAAW,CAAA,IAAA;AAAA,MAC/B,CAAC,IAAA,KAAS,IAAK,CAAA,WAAA,CAAY,aAAkB,KAAA,YAAA;AAAA,KAC9C,CAAA;AACA,IAAO,OAAA,YAAA,IAAgB,MAAM,OAAQ,CAAA,IAAA,CAAK,MAAM,CAAK,IAAA,IAAA,CAAK,OAAO,MAAS,GAAA,CAAA,CAAA;AAAA,GAC3E;AACA,EAAO,OAAA,IAAA,CAAA;AACR,CAAA,CAAA;AAEO,IAAM,mBAAA,GAAsB,CAAC,OAA6B,KAAA;AAChE,EAAO,OAAA,UAAA,CAAW,OAAO,CAAK,IAAA,sBAAA,CAAA;AAC/B,CAAA,CAAA;AAKO,IAAM,sBAAA,GAAyB,CAAC,QAAkC,KAAA;AACxE,EAAM,MAAA,cAAA,GACL,QAAS,CAAA,IAAA,CAAK,CAAC,IAAA,KAAS,IAAK,CAAA,EAAA,KAAO,aAAc,CAAA,IAAA,CAAK,UAAU,CAAA,EAAG,KACpE,IAAA,IAAA,CAAA;AACD,EAAM,MAAA,UAAA,GAAa,IAAK,CAAA,KAAA,CAAM,cAAc,CAAA,CAAA;AAC5C,EAAA,OAAO,WAAW,MAAS,GAAA,CAAA,CAAA;AAC5B,CAAA,CAAA;AAEO,IAAM,2BAAA,GAA8B,OAC1C,QACsB,KAAA;AACtB,EAAM,MAAA,SAAA,GAAY,MAAM,YAAa,EAAA,CAAA;AACrC,EAAM,MAAA,QAAA,uBAAe,GAAI,CAAA;AAAA,IACxB,GAAG,aAAc,CAAA,OAAA;AAAA,IACjB,GAAG,mBAAoB,CAAA,OAAA;AAAA,IACvB,GAAG,SAAU,CAAA,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,EAAE,CAAA;AAAA,GAC5B,CAAA,CAAA;AAED,EAAA,OAAO,QAAS,CAAA,KAAA;AAAA,IACf,CAAC,IACA,KAAA,QAAA,CAAS,IAAI,IAAK,CAAA,EAAE,MACnB,CAAC,SAAA,CAAU,IAAK,CAAA,CAAC,MAAM,CAAE,CAAA,EAAA,KAAO,KAAK,EAAE,CAAA,IACtC,WAAW,IAAK,CAAA,KAAK,CACrB,IAAA,IAAI,IAAI,IAAK,CAAA,KAAK,EAAE,MACnB,KAAA,IAAI,IAAI,SAAU,CAAA,IAAA,CAAK,CAAC,CAAA,KAAM,EAAE,EAAO,KAAA,IAAA,CAAK,EAAE,CAAG,EAAA,OAAA,IAAW,EAAE,CAC5D,CAAA,MAAA,CAAA;AAAA,GACP,CAAA;AACD,CAAA,CAAA;AAKO,IAAM,sBAAA,GAAyB,CACrC,IACmB,KAAA;AACnB,EAAA,OAAO,KACL,MAAO,CAAA,CAAC,QAAQ,GAAI,CAAA,SAAA,CAAU,IAAI,EAAE,CAAA,CAAE,OAAO,CAAA,CAC7C,IAAI,CAAC,GAAA,MAAS,EAAE,EAAI,EAAA,GAAA,CAAI,IAAY,CAAA,CAAA,CAAA;AACvC,CAAA,CAAA;AAKA,eAAsB,YAAoC,GAAA;AACzD,EAAA,MAAM,KAAQ,GAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAAA,CAAA,CAAA;AAWd,EAAM,MAAA,MAAA,GAAS,MAAM,MAAO,CAAA;AAAA,IAC3B,OAAS,EAAA,sCAAA;AAAA,IACT,OAAS,EAAA;AAAA,MACR,cAAgB,EAAA,kBAAA;AAAA,KACjB;AAAA,GACA,CAAA,CAAA;AAGD,EAAA,MAAM,EAAE,IAAK,EAAA,GAAI,MAAM,MAAA,CAAO,KAAiB,EAAI,EAAA;AAAA,IAClD,KAAA;AAAA,IACA,SAAW,EAAA;AAAA,MACV,MAAQ,EAAA,CAAA;AAAA,MACR,KAAO,EAAA,EAAA;AAAA,KACR;AAAA,GACA,CAAA,CAAA;AAED,EAAO,OAAA,IAAA,CAAA;AACR,CAAA;;;ACnLO,IAAM,YAAY,CAAE,CAAA,IAAA,CAAK,CAAC,SAAA,EAAW,MAAM,CAAC,EAAA;AAGtC,IAAA,WAAA,GAAc,EAAE,IAAK,CAAA,CAAC,YAAY,OAAS,EAAA,SAAA,EAAW,UAAU,CAAC,EAAA;AAGjE,IAAA,aAAA,GAAgB,EAAE,IAAK,CAAA;AAAA,EACnC,YAAA;AAAA,EACA,SAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,iBAAA;AAAA,EACA,kBAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,gBAAA;AAAA,EACA,4BAAA;AACD,CAAC,EAAA;AAGM,IAAM,sBAAsB,CAAE,CAAA,IAAA,CAAK,CAAC,cAAA,EAAgB,gBAAgB,CAAC,EAAA;AAG/D,IAAA,cAAA,GAAiB,EAAE,IAAK,CAAA;AAAA,EACpC,YAAA;AAAA,EACA,UAAA;AAAA,EACA,gBAAA;AAAA,EACA,YAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,eAAA;AAAA,EACA,aAAA;AAAA,EACA,WAAA;AAAA,EACA,oBAAA;AAAA,EACA,gBAAA;AAAA,EACA,aAAA;AAAA,EACA,mBAAA;AAAA,EACA,cAAA;AAAA,EACA,cAAA;AACD,CAAC,EAAA;AAGY,IAAA,YAAA,GAAe,EAAE,IAAK,CAAA,CAAC,MAAM,IAAM,EAAA,IAAA,EAAM,IAAI,CAAC,EAAA;AAGpD,IAAM,gBAAgB,CAAE,CAAA,IAAA,CAAK,CAAC,UAAY,EAAA,aAAA,EAAe,UAAU,CAAC,EAAA;AAGpE,IAAM,YAAY,CAAE,CAAA,IAAA,CAAK,CAAC,SAAW,EAAA,SAAA,EAAW,WAAW,CAAC,EAAA;AAGtD,IAAA,GAAA,GAAM,EAAE,IAAK,CAAA;AAAA,EACzB,SAAA;AAAA,EACA,IAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,aAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,OAAA;AAAA,EACA,YAAA;AAAA,EACA,eAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,UAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,WAAA;AAAA,EACA,cAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAA;AAAA,EACA,QAAA;AAAA,EACA,cAAA;AAAA,EACA,UAAA;AAAA,EACA,SAAA;AAAA,EACA,WAAA;AAAA,EACA,QAAA;AAAA,EACA,UAAA;AAAA,EACA,aAAA;AAAA,EACA,SAAA;AACD,CAAC,EAAA;AAGY,IAAA,QAAA,GAAW,EAAE,IAAK,CAAA;AAAA,EAC9B,MAAA;AAAA,EACA,MAAA;AAAA,EACA,WAAA;AAAA,EACA,kBAAA;AAAA,EACA,MAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,eAAA;AACD,CAAC,EAAA;AASY,IAAA,YAAA,GAAe,EAAE,MAAO,CAAA;AAAA,EACpC,OAAS,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EAC7B,OAAS,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EAC7B,SAAW,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAChC,CAAC,EAAA;AAGY,IAAA,WAAA,GAAc,EAAE,MAAO,CAAA;AAAA,EACnC,EAAI,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EACxB,QAAU,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EAC9B,GAAK,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EACzB,KAAO,EAAA,CAAA,CAAE,KAAM,CAAA,YAAY,EAAE,QAAS,EAAA;AAAA,EACtC,MAAQ,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EAC5B,MAAQ,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAC7B,CAAC,EAAA;AAGY,IAAA,KAAA,GAAQ,EAAE,MAAO,CAAA;AAAA,EAC7B,EAAA,EAAI,EAAE,MAAO,EAAA;AAAA,EACb,IAAA,EAAM,EAAE,MAAO,EAAA;AAChB,CAAC,EAAA;AAGY,IAAA,KAAA,GAAQ,EAAE,MAAO,CAAA;AAAA,EAC7B,EAAA,EAAI,EAAE,MAAO,EAAA;AAAA,EACb,IAAM,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACzB,IAAM,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACzB,IAAA,EAAM,UAAU,OAAQ,EAAA;AAAA,EACxB,OAAS,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAC5B,SAAW,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAC9B,MAAQ,EAAA,WAAA;AACT,CAAC,EAAA;AAGD,IAAM,QAAA,GAAW,EAAE,MAAO,CAAA;AAAA,EACzB,EAAA,EAAI,EAAE,MAAO,EAAA;AAAA,EACb,KAAA,EAAO,EAAE,GAAI,EAAA;AACd,CAAC,CAAA,CAAA;AAGY,IAAA,YAAA,GAAe,EAAE,MAAO,CAAA;AAAA,EACpC,EAAI,EAAA,QAAA;AAAA,EACJ,KAAA,EAAO,EAAE,MAAO,EAAA;AACjB,CAAC,EAAA;AAGY,IAAA,UAAA,GAAa,EAAE,MAAO,CAAA;AAAA,EAClC,EAAI,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACvB,IAAM,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAS,EAAA;AAAA,EAC1B,KAAO,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAC1B,IAAA,EAAM,UAAU,QAAS,EAAA;AAAA,EACzB,WAAa,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAChC,IAAM,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACzB,cAAgB,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACnC,YAAc,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EACjC,SAAW,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAC9B,OAAS,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,OAAQ,EAAA;AAAA,EAC5B,MAAA,EAAQ,EAAE,IAAK,CAAA,CAAC,UAAU,MAAQ,EAAA,QAAQ,CAAC,CAAA,CAAE,OAAQ,EAAA;AACtD,CAAC,EAAA;AASY,IAAA,IAAA,GAAO,EAClB,MAAO,CAAA;AAAA,EACP,EAAA,EAAI,EAAE,MAAO,EAAA;AAAA,EACb,OAAO,CACL,CAAA,MAAA,GACA,GAAI,CAAA,CAAA,EAAG,kDAAkD,CACzD,CAAA,GAAA;AAAA,IACA,qBAAA;AAAA,IACA,6BAA6B,qBAAqB,CAAA,WAAA,CAAA;AAAA,GACnD;AAAA,EACD,SAAS,CACP,CAAA,MAAA,GACA,GAAI,CAAA,CAAA,EAAG,mCAAmC,CAC1C,CAAA,MAAA;AAAA,IACA,mBAAA;AAAA,IACA,oBAAoB,sBAAsB,CAAA,yCAAA,CAAA;AAAA,GAE1C,CAAA,MAAA;AAAA,IACA,yBAAA;AAAA,IACA,mDAAA;AAAA,GACD;AAAA,EACD,OAAA,EAAS,CACP,CAAA,MAAA,EACA,CAAA,GAAA;AAAA,IACA,uBAAA;AAAA,IACA,oCAAoC,uBAAuB,CAAA,CAAA;AAAA,GAC5D;AAAA,EACD,QAAQ,CACN,CAAA,KAAA,CAAM,KAAK,CACX,CAAA,GAAA,CAAI,GAAG,kDAAkD,CAAA;AAAA,EAC3D,YAAY,CAAE,CAAA,KAAA,CAAM,YAAY,CAAE,CAAA,GAAA,CAAI,GAAG,8BAA8B,CAAA;AAAA,EACvE,IAAM,EAAA,CAAA,CACJ,KAAM,CAAA,CAAA,CAAE,OAAO,EAAE,EAAA,EAAI,CAAE,CAAA,MAAA,EAAS,EAAC,CAAC,CAAA,CAClC,UAAU,sBAAsB,CAAA;AAAA,EAClC,KAAO,EAAA,CAAA,CACL,KAAM,CAAA,KAAK,CACX,CAAA,GAAA,CAAI,eAAe,CAAA,CACnB,MAAO,CAAA,2BAAA,EAA6B,kBAAkB,CAAA,CACtD,QAAS,EAAA;AAAA,EACX,QAAA,EAAU,EACR,KAAM,CAAA,QAAQ,EACd,MAAO,CAAA,sBAAA,EAAwB,kCAAkC,CACjE,CAAA,MAAA;AAAA,IACA,2BAAA;AAAA,IACA,2CAAA;AAAA,GACD;AAAA,EACD,MAAQ,EAAA,CAAA,CAAE,KAAM,CAAA,UAAU,EAAE,OAAQ,EAAA;AAAA,EACpC,IAAA,EAAM,EAAE,MAAO,CAAA,EAAE,IAAI,CAAE,CAAA,MAAA,IAAU,CAAA;AAAA,EACjC,MAAA,EAAQ,EAAE,MAAO,CAAA,EAAE,IAAI,CAAE,CAAA,MAAA,IAAU,CAAA;AAAA,EACnC,QAAU,EAAA,YAAA,CAAa,OAAQ,CAAA,YAAA,CAAa,KAAK,EAAE,CAAA;AAAA,EACnD,OAAS,EAAA,CAAA,CAAE,MAAO,EAAA,CAAE,QAAQ,CAAC,CAAA;AAAA,EAC7B,WAAA,EAAa,EACX,MAAO,CAAA;AAAA,IACP,CAAC,aAAc,CAAA,IAAA,CAAK,WAAW,GAAG,CAAE,CAAA,KAAA,CAAM,CAAE,CAAA,MAAA,EAAQ,CAAA,CAAE,OAAQ,EAAA;AAAA,IAC9D,CAAC,aAAc,CAAA,IAAA,CAAK,QAAQ,GAAG,CAAE,CAAA,KAAA,CAAM,CAAE,CAAA,MAAA,EAAQ,CAAA,CAAE,OAAQ,EAAA;AAAA,IAC3D,CAAC,aAAc,CAAA,IAAA,CAAK,QAAQ,GAAG,CAAE,CAAA,KAAA,CAAM,CAAE,CAAA,MAAA,EAAQ,CAAA,CAAE,OAAQ,EAAA;AAAA,GAC3D,CACA,CAAA,OAAA,EACA,CAAA,OAAA,CAAQ,EAAE,CAAA;AACb,CAAC,CAAA,CACA,OAAO,gBAAkB,EAAA;AAAA,EACzB,OACC,EAAA,0EAAA;AAAA,EACD,IAAA,EAAM,CAAC,QAAQ,CAAA;AAChB,CAAC,EAAA;AAIW,IAAA,SAAA,GAAY,EAAE,MAAO,CAAA;AAAA,EACjC,EAAA,EAAI,EAAE,MAAO,EAAA;AAAA,EACb,WAAA,EAAa,EAAE,MAAO,EAAA;AAAA,EACtB,SAAA,EAAW,EAAE,MAAO,EAAA;AAAA,EACpB,GAAA,EAAK,EAAE,MAAO,EAAA;AACf,CAAC,EAAA;;;AClQD,IAAM,cAAA,GAAiB,CAAC,SAA8B,KAAA;AACrD,EAAA,MAAM,QAAW,GAAA,CAAA,CAAA;AACjB,EAAA,MAAM,QAAW,GAAA,CAAA,CAAA;AAEjB,EAAA,IAAI,KAAQ,GAAA,CAAA,CAAA;AAEZ,EAAA,IAAI,YAAY,sBAAwB,EAAA;AACvC,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EACC,IAAA,SAAA,IAAa,sBACb,IAAA,SAAA,IAAa,uBACZ,EAAA;AACD,IAAA,KAAA,GAAQ,SAAY,GAAA,uBAAA,CAAA;AACpB,IAAS,KAAA,IAAA,GAAA,CAAA;AAAA,GACV;AAEA,EACC,IAAA,SAAA,GAAY,uBACZ,IAAA,SAAA,GAAY,wBACX,EAAA;AACD,IAAA,MAAM,SAAY,GAAA,GAAA,CAAA;AAClB,IAAA,MAAM,qBAAqB,SAAY,GAAA,uBAAA,CAAA;AACvC,IAAM,MAAA,gBAAA,GACL,sBAAsB,wBAA2B,GAAA,uBAAA,CAAA,CAAA;AAClD,IAAA,MAAM,UAAa,GAAA,IAAA,CAAK,IAAK,CAAA,gBAAgB,CAAI,GAAA,GAAA,CAAA;AACjD,IAAA,KAAA,GAAQ,SAAY,GAAA,UAAA,CAAA;AAAA,GACrB;AAEA,EAAA,IAAI,aAAa,wBAA0B,EAAA;AAC1C,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EAAA,IAAI,QAAQ,QAAU,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EAAA,IAAI,QAAQ,QAAU,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EAAO,OAAA,KAAA,CAAA;AACR,CAAA,CAAA;AAEA,IAAM,YAAA,GAAe,CAAC,UAAA,EAAoB,SAA8B,KAAA;AACvE,EAAA,MAAM,QAAW,GAAA,CAAA,CAAA;AACjB,EAAA,MAAM,QAAW,GAAA,CAAA,CAAA;AAEjB,EAAA,MAAM,QAAQ,SAAY,GAAA,UAAA,CAAA;AAE1B,EAAA,IAAI,QAAQ,QAAU,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EAAA,IAAI,QAAQ,QAAU,EAAA;AACrB,IAAO,OAAA,QAAA,CAAA;AAAA,GACR;AAEA,EAAO,OAAA,KAAA,CAAA;AACR,CAAA,CAAA;AAEA,IAAM,oBAAA,GAAuB,CAAC,GAAgB,KAAA;AAC7C,EAAA,MAAM,OAAU,GAAA,MAAA,CAAO,mCAAmC,CAAA,CAAE,KAAK,GAAG,CAAA,CAAA;AACpE,EAAA,OAAO,UAAU,CAAC,CAAA,CAAA;AACnB,CAAA,CAAA;AAEA,IAAM,oBAAA,GAAuB,CAAC,OAA4B,KAAA;AACzD,EAAA,MAAM,iBAAoB,GAAA,qBAAA,CAAA;AAC1B,EAAA,IAAI,kBAAqB,GAAA,CAAA,CAAA;AACzB,EAAI,IAAA,KAAA,GAAQ,iBAAkB,CAAA,IAAA,CAAK,OAAO,CAAA,CAAA;AAE1C,EAAA,OAAO,UAAU,IAAM,EAAA;AACtB,IAAM,MAAA,GAAA,GAAM,MAAM,CAAC,CAAA,CAAA;AACnB,IAAA,IAAI,GAAO,IAAA,CAAC,GAAI,CAAA,UAAA,CAAW,GAAG,CAAG,EAAA;AAChC,MAAM,MAAA,QAAA,GAAW,qBAAqB,GAAG,CAAA,CAAA;AACzC,MAAA,IACC,aAAa,gBACb,IAAA,QAAA,KAAa,aACb,QAAU,EAAA,QAAA,CAAS,iBAAiB,CACnC,EAAA;AACD,QAAA,kBAAA,EAAA,CAAA;AAAA,OACD;AAAA,KACD;AACA,IAAQ,KAAA,GAAA,iBAAA,CAAkB,KAAK,OAAO,CAAA,CAAA;AAAA,GACvC;AAEA,EAAO,OAAA,kBAAA,CAAA;AACR,CAAA,CAAA;AAEA,IAAM,oBAAA,GAAuB,CAAC,IAAe,KAAA;AAC5C,EAAM,MAAA,iBAAA,GAAoB,KAAK,QAAS,CAAA,IAAA;AAAA,IACvC,CAAC,CAAA,KAAM,CAAE,CAAA,EAAA,KAAO,cAAc,IAAK,CAAA,UAAA;AAAA,GACjC,EAAA,KAAA,CAAA;AAEH,EAAA,IACC,sBAAsB,KACtB,CAAA,IAAA,iBAAA,EAAmB,IAAK,EAAA,CAAE,WAAW,CACpC,EAAA;AACD,IAAO,OAAA,CAAA,CAAA;AAAA,GACR;AAEA,EAAM,MAAA,cAAA,GAAiB,IAAK,CAAA,KAAA,CAAM,iBAAiB,CAAA,CAAA;AAEnD,EAAA,OAAO,cAAe,CAAA,MAAA,CAAA;AACvB,CAAA,CAAA;AAEA,IAAM,eAAA,GAAkB,CAAC,IAAuB,KAAA;AAC/C,EAAA,IAAI,YAAe,GAAA,CAAA,CAAA;AACnB,EAAW,KAAA,MAAA,IAAA,IAAQ,KAAK,QAAU,EAAA;AACjC,IAAA,IACC,aAAc,CAAA,OAAA,CAAQ,QAAS,CAAA,IAAA,CAAK,EAAqC,CACxE,EAAA;AACD,MAAA,IAAI,KAAK,KAAO,EAAA;AACf,QAAgB,YAAA,IAAA,CAAA,CAAA;AAAA,OACjB;AAAA,KACD;AAAA,GACD;AACA,EAAO,OAAA,YAAA,CAAA;AACR,CAAA,CAAA;AAEa,IAAA,kBAAA,GAAqB,CAAC,IAAuB,KAAA;AACzD,EAAA,MAAM,SAAY,GAAA,IAAA,CAAK,OAAQ,CAAA,KAAA,CAAM,GAAG,CAAE,CAAA,MAAA,CAAA;AAC1C,EAAM,MAAA,kBAAA,GAAqB,oBAAqB,CAAA,IAAA,CAAK,OAAO,CAAA,CAAA;AAC5D,EAAM,MAAA,aAAA,GAAgB,qBAAqB,IAAI,CAAA,CAAA;AAC/C,EAAM,MAAA,UAAA,GAAa,IAAK,CAAA,KAAA,EAAO,MAAU,IAAA,CAAA,CAAA;AACzC,EAAM,MAAA,SAAA,GAAY,IAAK,CAAA,IAAA,EAAM,MAAU,IAAA,CAAA,CAAA;AACvC,EAAM,MAAA,gBAAA,GAAmB,IAAK,CAAA,OAAA,EAAS,MAAU,IAAA,CAAA,CAAA;AACjD,EAAM,MAAA,YAAA,GAAe,gBAAgB,IAAI,CAAA,CAAA;AAEzC,EAAM,MAAA,YAAA,GAAe,eAAe,SAAS,CAAA,CAAA;AAC7C,EAAA,MAAM,kBAAqB,GAAA,YAAA;AAAA,IAC1B,0BAAA;AAAA,IACA,kBAAA;AAAA,GACD,CAAA;AACA,EAAM,MAAA,aAAA,GAAgB,YAAa,CAAA,qBAAA,EAAuB,aAAa,CAAA,CAAA;AACvE,EAAM,MAAA,UAAA,GAAa,YAAa,CAAA,iBAAA,EAAmB,UAAU,CAAA,CAAA;AAC7D,EAAM,MAAA,SAAA,GAAY,YAAa,CAAA,gBAAA,EAAkB,SAAS,CAAA,CAAA;AAC1D,EAAM,MAAA,YAAA,GAAe,YAAa,CAAA,oBAAA,EAAsB,gBAAgB,CAAA,CAAA;AACxE,EAAM,MAAA,YAAA,GAAe,YAAa,CAAA,wBAAA,EAA0B,YAAY,CAAA,CAAA;AAExE,EAAA,MAAM,eACL,oBACA,GAAA,2BAAA,GACA,sBACA,GAAA,kBAAA,GACA,oBACA,oBACA,GAAA,mBAAA,CAAA;AAED,EAAA,MAAM,KACJ,GAAA,CAAA,YAAA,GAAe,oBACf,GAAA,kBAAA,GAAqB,8BACrB,aAAgB,GAAA,sBAAA,GAChB,UAAa,GAAA,kBAAA,GACb,SAAY,GAAA,iBAAA,GACZ,YAAe,GAAA,oBAAA,GACf,eAAe,mBAChB,IAAA,YAAA,CAAA;AAED,EAAA,MAAM,YAAe,GAAA,IAAA,CAAK,KAAM,CAAA,KAAA,GAAQ,GAAG,CAAA,CAAA;AAC3C,EAAO,OAAA,YAAA,CAAA;AACR,EAAA;;;ACrKO,IAAMA,WAAa,GAAA,CAAC,IAC1B,KAAA,IAAA,CAAK,KAAM,CAAA,GAAG,CAAE,CAAA,MAAA,CAAO,CAAC,IAAA,KAAS,IAAS,KAAA,EAAE,CAAE,CAAA,OAAA;AAOlCC,IAAAA,WAAAA,GAAa,CAAC,SAAsB,KAAA;AAChD,EAAI,IAAA;AACH,IAAA,OAAO,OAAQ,CAAA,IAAI,GAAI,CAAA,SAAS,CAAC,CAAA,CAAA;AAAA,WACzB,EAAI,EAAA;AACZ,IAAO,OAAA,KAAA,CAAA;AAAA,GACR;AACD,EAAA;AAOa,IAAA,uBAAA,GAA0B,CAAC,OAAoB,KAAA;AAC3D,EAAM,MAAA,aAAA,GAAgB,OAAQ,CAAA,KAAA,CAAM,qBAAqB,CAAA,CAAA;AACzD,EACC,OAAA,aAAA,EAAe,KAAM,CAAA,CAAC,IAAS,KAAA;AAC9B,IAAM,MAAA,GAAG,QAAA,EAAU,OAAO,CAAA,GACzB,MAAO,CAAA,oBAAoB,CAAE,CAAA,IAAA,CAAK,IAAI,CAAA,IAAK,EAAC,CAAA;AAE7C,IACC,IAAA,QAAA,IACA,WACA,sBAAuB,CAAA,QAAA,CAAS,QAAQ,CACxC,IAAA,CAACA,WAAW,CAAA,OAAO,CAClB,EAAA;AACD,MAAO,OAAA,IAAA,CAAA;AAAA,KACR;AAEA,IAAA,IAAI,OAAW,IAAA,CAAC,OAAQ,CAAA,UAAA,CAAW,GAAG,CAAG,EAAA;AACxC,MAAA,MAAM,qBAAqB,IAAI,MAAA;AAAA,QAC9B,CAAuB,oBAAA,EAAA,mBAAA,CAAoB,IAAK,CAAA,GAAG,CAAC,CAAA,CAAA,CAAA;AAAA,OACrD,CAAA;AACA,MAAO,OAAA,kBAAA,CAAmB,KAAK,OAAO,CAAA,CAAA;AAAA,KACvC;AACA,IAAO,OAAA,IAAA,CAAA;AAAA,GACP,CAAK,IAAA,IAAA,CAAA;AAER,EAAA;AAOa,IAAA,YAAA,GAAe,CAAC,IAAe,KAAA;AAC3C,EAAI,IAAA,CAAC,IAAK,CAAA,KAAA,EAAc,OAAA,IAAA,CAAA;AAExB,EAAA,MAAMC,oBAAsB,GAAA,IAAA,CAAK,KAAM,CAAA,KAAA,CAAM,CAAC,KAAU,KAAA;AACvD,IACC,IAAA,KAAA,CAAM,WAAW,WAAY,CAAA,IAAA,CAAK,YAClC,KAAM,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,QACjC,EAAA;AACD,MAAO,OAAA,KAAA,CAAM,GAAG,MAAW,KAAA,gBAAA,CAAA;AAAA,KAC5B;AAEA,IAAA,IAAI,KAAM,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,OAAS,EAAA;AAC9C,MAAA,MAAM,cACL,GAAA,2EAAA,CAAA;AACD,MACC,OAAA,KAAA,CAAM,OAAO,CAAmC,gCAAA,EAAA,KAAA,CAAM,IAAI,CAC1D,CAAA,IAAA,cAAA,CAAe,IAAK,CAAA,KAAA,CAAM,EAAE,CAAA,CAAA;AAAA,KAE9B;AAEA,IAAA,IAAI,KAAM,CAAA,MAAA,KAAW,WAAY,CAAA,IAAA,CAAK,KAAO,EAAA;AAC5C,MAAA,OAAO,KAAM,CAAA,EAAA,KAAO,CAAqB,kBAAA,EAAA,KAAA,CAAM,IAAI,CAAA,CAAA,CAAA;AAAA,KACpD;AAEA,IAAA,OAAO,MAAM,IAAO,GAAA,SAAA,CAAU,QAAQ,QAAS,CAAA,KAAA,CAAM,IAAI,CAAI,GAAA,IAAA,CAAA;AAAA,GAC7D,CAAA,CAAA;AAED,EAAM,MAAA,cAAA,GAAiB,KAAK,KAAM,CAAA,MAAA;AAAA,IACjC,CAAC,KAAA,KAAU,KAAM,CAAA,IAAA,KAAS,UAAU,IAAK,CAAA,IAAA;AAAA,GACxC,CAAA,MAAA,CAAA;AAEF,EAAA,OACC,IAAK,CAAA,KAAA,CAAM,MAAU,IAAA,eAAA,IACrBA,wBACA,cAAkB,IAAA,CAAA,CAAA;AAEpB,EAAA;AAOO,IAAM,mBAAsB,GAAA,CAAC,IACnC,KAAA,IAAA,CAAK,KAAO,EAAA,IAAA,CAAK,CAAC,KAAA,KAAU,KAAM,CAAA,EAAA,CAAG,QAAS,CAAA,2BAA2B,CAAC,CAC1E,IAAA,MAAA;AAOY,IAAA,iBAAA,GAAoB,CAAC,IAAe,KAAA;AAChD,EAAI,IAAA,IAAA,CAAK,KAAK,IAAK,CAAA,CAAC,QAAQ,GAAI,CAAA,EAAA,KAAO,QAAQ,CAAG,EAAA;AACjD,IAAA,MAAM,cACL,GAAA,IAAA,CAAK,QAAS,CAAA,IAAA,CAAK,CAAC,IAAA,KAAS,IAAK,CAAA,EAAA,KAAO,aAAc,CAAA,IAAA,CAAK,UAAU,CAAA,EACnE,KAAS,IAAA,IAAA,CAAA;AACb,IAAM,MAAA,UAAA,GAAa,IAAK,CAAA,KAAA,CAAM,cAAc,CAAA,CAAA;AAC5C,IAAA,OAAO,CAAC,UAAW,CAAA,IAAA;AAAA,MAClB,CAAC,IAAA,KACA,IAAK,CAAA,WAAA,CAAY,aAAkB,KAAA,YAAA;AAAA,KACrC,CAAA;AAAA,GACD;AACA,EAAO,OAAA,KAAA,CAAA;AACR,EAAA;AAOO,IAAM,kBAAqB,GAAA,CAAC,IAClC,KAAA,IAAA,CAAK,KAAK,IAAK,CAAA,CAAC,GAAQ,KAAA,GAAA,CAAI,EAAO,KAAA,QAAQ,CAAK,IAAA,IAAA,CAAK,QAAQ,MAAW,KAAA,EAAA;AAO5D,IAAA,gBAAA,GAAmB,CAAC,IAChC,KAAA,CAAC,EAAE,IAAK,CAAA,OAAA,IAAW,IAAK,CAAA,OAAA,CAAQ,MAAS,GAAA,uBAAA,EAAA;AAO7B,IAAA,cAAA,GAAiB,CAAC,IAAe,KAAA;AAC7C,EAAM,MAAA,UAAA,GAAa,KAAK,QAAS,CAAA,IAAA;AAAA,IAChC,CAAC,IAAA,KAAS,IAAK,CAAA,EAAA,KAAO,cAAc,IAAK,CAAA,UAAA;AAAA,GAC1C,CAAA;AACA,EAAA,OAAO,CAAC,UAAA,EAAY,KAAS,IAAA,UAAA,CAAW,MAAM,MAAW,KAAA,CAAA,CAAA;AAC1D,EAAA;AAOa,IAAA,YAAA,GAAe,CAAC,IAAe,KAAA;AAC3C,EAAA,MAAM,SAAYF,GAAAA,WAAAA,CAAW,IAAK,CAAA,OAAA,IAAW,EAAE,CAAA,CAAA;AAE/C,EAAI,IAAA,CAAC,KAAK,KAAO,EAAA;AAChB,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,kDAAA;AAAA,KACR,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,IAAA,CAAK,KAAM,CAAA,MAAA,GAAS,qBAAuB,EAAA;AAC9C,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAA,EAAO,6BAA6B,qBAAqB,CAAA,WAAA,CAAA;AAAA,KAC1D,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,CAAC,KAAK,OAAS,EAAA;AAClB,IAAA,OAAO,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,mCAAoC,EAAA,CAAA;AAAA,GACrE;AAEA,EAAA,IAAI,YAAY,sBAAwB,EAAA;AACvC,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,CAAA,iBAAA,EAAoB,sBAAsB,CAAA,4DAAA,EAA+D,SAAS,CAAA,CAAA;AAAA,KAC1H,CAAA;AAAA,GACD;AAEA,EAAA,IAAI,CAAC,uBAAA,CAAwB,IAAK,CAAA,OAAO,CAAG,EAAA;AAC3C,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,mDAAA;AAAA,KACR,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,CAAC,IAAK,CAAA,MAAA,EAAQ,MAAQ,EAAA;AACzB,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,kDAAA;AAAA,KACR,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,IAAA,CAAK,UAAW,CAAA,MAAA,KAAW,CAAG,EAAA;AACjC,IAAA,OAAO,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,8BAA+B,EAAA,CAAA;AAAA,GAChE;AAEA,EAAI,IAAA,gBAAA,CAAiB,IAAI,CAAG,EAAA;AAC3B,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAA,EAAO,oCAAoC,uBAAuB,CAAA,CAAA;AAAA,KACnE,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,mBAAA,CAAoB,IAAI,CAAG,EAAA;AAC9B,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KAAO,EAAA,6CAAA;AAAA,KACR,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,cAAA,CAAe,IAAI,CAAG,EAAA;AACzB,IAAA,OAAO,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,kCAAmC,EAAA,CAAA;AAAA,GACpE;AAEA,EAAI,IAAA,iBAAA,CAAkB,IAAI,CAAG,EAAA;AAC5B,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KACC,EAAA,sEAAA;AAAA,KACF,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,kBAAA,CAAmB,IAAI,CAAG,EAAA;AAC7B,IAAO,OAAA;AAAA,MACN,OAAS,EAAA,KAAA;AAAA,MACT,KACC,EAAA,wEAAA;AAAA,KACF,CAAA;AAAA,GACD;AAEA,EAAI,IAAA,CAAC,YAAa,CAAA,IAAI,CAAG,EAAA;AACxB,IAAA,OAAO,EAAE,OAAA,EAAS,KAAO,EAAA,KAAA,EAAO,kBAAmB,EAAA,CAAA;AAAA,GACpD;AAEA,EAAO,OAAA,EAAE,SAAS,IAAK,EAAA,CAAA;AACxB","file":"index.mjs","sourcesContent":["export const WIKI_SUMMARY_MAX_LENGTH = 255;\nexport const WIKI_CONTENT_MIN_WORDS = 100;\nexport const WIKI_TITLE_MAX_LENGTH = 60;\nexport const MEDIA_UPLOAD_PENDING_SUFFIX = \"default\";\nexport const MAX_MEDIA_COUNT = 25;\nexport const IPFS_HASH_LENGTH = 46;\nexport const EditorContentOverride = \"%OVERRIDE@EDITOR@MARKDOWN%\";\nexport const CreateNewWikiSlug = \"/*CREATE+NEW+WIKI*/\";\n\nexport const MIN_CONTENT_WORD_COUNT = 10;\nexport const GOOD_CONTENT_WORD_COUNT = 500;\nexport const IDEAL_CONTENT_WORD_COUNT = 1500;\n\nexport const CONTENT_SCORE_WEIGHT = 0.8;\nexport const INTERNAL_LINKS_SCORE_WEIGHT = 0.5;\nexport const CITATIONS_SCORE_WEIGHT = 0.5;\nexport const MEDIA_SCORE_WEIGHT = 0.3;\nexport const TAGS_SCORE_WEIGHT = 0.3;\nexport const SUMMARY_SCORE_WEIGHT = 0.5;\nexport const SOCIAL_SCORE_WEIGHT = 0.5;\n\nexport const IDEAL_INTERNAL_LINKS_COUNT = 10;\nexport const IDEAL_CITATIONS_COUNT = 10;\nexport const IDEAL_MEDIA_COUNT = 5;\nexport const IDEAL_TAGS_COUNT = 3;\nexport const IDEAL_SUMMARY_LENGTH = 100;\nexport const IDEAL_SOCIAL_MEDIA_COUNT = 4;\n\nexport const WHITELISTED_DOMAINS = [\n\t\"youtube.com/watch\",\n\t\"youtu.be\",\n\t\"vimeo.com\",\n\t\"alpha.everipedia.org/wiki\",\n\t\"beta.everipedia.org/wiki\",\n\t\"iq.wiki/wiki\",\n\t\"ipfs.everipedia.org/ipfs\",\n];\n\nexport const WHITELISTED_LINK_NAMES = [\"YOUTUBE@VID\", \"DUNE@EMBED\"];\n","import type { z } from \"zod\";\n\nimport {\n\tIPFS_HASH_LENGTH,\n\tMAX_MEDIA_COUNT,\n\tWHITELISTED_DOMAINS,\n\tWHITELISTED_LINK_NAMES,\n\tWIKI_CONTENT_MIN_WORDS,\n} from \"../data/constants\";\nimport {\n\tCommonMetaIds,\n\tEditSpecificMetaIds,\n\ttype Media,\n\tMediaSource,\n\tMediaType,\n\ttype MetaData,\n\tTag,\n} from \"../schema\";\nimport axios from \"axios\";\n\n// ===============================\n// Text and content helpers\n// ===============================\n\nexport const countWords = (text: string): number => {\n\treturn text.split(\" \").filter((word) => word !== \"\").length;\n};\n\nexport const isValidUrl = (urlString: string): boolean => {\n\ttry {\n\t\treturn Boolean(new URL(urlString));\n\t} catch (_e) {\n\t\treturn false;\n\t}\n};\n\nexport const containsOnlyVerifiedLinks = (content: string): boolean => {\n\tconst markdownLinks = content.match(/\\[(.*?)\\]\\((.*?)\\)/g);\n\treturn (\n\t\tmarkdownLinks?.every((link) => {\n\t\t\tconst [, linkText, linkUrl] =\n\t\t\t\tRegExp(/\\[(.*?)\\]\\((.*?)\\)/).exec(link) || [];\n\n\t\t\tif (\n\t\t\t\tlinkText &&\n\t\t\t\tlinkUrl &&\n\t\t\t\tWHITELISTED_LINK_NAMES.includes(linkText) &&\n\t\t\t\t!isValidUrl(linkUrl)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (linkUrl && !linkUrl.startsWith(\"#\")) {\n\t\t\t\tconst validDomainPattern = new RegExp(\n\t\t\t\t\t`^https?://(www\\\\.)?(${WHITELISTED_DOMAINS.join(\"|\")})`,\n\t\t\t\t);\n\t\t\t\treturn validDomainPattern.test(linkUrl);\n\t\t\t}\n\t\t\treturn true;\n\t\t}) ?? true\n\t);\n};\n\n// ===============================\n// Media validation helpers\n// ===============================\nexport const isMediaContentValid = (media: Media[]): boolean => {\n\treturn media.every((item) => {\n\t\tif (\n\t\t\titem.source === MediaSource.Enum.IPFS_IMG ||\n\t\t\titem.source === MediaSource.Enum.IPFS_VID\n\t\t) {\n\t\t\treturn item.id.length === IPFS_HASH_LENGTH;\n\t\t}\n\n\t\tif (item.source === MediaSource.Enum.YOUTUBE) {\n\t\t\tconst youtubePattern =\n\t\t\t\t/^.*(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/|watch\\?v=)([^#&?]*).*/;\n\t\t\treturn (\n\t\t\t\titem.id === `https://www.youtube.com/watch?v=${item.name}` &&\n\t\t\t\tyoutubePattern.test(item.id)\n\t\t\t);\n\t\t}\n\n\t\tif (item.source === MediaSource.Enum.VIMEO) {\n\t\t\treturn item.id === `https://vimeo.com/${item.name}`;\n\t\t}\n\n\t\treturn item.type ? item.type in MediaType : true;\n\t});\n};\n\nexport const isMediaCountWithinLimits = (media: Media[]): boolean => {\n\tconst iconMediaCount = media.filter(\n\t\t(item) => item.type === MediaType.Enum.ICON,\n\t).length;\n\treturn media.length <= MAX_MEDIA_COUNT && iconMediaCount <= 1;\n};\n\nexport const isMediaContentAndCountValid = (media: Media[]): boolean => {\n\treturn isMediaContentValid(media) && isMediaCountWithinLimits(media);\n};\n\n// ===============================\n// Wiki-specific validation helpers\n// ===============================\nexport const isEventWikiValid = (wiki: any): boolean => {\n\tif (wiki.tags.some((tag: any) => tag.id === \"Events\")) {\n\t\tconst referencesData =\n\t\t\twiki.metadata.find(\n\t\t\t\t(meta: any) => meta.id === CommonMetaIds.Enum.references,\n\t\t\t)?.value || \"[]\";\n\t\tconst references: { description: string }[] = JSON.parse(\n\t\t\treferencesData,\n\t\t) as { description: string }[];\n\t\tconst hasEventLink = references.some(\n\t\t\t(item) => item.description.toLowerCase() === \"event link\",\n\t\t);\n\t\treturn hasEventLink && Array.isArray(wiki.events) && wiki.events.length > 0;\n\t}\n\treturn true;\n};\n\nexport const hasMinimumWordCount = (content: string): boolean => {\n\treturn countWords(content) >= WIKI_CONTENT_MIN_WORDS;\n};\n\n// ===============================\n// Metadata helpers\n// ===============================\nexport const hasAtLeastOneReference = (metadata: MetaData[]): boolean => {\n\tconst referencesData =\n\t\tmetadata.find((meta) => meta.id === CommonMetaIds.Enum.references)?.value ||\n\t\t\"[]\";\n\tconst references = JSON.parse(referencesData) as { description: string }[];\n\treturn references.length > 0;\n};\n\nexport const areMetadataAndExplorerValid = async (\n\tmetadata: MetaData[],\n): Promise<boolean> => {\n\tconst explorers = await getExplorers();\n\tconst validIds = new Set([\n\t\t...CommonMetaIds.options,\n\t\t...EditSpecificMetaIds.options,\n\t\t...explorers.map((e) => e.id),\n\t]);\n\n\treturn metadata.every(\n\t\t(meta) =>\n\t\t\tvalidIds.has(meta.id) &&\n\t\t\t(!explorers.some((e) => e.id === meta.id) ||\n\t\t\t\t(isValidUrl(meta.value) &&\n\t\t\t\t\tnew URL(meta.value).origin ===\n\t\t\t\t\t\tnew URL(explorers.find((e) => e.id === meta.id)?.baseUrl || \"\")\n\t\t\t\t\t\t\t.origin)),\n\t);\n};\n\n// ===============================\n// Tag helpers\n// ===============================\nexport const transformAndFilterTags = (\n\ttags: { id: string }[],\n): { id: Tag }[] => {\n\treturn tags\n\t\t.filter((tag) => Tag.safeParse(tag.id).success)\n\t\t.map((tag) => ({ id: tag.id as Tag }));\n};\n\n// ===============================\n// API-related helpers\n// ===============================\nexport async function getExplorers(): Promise<Explorer[]> {\n\tconst query = `\n query ExplorersList($offset: Int!, $limit: Int!) {\n explorers(offset: $offset, limit: $limit) {\n id\n baseUrl\n explorer\n hidden\n }\n }\n `;\n\n\tconst client = axios.create({\n\t\tbaseURL: \"https://graph.everipedia.org/graphql\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t});\n\n\t// TODO: make sure to fetch all explorers here. currently only fetching first 30 explorers\n\tconst { data } = await client.post<Explorer[]>(\"\", {\n\t\tquery,\n\t\tvariables: {\n\t\t\toffset: 0,\n\t\t\tlimit: 30,\n\t\t},\n\t});\n\n\treturn data;\n}\n\n// ===============================\n// Types\n// ===============================\ninterface WikiEventData {\n\ttags: { id: z.infer<typeof Tag> }[];\n\tmetadata: { id: string; value?: string }[];\n\tevents?: unknown[];\n}\n\ninterface Explorer {\n\tid: string;\n\tbaseUrl: string;\n\texplorer: string;\n\thidden: boolean;\n}\n","import { z } from \"zod\";\n\nimport {\n\tMAX_MEDIA_COUNT,\n\tWIKI_CONTENT_MIN_WORDS,\n\tWIKI_SUMMARY_MAX_LENGTH,\n\tWIKI_TITLE_MAX_LENGTH,\n} from \"../data/constants\";\nimport {\n\tareMetadataAndExplorerValid,\n\tcontainsOnlyVerifiedLinks,\n\thasAtLeastOneReference,\n\thasMinimumWordCount,\n\tisEventWikiValid,\n\tisMediaContentAndCountValid,\n\ttransformAndFilterTags,\n} from \"../lib/wiki-helpers\";\n\n/**\n * ========================\n * ===== Enum Schemas =====\n * ========================\n */\nexport const MediaType = z.enum([\"GALLERY\", \"ICON\"]);\nexport type MediaType = z.infer<typeof MediaType>;\n\nexport const MediaSource = z.enum([\"IPFS_IMG\", \"VIMEO\", \"YOUTUBE\", \"IPFS_VID\"]);\nexport type MediaSource = z.infer<typeof MediaSource>;\n\nexport const CommonMetaIds = z.enum([\n\t\"references\",\n\t\"website\",\n\t\"contract_url\",\n\t\"location\",\n\t\"email_url\",\n\t\"facebook_profile\",\n\t\"instagram_profile\",\n\t\"twitter_profile\",\n\t\"linkedin_profile\",\n\t\"youtube_profile\",\n\t\"discord_profile\",\n\t\"reddit_profile\",\n\t\"telegram_profile\",\n\t\"github_profile\",\n\t\"coinmarketcap_url\",\n\t\"coingecko_profile\",\n\t\"opensea_profile\",\n\t\"medium_profile\",\n\t\"mirror_profile\",\n\t\"tiktok_profile\",\n\t\"explorer_injective_profile\",\n]);\nexport type CommonMetaIds = z.infer<typeof CommonMetaIds>;\n\nexport const EditSpecificMetaIds = z.enum([\"previous_cid\", \"commit-message\"]);\nexport type EditSpecificMetaIds = z.infer<typeof EditSpecificMetaIds>;\n\nexport const ValidatorCodes = z.enum([\n\t\"VALID_WIKI\",\n\t\"ID_ERROR\",\n\t\"LANGUAGE_ERROR\",\n\t\"USER_ERROR\",\n\t\"WORD_COUNT_ERROR\",\n\t\"CATEGORY_ERROR\",\n\t\"SUMMARY_ERROR\",\n\t\"IMAGE_ERROR\",\n\t\"TAG_ERROR\",\n\t\"EXTERNAL_URL_ERROR\",\n\t\"METADATA_ERROR\",\n\t\"MEDIA_ERROR\",\n\t\"GLOBAL_RATE_LIMIT\",\n\t\"LINKED_WIKIS\",\n\t\"EVENTS_ERROR\",\n]);\nexport type ValidatorCodes = z.infer<typeof ValidatorCodes>;\n\nexport const LanguagesISO = z.enum([\"en\", \"es\", \"zh\", \"ko\"]);\nexport type LanguagesISO = z.infer<typeof LanguagesISO>;\n\nexport const LinkedWikiKey = z.enum([\"founders\", \"blockchains\", \"speakers\"]);\nexport type LinkedWikiKey = z.infer<typeof LinkedWikiKey>;\n\nexport const EventType = z.enum([\"CREATED\", \"DEFAULT\", \"MULTIDATE\"]);\nexport type EventType = z.infer<typeof EventType>;\n\nexport const Tag = z.enum([\n\t\"Artists\",\n\t\"AI\",\n\t\"BinanceSmartChain\",\n\t\"Blockchains\",\n\t\"CEXes\",\n\t\"Collections\",\n\t\"Collectors\",\n\t\"Conference\",\n\t\"DEXes\",\n\t\"Developers\",\n\t\"Entertainment\",\n\t\"Ethereum\",\n\t\"Events\",\n\t\"Forum\",\n\t\"Founders\",\n\t\"Festival\",\n\t\"Games\",\n\t\"Glossary\",\n\t\"Hackathon\",\n\t\"Marketplaces\",\n\t\"Memecoins\",\n\t\"Organizations\",\n\t\"Online\",\n\t\"PeopleInDeFi\",\n\t\"Polkadot\",\n\t\"Polygon\",\n\t\"Protocols\",\n\t\"Solana\",\n\t\"Speakers\",\n\t\"Stablecoins\",\n\t\"Venture\",\n]);\nexport type Tag = z.infer<typeof Tag>;\n\nexport const Category = z.enum([\n\t\"nfts\",\n\t\"defi\",\n\t\"exchanges\",\n\t\"cryptocurrencies\",\n\t\"daos\",\n\t\"people\",\n\t\"dapps\",\n\t\"organizations\",\n]);\nexport type Category = z.infer<typeof Category>;\n\n/**\n * ==============================\n * ===== Supporting Schemas =====\n * ==============================\n */\n\nexport const ProfileLinks = z.object({\n\ttwitter: z.string().nullable(),\n\twebsite: z.string().nullable(),\n\tinstagram: z.string().nullable(),\n});\nexport type ProfileLinks = z.infer<typeof ProfileLinks>;\n\nexport const ProfileData = z.object({\n\tid: z.string().nullable(),\n\tusername: z.string().nullable(),\n\tbio: z.string().nullable(),\n\tlinks: z.array(ProfileLinks).nullable(),\n\tbanner: z.string().nullable(),\n\tavatar: z.string().nullable(),\n});\nexport type ProfileData = z.infer<typeof ProfileData>;\n\nexport const Image = z.object({\n\tid: z.string(),\n\ttype: z.string(),\n});\nexport type Image = z.infer<typeof Image>;\n\nexport const Media = z.object({\n\tid: z.string(),\n\tsize: z.string().nullish(),\n\tname: z.string().nullish(),\n\ttype: MediaType.nullish(),\n\tcaption: z.string().nullish(),\n\tthumbnail: z.string().nullish(),\n\tsource: MediaSource,\n});\nexport type Media = z.infer<typeof Media>;\n\nconst MetaData = z.object({\n\tid: z.string(),\n\tvalue: z.any(),\n});\nexport type MetaData = z.infer<typeof MetaData>;\n\nexport const BaseCategory = z.object({\n\tid: Category,\n\ttitle: z.string(),\n});\nexport type BaseCategory = z.infer<typeof BaseCategory>;\n\nexport const BaseEvents = z.object({\n\tid: z.string().nullish(),\n\tdate: z.string().nullable(),\n\ttitle: z.string().nullish(),\n\ttype: EventType.nullable(),\n\tdescription: z.string().nullish(),\n\tlink: z.string().nullish(),\n\tmultiDateStart: z.string().nullish(),\n\tmultiDateEnd: z.string().nullish(),\n\tcontinent: z.string().nullish(),\n\tcountry: z.string().nullish(),\n\taction: z.enum([\"DELETE\", \"EDIT\", \"CREATE\"]).nullish(),\n});\nexport type BaseEvents = z.infer<typeof BaseEvents>;\n\n/**\n * ========================\n * ===== Core Schemas =====\n * ========================\n */\n\nexport const Wiki = z\n\t.object({\n\t\tid: z.string(),\n\t\ttitle: z\n\t\t\t.string()\n\t\t\t.min(1, \"Add a Title at the top for this Wiki to continue\")\n\t\t\t.max(\n\t\t\t\tWIKI_TITLE_MAX_LENGTH,\n\t\t\t\t`Title should be less than ${WIKI_TITLE_MAX_LENGTH} characters`,\n\t\t\t),\n\t\tcontent: z\n\t\t\t.string()\n\t\t\t.min(1, \"Add a Content section to continue\")\n\t\t\t.refine(\n\t\t\t\thasMinimumWordCount,\n\t\t\t\t`Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue`,\n\t\t\t)\n\t\t\t.refine(\n\t\t\t\tcontainsOnlyVerifiedLinks,\n\t\t\t\t\"Please remove all external links from the content\",\n\t\t\t),\n\t\tsummary: z\n\t\t\t.string()\n\t\t\t.max(\n\t\t\t\tWIKI_SUMMARY_MAX_LENGTH,\n\t\t\t\t`Summary exceeds maximum limit of ${WIKI_SUMMARY_MAX_LENGTH}`,\n\t\t\t),\n\t\timages: z\n\t\t\t.array(Image)\n\t\t\t.min(1, \"Add a main image on the right column to continue\"),\n\t\tcategories: z.array(BaseCategory).min(1, \"Add one category to continue\"),\n\t\ttags: z\n\t\t\t.array(z.object({ id: z.string() }))\n\t\t\t.transform(transformAndFilterTags),\n\t\tmedia: z\n\t\t\t.array(Media)\n\t\t\t.max(MAX_MEDIA_COUNT)\n\t\t\t.refine(isMediaContentAndCountValid, \"Media is invalid\")\n\t\t\t.optional(),\n\t\tmetadata: z\n\t\t\t.array(MetaData)\n\t\t\t.refine(hasAtLeastOneReference, \"Please add at least one citation\")\n\t\t\t.refine(\n\t\t\t\tareMetadataAndExplorerValid,\n\t\t\t\t\"Invalid metadata Ids or explorer metadata\",\n\t\t\t),\n\t\tevents: z.array(BaseEvents).nullish(),\n\t\tuser: z.object({ id: z.string() }),\n\t\tauthor: z.object({ id: z.string() }),\n\t\tlanguage: LanguagesISO.default(LanguagesISO.Enum.en),\n\t\tversion: z.number().default(1),\n\t\tlinkedWikis: z\n\t\t\t.object({\n\t\t\t\t[LinkedWikiKey.Enum.blockchains]: z.array(z.string()).nullish(),\n\t\t\t\t[LinkedWikiKey.Enum.founders]: z.array(z.string()).nullish(),\n\t\t\t\t[LinkedWikiKey.Enum.speakers]: z.array(z.string()).nullish(),\n\t\t\t})\n\t\t\t.nullish()\n\t\t\t.default({}),\n\t})\n\t.refine(isEventWikiValid, {\n\t\tmessage:\n\t\t\t\"Event wikis must have an event link citation and at least one event date\",\n\t\tpath: [\"events\"],\n\t});\n\nexport type Wiki = z.infer<typeof Wiki>;\n\nexport const Reference = z.object({\n\tid: z.string(),\n\tdescription: z.string(),\n\ttimestamp: z.number(),\n\turl: z.string(),\n});\nexport type Reference = z.infer<typeof Reference>;\n","import {\n\tCITATIONS_SCORE_WEIGHT,\n\tCONTENT_SCORE_WEIGHT,\n\tGOOD_CONTENT_WORD_COUNT,\n\tIDEAL_CITATIONS_COUNT,\n\tIDEAL_CONTENT_WORD_COUNT,\n\tIDEAL_INTERNAL_LINKS_COUNT,\n\tIDEAL_MEDIA_COUNT,\n\tIDEAL_SOCIAL_MEDIA_COUNT,\n\tIDEAL_SUMMARY_LENGTH,\n\tIDEAL_TAGS_COUNT,\n\tINTERNAL_LINKS_SCORE_WEIGHT,\n\tMEDIA_SCORE_WEIGHT,\n\tMIN_CONTENT_WORD_COUNT,\n\tSOCIAL_SCORE_WEIGHT,\n\tSUMMARY_SCORE_WEIGHT,\n\tTAGS_SCORE_WEIGHT,\n} from \"../data/constants\";\nimport { CommonMetaIds, type Wiki } from \"../schema\";\n\nconst contentQuality = (wordCount: number): number => {\n\tconst scoreMin = 0.0;\n\tconst scoreMax = 1.0;\n\n\tlet score = 0;\n\n\tif (wordCount < MIN_CONTENT_WORD_COUNT) {\n\t\treturn scoreMin;\n\t}\n\n\tif (\n\t\twordCount >= MIN_CONTENT_WORD_COUNT &&\n\t\twordCount <= GOOD_CONTENT_WORD_COUNT\n\t) {\n\t\tscore = wordCount / GOOD_CONTENT_WORD_COUNT;\n\t\tscore *= 0.8;\n\t}\n\n\tif (\n\t\twordCount > GOOD_CONTENT_WORD_COUNT &&\n\t\twordCount < IDEAL_CONTENT_WORD_COUNT\n\t) {\n\t\tconst baseScore = 0.8;\n\t\tconst wordCountAboveGood = wordCount - GOOD_CONTENT_WORD_COUNT;\n\t\tconst extraScoreFactor =\n\t\t\twordCountAboveGood / (IDEAL_CONTENT_WORD_COUNT - GOOD_CONTENT_WORD_COUNT);\n\t\tconst extraScore = Math.sqrt(extraScoreFactor) * 0.2;\n\t\tscore = baseScore + extraScore;\n\t}\n\n\tif (wordCount >= IDEAL_CONTENT_WORD_COUNT) {\n\t\treturn scoreMax;\n\t}\n\n\tif (score < scoreMin) {\n\t\treturn scoreMin;\n\t}\n\n\tif (score > scoreMax) {\n\t\treturn scoreMax;\n\t}\n\n\treturn score;\n};\n\nconst countQuality = (idealCount: number, realCount: number): number => {\n\tconst scoreMin = 0.0;\n\tconst scoreMax = 1.0;\n\n\tconst score = realCount / idealCount;\n\n\tif (score < scoreMin) {\n\t\treturn scoreMin;\n\t}\n\n\tif (score > scoreMax) {\n\t\treturn scoreMax;\n\t}\n\n\treturn score;\n};\n\nconst getHostnameFromRegex = (url: string) => {\n\tconst matches = RegExp(/^https?:\\/\\/([^/?#]+)(?:[/?#]|$)/i).exec(url);\n\treturn matches?.[1];\n};\n\nconst getWikiInternalLinks = (content: string): number => {\n\tconst markdownLinkRegex = /\\[(.*?)\\]\\((.*?)\\)/g;\n\tlet internalLinksCount = 0;\n\tlet match = markdownLinkRegex.exec(content);\n\n\twhile (match !== null) {\n\t\tconst url = match[2];\n\t\tif (url && !url.startsWith(\"#\")) {\n\t\t\tconst hostname = getHostnameFromRegex(url);\n\t\t\tif (\n\t\t\t\thostname === \"everipedia.org\" ||\n\t\t\t\thostname === \"iq.wiki\" ||\n\t\t\t\thostname?.endsWith(\".everipedia.org\")\n\t\t\t) {\n\t\t\t\tinternalLinksCount++;\n\t\t\t}\n\t\t}\n\t\tmatch = markdownLinkRegex.exec(content); // Move assignment here\n\t}\n\n\treturn internalLinksCount;\n};\n\nconst getWikiCitationLinks = (wiki: Wiki) => {\n\tconst rawWikiReferences = wiki.metadata.find(\n\t\t(m) => m.id === CommonMetaIds.Enum.references,\n\t)?.value;\n\n\tif (\n\t\trawWikiReferences === undefined ||\n\t\trawWikiReferences?.trim().length === 0\n\t) {\n\t\treturn 0;\n\t}\n\n\tconst wikiReferences = JSON.parse(rawWikiReferences);\n\n\treturn wikiReferences.length;\n};\n\nconst getSocialsCount = (wiki: Wiki): number => {\n\tlet socialsCount = 0;\n\tfor (const meta of wiki.metadata) {\n\t\tif (\n\t\t\tCommonMetaIds.options.includes(meta.id as keyof typeof CommonMetaIds.enum)\n\t\t) {\n\t\t\tif (meta.value) {\n\t\t\t\tsocialsCount += 1;\n\t\t\t}\n\t\t}\n\t}\n\treturn socialsCount;\n};\n\nexport const calculateWikiScore = (wiki: Wiki): number => {\n\tconst wordCount = wiki.content.split(\" \").length;\n\tconst internalLinksCount = getWikiInternalLinks(wiki.content);\n\tconst citationCount = getWikiCitationLinks(wiki);\n\tconst mediaCount = wiki.media?.length || 0;\n\tconst tagsCount = wiki.tags?.length || 0;\n\tconst summaryWordCount = wiki.summary?.length || 0;\n\tconst socialsCount = getSocialsCount(wiki);\n\n\tconst contentScore = contentQuality(wordCount);\n\tconst internalLinksScore = countQuality(\n\t\tIDEAL_INTERNAL_LINKS_COUNT,\n\t\tinternalLinksCount,\n\t);\n\tconst citationScore = countQuality(IDEAL_CITATIONS_COUNT, citationCount);\n\tconst mediaScore = countQuality(IDEAL_MEDIA_COUNT, mediaCount);\n\tconst tagsScore = countQuality(IDEAL_TAGS_COUNT, tagsCount);\n\tconst summaryScore = countQuality(IDEAL_SUMMARY_LENGTH, summaryWordCount);\n\tconst socialsScore = countQuality(IDEAL_SOCIAL_MEDIA_COUNT, socialsCount);\n\n\tconst sumOfWeights =\n\t\tCONTENT_SCORE_WEIGHT +\n\t\tINTERNAL_LINKS_SCORE_WEIGHT +\n\t\tCITATIONS_SCORE_WEIGHT +\n\t\tMEDIA_SCORE_WEIGHT +\n\t\tTAGS_SCORE_WEIGHT +\n\t\tSUMMARY_SCORE_WEIGHT +\n\t\tSOCIAL_SCORE_WEIGHT;\n\n\tconst score =\n\t\t(contentScore * CONTENT_SCORE_WEIGHT +\n\t\t\tinternalLinksScore * INTERNAL_LINKS_SCORE_WEIGHT +\n\t\t\tcitationScore * CITATIONS_SCORE_WEIGHT +\n\t\t\tmediaScore * MEDIA_SCORE_WEIGHT +\n\t\t\ttagsScore * TAGS_SCORE_WEIGHT +\n\t\t\tsummaryScore * SUMMARY_SCORE_WEIGHT +\n\t\t\tsocialsScore * SOCIAL_SCORE_WEIGHT) /\n\t\tsumOfWeights;\n\n\tconst percentScore = Math.floor(score * 100);\n\treturn percentScore;\n};\n","import {\n\tIPFS_HASH_LENGTH,\n\tMAX_MEDIA_COUNT,\n\tMEDIA_UPLOAD_PENDING_SUFFIX,\n\tWIKI_CONTENT_MIN_WORDS,\n\tWIKI_SUMMARY_MAX_LENGTH,\n\tWIKI_TITLE_MAX_LENGTH,\n\tWHITELISTED_DOMAINS,\n\tWHITELISTED_LINK_NAMES,\n} from \"../data/constants\";\nimport { CommonMetaIds, MediaSource, MediaType, type Wiki } from \"../schema\";\n\n/**\n * Counts the number of words in a given string.\n * @param text - The input string to count words from.\n * @returns The number of words in the string.\n */\nexport const countWords = (text: string) =>\n\ttext.split(\" \").filter((word) => word !== \"\").length;\n\n/**\n * Checks if a given string is a valid URL.\n * @param urlString - The string to check.\n * @returns True if the string is a valid URL, false otherwise.\n */\nexport const isValidUrl = (urlString: string) => {\n\ttry {\n\t\treturn Boolean(new URL(urlString));\n\t} catch (_e) {\n\t\treturn false;\n\t}\n};\n\n/**\n * Checks if all content links in the given text are verified.\n * @param content - The content to check for links.\n * @returns True if all links are verified, false otherwise.\n */\nexport const areContentLinksVerified = (content: string) => {\n\tconst markdownLinks = content.match(/\\[(.*?)\\]\\((.*?)\\)/g);\n\treturn (\n\t\tmarkdownLinks?.every((link) => {\n\t\t\tconst [, linkText, linkUrl] =\n\t\t\t\tRegExp(/\\[(.*?)\\]\\((.*?)\\)/).exec(link) || [];\n\n\t\t\tif (\n\t\t\t\tlinkText &&\n\t\t\t\tlinkUrl &&\n\t\t\t\tWHITELISTED_LINK_NAMES.includes(linkText) &&\n\t\t\t\t!isValidUrl(linkUrl)\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (linkUrl && !linkUrl.startsWith(\"#\")) {\n\t\t\t\tconst validDomainPattern = new RegExp(\n\t\t\t\t\t`^https?://(www\\\\.)?(${WHITELISTED_DOMAINS.join(\"|\")})`,\n\t\t\t\t);\n\t\t\t\treturn validDomainPattern.test(linkUrl);\n\t\t\t}\n\t\t\treturn true;\n\t\t}) ?? true\n\t);\n};\n\n/**\n * Checks if the media in the wiki is valid.\n * @param wiki - The wiki object to check.\n * @returns True if the media is valid, false otherwise.\n */\nexport const isMediaValid = (wiki: Wiki) => {\n\tif (!wiki.media) return true;\n\n\tconst isMediaContentValid = wiki.media.every((media) => {\n\t\tif (\n\t\t\tmedia.source === MediaSource.Enum.IPFS_IMG ||\n\t\t\tmedia.source === MediaSource.Enum.IPFS_VID\n\t\t) {\n\t\t\treturn media.id.length === IPFS_HASH_LENGTH;\n\t\t}\n\n\t\tif (media.source === MediaSource.Enum.YOUTUBE) {\n\t\t\tconst youtubePattern =\n\t\t\t\t/^.*(?:youtu\\.be\\/|v\\/|vi\\/|u\\/\\w\\/|embed\\/|shorts\\/|watch\\?v=)([^#&?]*).*/;\n\t\t\treturn (\n\t\t\t\tmedia.id === `https://www.youtube.com/watch?v=${media.name}` &&\n\t\t\t\tyoutubePattern.test(media.id)\n\t\t\t);\n\t\t}\n\n\t\tif (media.source === MediaSource.Enum.VIMEO) {\n\t\t\treturn media.id === `https://vimeo.com/${media.name}`;\n\t\t}\n\n\t\treturn media.type ? MediaType.options.includes(media.type) : true;\n\t});\n\n\tconst iconMediaCount = wiki.media.filter(\n\t\t(media) => media.type === MediaType.Enum.ICON,\n\t).length;\n\n\treturn (\n\t\twiki.media.length <= MAX_MEDIA_COUNT &&\n\t\tisMediaContentValid &&\n\t\ticonMediaCount <= 1\n\t);\n};\n\n/**\n * Checks if any media in the wiki is still uploading.\n * @param wiki - The wiki object to check.\n * @returns True if any media is still uploading, false otherwise.\n */\nexport const isAnyMediaUploading = (wiki: Wiki) =>\n\twiki.media?.some((media) => media.id.endsWith(MEDIA_UPLOAD_PENDING_SUFFIX)) ??\n\tfalse;\n\n/**\n * Checks if the event URL is missing for an event wiki.\n * @param wiki - The wiki object to check.\n * @returns True if the event URL is missing, false otherwise.\n */\nexport const isEventUrlMissing = (wiki: Wiki) => {\n\tif (wiki.tags.some((tag) => tag.id === \"Events\")) {\n\t\tconst referencesData =\n\t\t\twiki.metadata.find((meta) => meta.id === CommonMetaIds.Enum.references)\n\t\t\t\t?.value || \"[]\";\n\t\tconst references = JSON.parse(referencesData);\n\t\treturn !references.some(\n\t\t\t(item: { description: string }) =>\n\t\t\t\titem.description.toLowerCase() === \"event link\",\n\t\t);\n\t}\n\treturn false;\n};\n\n/**\n * Checks if the event date is missing for an event wiki.\n * @param wiki - The wiki object to check.\n * @returns True if the event date is missing, false otherwise.\n */\nexport const isEventDateMissing = (wiki: Wiki) =>\n\twiki.tags.some((tag) => tag.id === \"Events\") && wiki.events?.length === 0;\n\n/**\n * Checks if the wiki summary exceeds the maximum length.\n * @param wiki - The wiki object to check.\n * @returns True if the summary exceeds the limit, false otherwise.\n */\nexport const isSummaryTooLong = (wiki: Wiki) =>\n\t!!(wiki.summary && wiki.summary.length > WIKI_SUMMARY_MAX_LENGTH);\n\n/**\n * Checks if the wiki has no citations.\n * @param wiki - The wiki object to check.\n * @returns True if there are no citations, false otherwise.\n */\nexport const hasNoCitations = (wiki: Wiki) => {\n\tconst references = wiki.metadata.find(\n\t\t(meta) => meta.id === CommonMetaIds.Enum.references,\n\t);\n\treturn !references?.value || references.value.length === 0;\n};\n\n/**\n * Validates a wiki object and returns the validation result.\n * @param wiki - The wiki object to validate.\n * @returns An object containing the validation result and an error message if applicable.\n */\nexport const validateWiki = (wiki: Wiki) => {\n\tconst wordCount = countWords(wiki.content || \"\");\n\n\tif (!wiki.title) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Add a Title at the top for this Wiki to continue\",\n\t\t};\n\t}\n\n\tif (wiki.title.length > WIKI_TITLE_MAX_LENGTH) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Title should be less than ${WIKI_TITLE_MAX_LENGTH} characters`,\n\t\t};\n\t}\n\n\tif (!wiki.content) {\n\t\treturn { isValid: false, error: \"Add a Content section to continue\" };\n\t}\n\n\tif (wordCount < WIKI_CONTENT_MIN_WORDS) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Add a minimum of ${WIKI_CONTENT_MIN_WORDS} words in the content section to continue. You have written ${wordCount}`,\n\t\t};\n\t}\n\n\tif (!areContentLinksVerified(wiki.content)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Please remove all external links from the content\",\n\t\t};\n\t}\n\n\tif (!wiki.images?.length) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Add a main image on the right column to continue\",\n\t\t};\n\t}\n\n\tif (wiki.categories.length === 0) {\n\t\treturn { isValid: false, error: \"Add one category to continue\" };\n\t}\n\n\tif (isSummaryTooLong(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: `Summary exceeds maximum limit of ${WIKI_SUMMARY_MAX_LENGTH}`,\n\t\t};\n\t}\n\n\tif (isAnyMediaUploading(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror: \"Some media are still uploading, please wait\",\n\t\t};\n\t}\n\n\tif (hasNoCitations(wiki)) {\n\t\treturn { isValid: false, error: \"Please add at least one citation\" };\n\t}\n\n\tif (isEventUrlMissing(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror:\n\t\t\t\t\"Please cite the event official website with 'Event Link' description\",\n\t\t};\n\t}\n\n\tif (isEventDateMissing(wiki)) {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terror:\n\t\t\t\t'Please open the \"Edit Wiki Details Modal\" and enter a valid event date',\n\t\t};\n\t}\n\n\tif (!isMediaValid(wiki)) {\n\t\treturn { isValid: false, error: \"Media is invalid\" };\n\t}\n\n\treturn { isValid: true };\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@everipedia/iq-utils",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "Common utility library for IQ projects",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -9,6 +9,7 @@
9
9
  "license": "MIT",
10
10
  "keywords": [],
11
11
  "dependencies": {
12
+ "axios": "^1.7.7",
12
13
  "zod": "^3.23.8"
13
14
  },
14
15
  "devDependencies": {
@@ -16,9 +17,9 @@
16
17
  "@changesets/cli": "^2.24.0",
17
18
  "@types/node": "^22.7.4",
18
19
  "changeset": "^0.2.6",
20
+ "lint-staged": "^15.2.10",
19
21
  "tsup": "^8.3.0",
20
- "typescript": "^4.7.4",
21
- "lint-staged": "^15.2.10"
22
+ "typescript": "^4.7.4"
22
23
  },
23
24
  "files": [
24
25
  "dist",