@atmosx/event-product-parser 3.0.622 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/.github/CHANGELOGS.md +52 -0
  2. package/.github/CODE_OF_CONDUCT.md +24 -1
  3. package/.github/CONTRIBUTING.md +22 -3
  4. package/.github/FUNDING.yaml +3 -0
  5. package/.github/LICENSE +24 -1
  6. package/.github/SECURITY.md +25 -6
  7. package/.github/docs/chapters/general-configurations.md +109 -0
  8. package/.github/docs/chapters/sources-and-attributes.md +219 -0
  9. package/README.md +56 -148
  10. package/dist/{cjs/index.cjs → index.cjs} +4486 -1471
  11. package/package.json +13 -8
  12. package/pnpm-workspace.yaml +1 -0
  13. package/src/bootstrap.ts +66 -51
  14. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  15. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  16. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  17. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  18. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  19. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  20. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  21. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +15 -8
  22. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  23. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  24. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  25. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  26. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  27. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  28. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  29. package/src/components/database/CreateQuery.ts +39 -0
  30. package/src/components/database/InitializeDatabase.ts +71 -0
  31. package/src/components/database/imports/Boundaires.ts +168 -0
  32. package/src/{@modules/@database/ImportBroadcastify.ts → components/database/imports/Broadcastify.ts} +15 -25
  33. package/src/components/database/imports/Census.ts +87 -0
  34. package/src/{@modules/@database/ImportShapefiles.ts → components/database/imports/Shapefiles.ts} +18 -21
  35. package/src/{@modules/@database/ImportStanza.ts → components/database/imports/Stanza.ts} +15 -19
  36. package/src/components/events/CreateEvents.ts +88 -0
  37. package/src/components/events/FilterEvents.ts +149 -0
  38. package/src/{@building/CreateEvent.ts → components/events/ProcessStanza.ts} +22 -22
  39. package/src/components/events/RemoveEvents.ts +74 -0
  40. package/src/{@building → components/events/components}/GetCleanedEvent.ts +2 -2
  41. package/src/{@building → components/events/components}/GetEventAttachments.ts +14 -12
  42. package/src/components/events/components/GetEventDirection.ts +28 -0
  43. package/src/{@building → components/events/components}/GetEventEnhancedName.ts +5 -6
  44. package/src/{@building → components/events/components}/GetEventGeometry.ts +19 -13
  45. package/src/{@building → components/events/components}/GetEventHeader.ts +13 -13
  46. package/src/components/events/components/GetEventMerged.ts +51 -0
  47. package/src/{@building → components/events/components}/GetEventNodes.ts +20 -18
  48. package/src/{@building → components/events/components}/GetEventOffice.ts +13 -13
  49. package/src/components/events/components/GetEventPopulation.ts +58 -0
  50. package/src/components/events/components/GetEventProperties.ts +106 -0
  51. package/src/{@building → components/events/components}/GetEventSignature.ts +9 -9
  52. package/src/{@building → components/events/components}/GetEventTags.ts +3 -3
  53. package/src/{@core/CreateListener.ts → components/events/components/GetEventTheme.ts} +8 -6
  54. package/src/components/events/components/GetEventTracking.ts +64 -0
  55. package/src/{@modules/@database → components/events/utilities}/GetCachedEvents.ts +18 -14
  56. package/src/{@manager → components/events/utilities}/SetHash.ts +18 -13
  57. package/src/{@manager → components/events/utilities}/UpdateEvents.ts +12 -12
  58. package/src/{@manager → components/events/utilities}/UpdateNode.ts +14 -14
  59. package/src/{@parsers/@text → components/formatting}/GetEmbededText.ts +12 -6
  60. package/src/{@parsers/@text → components/formatting}/GetStringText.ts +13 -9
  61. package/src/{@modules/@utilities → components/geometry}/GetShapeNearestPoint.ts +24 -19
  62. package/src/components/geometry/GetUnionPolygon.ts +36 -0
  63. package/src/components/images/GenerateGraphic.ts +242 -0
  64. package/src/components/images/components/CreateRectangle.ts +22 -0
  65. package/src/components/images/components/CreateText.ts +22 -0
  66. package/src/components/images/modules/CreateSVG.ts +37 -0
  67. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  68. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  69. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  70. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  71. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  72. package/src/components/images/modules/GetSVGPath.ts +53 -0
  73. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  74. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  75. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  76. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  77. package/src/components/utilities/EmitThread.ts +97 -0
  78. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  79. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  80. package/src/{@modules/@utilities → components/utilities}/QueueManager.ts +7 -8
  81. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +13 -13
  82. package/src/components/utilities/SetEventEmit.ts +42 -0
  83. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  84. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  85. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  86. package/src/components/utilities/SetWarning.ts +47 -0
  87. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  88. package/src/{@modules/@xmpp → components/xmpp}/ErrorXMPP.ts +6 -6
  89. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  90. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  91. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  92. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +26 -26
  93. package/src/{@enums → enums}/AWIPS.ts +2 -2
  94. package/src/{@enums → enums}/Actions.ts +2 -2
  95. package/src/{@enums → enums}/Cancellation.ts +2 -2
  96. package/src/{@enums → enums}/Causes.ts +2 -2
  97. package/src/{@enums → enums}/Correlations.ts +2 -2
  98. package/src/{@enums → enums}/Enhanced.ts +4 -3
  99. package/src/{@enums → enums}/Events.ts +2 -2
  100. package/src/{@enums → enums}/Expressions.ts +3 -3
  101. package/src/{@enums → enums}/GlobalFilter.ts +2 -2
  102. package/src/{@enums → enums}/Hail.ts +2 -2
  103. package/src/{@enums → enums}/ICAO.ts +2 -2
  104. package/src/{@enums → enums}/Matches.ts +8 -3
  105. package/src/{@enums → enums}/Products.ts +2 -2
  106. package/src/{@enums → enums}/Records.ts +2 -2
  107. package/src/{@enums → enums}/Severity.ts +2 -2
  108. package/src/{@enums → enums}/Shapefiles.ts +2 -2
  109. package/src/{@enums → enums}/States.ts +68 -4
  110. package/src/{@enums → enums}/Status.ts +2 -2
  111. package/src/{@enums → enums}/Strings.ts +2 -2
  112. package/src/{@enums → enums}/Tags.ts +8 -3
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +133 -0
  116. package/src/{@events → events}/ParseText.ts +24 -22
  117. package/src/{@events → events}/ParseUGC.ts +27 -26
  118. package/src/{@events → events}/ParseVTEC.ts +37 -36
  119. package/src/{@core → exports}/ClearEvents.ts +9 -9
  120. package/src/{@core → exports}/GetEvents.ts +4 -4
  121. package/src/exports/GetNearestCity.ts +45 -0
  122. package/src/{@core → exports}/GetNodes.ts +4 -4
  123. package/src/{@core → exports}/GetRandomEvent.ts +4 -4
  124. package/src/{@core → exports}/GetVersion.ts +4 -4
  125. package/src/{@core → exports}/ManualEvent.ts +24 -24
  126. package/src/{@core → exports}/QueryStanza.ts +12 -11
  127. package/src/exports/SetNode.ts +100 -0
  128. package/src/{@core → exports}/StartService.ts +22 -21
  129. package/src/{@core → exports}/StopService.ts +10 -10
  130. package/src/index.ts +55 -37
  131. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +7 -7
  132. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  133. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  134. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  135. package/src/parsers/ugc/GetCache.ts +24 -0
  136. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  137. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  138. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  139. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  140. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  141. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  142. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  143. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  144. package/src/{@parsers/@pvtec → parsers/vtec}/VTECExtract.ts +17 -17
  145. package/src/tasks/CreateTasks.ts +116 -0
  146. package/src/{@tasks → tasks}/TaskGenerateJSON.ts +10 -11
  147. package/src/{@tasks → tasks}/TaskGenerateText.ts +11 -12
  148. package/src/tasks/TaskSendNTFY.ts +96 -0
  149. package/src/tasks/TaskSendWebhook.ts +107 -0
  150. package/src/{@types → types/event}/Attributes.ts +2 -3
  151. package/src/{@types → types/event}/Event.ts +8 -7
  152. package/src/{@types → types/event}/HVTEC.ts +2 -2
  153. package/src/{@types → types/event}/Properties.ts +17 -4
  154. package/src/{@types → types/event}/Stanza.ts +2 -2
  155. package/src/{@types → types/event}/VTEC.ts +8 -8
  156. package/src/{@types → types/standard}/Actions.ts +3 -3
  157. package/src/{@types → types/standard}/Hash.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/standard/Nodes.ts} +15 -7
  159. package/src/{@types → types/standard}/Settings.ts +19 -12
  160. package/src/{@types → types/standard}/StanzaCompiled.ts +15 -15
  161. package/src/{@types → types/standard}/UGC.ts +5 -5
  162. package/tools/build.js +2 -15
  163. package/tsconfig.json +29 -17
  164. package/.github/SUPPORTED_EVENTS.md +0 -370
  165. package/.github/docs/docs-functions.md +0 -30
  166. package/.github/docs/docs-general-configurations.md +0 -209
  167. package/.github/docs/docs-integrations.md +0 -37
  168. package/.github/docs/docs-listeners.md +0 -28
  169. package/.github/docs/docs-source-configuration.md +0 -218
  170. package/.github/docs/docs-technical.md +0 -50
  171. package/.github/logo.png +0 -0
  172. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  173. package/.github/samples/SAMPLE_GEOJSON.json +0 -204
  174. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +0 -119
  175. package/dist/esm/index.mjs +0 -22298
  176. package/src/@building/GetEventProperties.ts +0 -101
  177. package/src/@building/GetEventTracking.ts +0 -68
  178. package/src/@core/SetNode.ts +0 -87
  179. package/src/@events/ParseAPI.ts +0 -122
  180. package/src/@manager/MakeEvents.ts +0 -109
  181. package/src/@manager/RemoveEvent.ts +0 -70
  182. package/src/@manager/ValidateEvents.ts +0 -141
  183. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  184. package/src/@modules/@eas/GenerateEASMessage.ts +0 -152
  185. package/src/@modules/@utilities/GetFormattedTime.ts +0 -43
  186. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  187. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  188. package/src/@modules/@utilities/SetListener.ts +0 -30
  189. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  190. package/src/@modules/@utilities/SetWarning.ts +0 -34
  191. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  192. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  193. package/src/@parsers/@text/GetXML.ts +0 -61
  194. package/src/@parsers/@ugc/GetCache.ts +0 -24
  195. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  196. package/src/@tasks/CreateTasks.ts +0 -110
  197. package/src/@tasks/TaskGenerateAudio.ts +0 -35
  198. package/src/@tasks/TaskSendNTFY.ts +0 -93
  199. package/src/@tasks/TaskSendWebhook.ts +0 -101
@@ -0,0 +1,71 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ export const GetPolygonFromProduct = (message: string): number[][] => {
21
+ const coordinates: number[][] = [];
22
+ const match = message.match(
23
+ /LAT\.\.\.LON\s+([\s\S]*?)(?=\n\s*(?:TIME\.\.\.MOT\.\.\.LOC|\$\$|[A-Za-z]|$))/i
24
+ );
25
+ if (!match) return coordinates;
26
+ const text = match[1]
27
+ .split(/\r?\n/).map(l => l.trim())
28
+ .filter(l => l && !/[A-Za-z]/.test(l))
29
+ .join(' ').trim();
30
+ if (!text) return coordinates;
31
+ const values = text.match(/\d{4,8}/g);
32
+ if (!values || values.length === 0) return coordinates;
33
+ const points: { lat: number; lon: number }[] = [];
34
+ if (values.every(v => v.length === 8)) {
35
+ for (const value of values) {
36
+ const lat = parseInt(value.slice(0, 4), 10) / 100;
37
+ let lon = parseInt(value.slice(4, 8), 10) / 100;
38
+ if (lon < 20) lon += 100;
39
+ points.push({ lat, lon });
40
+ }
41
+ } else if (values.every(v => v.length === 4)) {
42
+ for (let i = 0; i + 1 < values.length; i += 2) {
43
+ const lat = parseInt(values[i], 10) / 100;
44
+ const lon = parseInt(values[i + 1], 10) / 100;
45
+ points.push({ lat, lon });
46
+ }
47
+ } else {
48
+ for (let i = 0; i + 1 < values.length; i += 2) {
49
+ const latStr = values[i];
50
+ const lonStr = values[i + 1];
51
+ if (latStr.length !== 4) continue;
52
+ if (lonStr.length < 4 || lonStr.length > 5) continue;
53
+ const lat = parseInt(latStr, 10) / 100;
54
+ let lon = parseInt(lonStr, 10) / 100;
55
+ points.push({ lat, lon });
56
+ }
57
+ }
58
+ if (points.length === 0) return coordinates;
59
+ const isEast = points.some(p => p.lon > 130 && p.lon < 180);
60
+ for (const p of points) {
61
+ const lon = isEast ? p.lon : -p.lon;
62
+ if (Number.isFinite(p.lat) && Number.isFinite(lon) && p.lat >= -90 && p.lat <= 90 && lon >= -180 && lon <= 180) {
63
+ coordinates.push([lon, p.lat]);
64
+ }
65
+ }
66
+ if (coordinates.length > 2 && (coordinates[0][0] !== coordinates[coordinates.length - 1][0] || coordinates[0][1] !== coordinates[coordinates.length - 1][1])) {
67
+ coordinates.push([...coordinates[0]]);
68
+ }
69
+
70
+ return coordinates;
71
+ };
@@ -11,32 +11,32 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
20
  interface GetTextFromProductOptions {
21
- message: string
22
- find: string[]
23
- append?: string
24
- removal?: string[]
21
+ Message: string
22
+ Find: string[]
23
+ Append?: string
24
+ Removal?: string[]
25
25
  }
26
26
 
27
- export const GetTextFromProduct = (options: GetTextFromProductOptions): string => {
28
- const lines = options.message.split(`\n`);
27
+ export const GetTextFromProduct = ({ Message, Find, Append, Removal }: GetTextFromProductOptions): string => {
28
+ const lines = Message.split(`\n`);
29
29
  for (const line of lines) {
30
- const matchedFind = options.find.find((find) => line.includes(find));
30
+ const matchedFind = Find.find((find) => line.includes(find));
31
31
  if (matchedFind) {
32
32
  let result = line.slice(line.indexOf(matchedFind) + matchedFind.length).trim();
33
- if (options.removal) {
34
- for (const str of options.removal) {
33
+ if (Removal) {
34
+ for (const str of Removal) {
35
35
  result = result.toLowerCase().split(str.toLowerCase()).join('');
36
36
  }
37
37
  result = result.replace(matchedFind, '').replace('<', '').trim();
38
38
  }
39
- return result.toUpperCase() + (options?.append ?? ``);
39
+ return result.toUpperCase() + (Append ?? ``);
40
40
  }
41
41
  }
42
42
  return null;
@@ -0,0 +1,24 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { Bootstrap } from "@Bootstrap"
21
+
22
+ export const GetCache = (key: string) => {
23
+ return Bootstrap.Cache.UGC.get(key);
24
+ };
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
@@ -11,15 +11,15 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { EnumExpressions } from "@enums/Expressions"
20
+ import { EnumExpressions } from "@Enums/Expressions"
21
21
 
22
- export const getUGCHeader = (message: string): string | null => {
22
+ export const GetHeader = (message: string): string | null => {
23
23
  const start = message.search(EnumExpressions.ugc1)
24
24
  const sub = message.substring(start)
25
25
  const end = sub.search(EnumExpressions.ugc2)
@@ -11,17 +11,17 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { bootstrap } from "@bootstrap"
21
- import { getCache } from "@parsers/ugc/GetCache"
22
- import { setCache } from "@parsers/ugc/SetCache"
20
+ import { Bootstrap } from "@Bootstrap"
21
+ import { GetCache } from "@ParsingUGC/GetCache"
22
+ import { SetCache } from "@ParsingUGC/SetCache"
23
23
 
24
- export const getLocations = async (zones: string[]): Promise<string[]> => {
24
+ export const GetLocations = async (zones: string[]): Promise<string[]> => {
25
25
  const uniqueZones = Array.from(new Set(zones));
26
26
 
27
27
  const results: string[] = [];
@@ -29,7 +29,7 @@ export const getLocations = async (zones: string[]): Promise<string[]> => {
29
29
 
30
30
  for (let i = 0; i < uniqueZones.length; i++) {
31
31
  const zone = uniqueZones[i];
32
- const cached = getCache(zone);
32
+ const cached = GetCache(zone);
33
33
 
34
34
  if (cached) {
35
35
  for (let j = 0; j < cached.length; j++) {
@@ -41,7 +41,7 @@ export const getLocations = async (zones: string[]): Promise<string[]> => {
41
41
  }
42
42
 
43
43
  if (missing.length > 0) {
44
- const rows = await bootstrap.database
44
+ const rows = await Bootstrap.Database
45
45
  .prepare(
46
46
  `SELECT id, location FROM shapefiles WHERE id IN (${missing.map(() => '?').join(',')})`
47
47
  )
@@ -49,9 +49,9 @@ export const getLocations = async (zones: string[]): Promise<string[]> => {
49
49
 
50
50
  for (let i = 0; i < rows.length; i++) {
51
51
  const r = rows[i] as any;
52
- setCache(r.id, [r.location]);
52
+ SetCache({ Key: r.id, Value: [r.location] });
53
53
  results.push(r.location);
54
54
  }
55
55
  }
56
- return results;
56
+ return Array.from(new Set(results));
57
57
  };
@@ -0,0 +1,73 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { CreateQuery } from "@Database/CreateQuery"
21
+ import { GetUnionPolygon } from "@Geometry/GetUnionPolygon"
22
+ import { createHash } from "crypto";
23
+
24
+ interface CoordinatesOptions {
25
+ Zones: string[]
26
+ Union: boolean
27
+ }
28
+
29
+ interface CoordinatesResponse {
30
+ type: `Polygon` | `MultiPolygon`
31
+ coordinates: any[]
32
+ }
33
+
34
+ export const GetZonePolygon = ({ Zones, Union }: CoordinatesOptions): CoordinatesResponse | null => {
35
+ const list = [...new Set(Zones.map(z => z.trim()))].filter(z => z === 'XX000' ? false : true);
36
+ if (list.length === 0) return null;
37
+
38
+ const placeholders = list.map(() => "?").join(",");
39
+ const rows = CreateQuery({
40
+ Query: `SELECT geometry FROM shapefiles WHERE id IN (${placeholders})`,
41
+ Parameters: list
42
+ });
43
+ const polygons: any[] = [];
44
+ const geometryHashes = new Set<string>();
45
+ for (const row of rows) {
46
+ if (!row?.geometry) continue;
47
+ const geometryHash = createHash("sha256").update(row.geometry).digest("hex");
48
+ if (geometryHashes.has(geometryHash)) continue;
49
+ geometryHashes.add(geometryHash);
50
+ const geom = JSON.parse(row.geometry);
51
+ if (geom?.type === "Polygon") {
52
+ polygons.push(geom.coordinates);
53
+ }
54
+ if (geom?.type === "MultiPolygon") {
55
+ for (const poly of geom.coordinates) {
56
+ polygons.push(poly);
57
+ }
58
+ }
59
+ }
60
+ if (polygons.length === 0) return null;
61
+ if (Union) {
62
+ return GetUnionPolygon({ Polygons: polygons });
63
+ } else {
64
+ const multi: any[] = [];
65
+ for (const polyCoords of polygons) {
66
+ if (Array.isArray(polyCoords) && Array.isArray(polyCoords[0])) {
67
+ multi.push(polyCoords);
68
+ }
69
+ }
70
+ if (multi.length === 0) return null;
71
+ return {type: "MultiPolygon", coordinates: multi};
72
+ }
73
+ }
@@ -11,13 +11,13 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- export const getZones = (header: string): string[] => {
20
+ export const GetZones = (header: string): string[] => {
21
21
  const splits = header.split('-');
22
22
  const zones: string[] = [];
23
23
  let state = splits[0].substring(0, 2);
@@ -11,18 +11,23 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { bootstrap } from "@bootstrap"
20
+ import { Bootstrap } from "@Bootstrap"
21
21
 
22
- export const setCache = (key: string, value: string[]) => {
23
- if (bootstrap.cache.ugc.size >= 5000) {
24
- const firstKey = bootstrap.cache.ugc.keys().next().value;
25
- bootstrap.cache.ugc.delete(firstKey);
22
+ interface SetCacheOptions {
23
+ Key: string
24
+ Value: string[]
25
+ }
26
+
27
+ export const SetCache = ({ Key, Value }: SetCacheOptions) => {
28
+ if (Bootstrap.Cache.UGC.size >= 5000) {
29
+ const firstKey = Bootstrap.Cache.UGC.keys().next().value;
30
+ Bootstrap.Cache.UGC.delete(firstKey);
26
31
  }
27
- bootstrap.cache.ugc.set(key, value);
32
+ Bootstrap.Cache.UGC.set(Key, Value);
28
33
  };
@@ -11,27 +11,27 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypeUGC } from "types/UGC"
21
- import { getUGCHeader } from "@parsers/ugc/GetUGCHeader"
22
- import { getZones } from "@parsers/ugc/GetZones"
23
- import { GetExpiry } from "@parsers/ugc/GetExpiry"
24
- import { getLocations } from "@parsers/ugc/GetLocations"
20
+ import { TypeUGC } from "TypesStandard/UGC"
21
+ import { GetHeader } from "@ParsingUGC/GetHeader"
22
+ import { GetZones } from "@ParsingUGC/GetZones"
23
+ import { GetExpiry } from "@ParsingUGC/GetExpiry"
24
+ import { GetLocations } from "@ParsingUGC/GetLocations"
25
25
 
26
- export const ugcExtract = async (message: string): Promise<TypeUGC> => {
27
- const head = getUGCHeader(message);
28
- const ugcs = getZones(head)
26
+ export const UGCExtract = async (message: string): Promise<TypeUGC> => {
29
27
  const expires = GetExpiry(message)
30
- const areas = await getLocations(ugcs)
28
+ const head = GetHeader(message);
29
+ const ugcs = GetZones(head);
30
+ const areas = await GetLocations(ugcs)
31
31
  if (!head || ugcs?.length == 0) return;
32
32
  return {
33
- zones: ugcs,
34
- locations: areas,
35
- expires: expires
33
+ Zones: ugcs,
34
+ Locations: areas,
35
+ Expires: expires
36
36
  }
37
37
  }
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
@@ -11,38 +11,38 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import { TypePVTEC } from "types/VTEC"
21
- import { EnumExpressions } from "@enums/Expressions"
22
- import { EnumProducts } from "@enums/Products"
23
- import { EnumEvents } from "@enums/Events"
24
- import { EnumActions } from "@enums/Actions"
25
- import { EnumStatus } from "@enums/Status"
26
- import { GetExpiry } from "@parsers/pvtec/GetExpiry"
20
+ import { TypeVTEC } from "TypesEvent/VTEC"
21
+ import { EnumExpressions } from "@Enums/Expressions"
22
+ import { EnumProducts } from "@Enums/Products"
23
+ import { EnumEvents } from "@Enums/Events"
24
+ import { EnumActions } from "@Enums/Actions"
25
+ import { EnumStatus } from "@Enums/Status"
26
+ import { GetExpiry } from "@ParsingVTEC/GetExpiry"
27
27
 
28
- export const VTECExtract = (message: string): TypePVTEC[] | null => {
28
+ export const VTECExtract = (message: string): TypeVTEC[] | null => {
29
29
  if (!message) return null;
30
- const getVTECs = message.match(EnumExpressions.pvtec) ?? [];
31
- const vtecs: TypePVTEC[] = [];
30
+ const getVTECs = message.match(EnumExpressions.vtec) ?? [];
31
+ const vtecs: TypeVTEC[] = [];
32
32
  for (const vtec of getVTECs) {
33
33
  const sub = vtec.split(`.`);
34
34
  if (sub?.length < 7) continue;
35
35
  const dates = sub[6]?.split(`-`);
36
36
  vtecs.push({
37
- vtec: vtec,
38
- product: EnumProducts[sub[0]],
37
+ raw: vtec,
38
+ type: EnumProducts[sub[0]],
39
39
  tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
40
40
  event: `${EnumEvents[sub[3]]} ${EnumActions[sub[4]]}`,
41
41
  status: EnumStatus[sub[1]],
42
- organization: message.match(EnumExpressions.wmo)?.[0] ?? null,
42
+ wmo: message.match(EnumExpressions.wmo)?.[0] ?? null,
43
43
  expires: GetExpiry(dates),
44
- is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
45
- prediction_center: sub[2] == `KWNS` ? true : false
44
+ watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
45
+ wou: sub[2] == `KWNS` ? true : false
46
46
  })
47
47
  }
48
48
  return vtecs.length > 0 ? vtecs : null;
@@ -0,0 +1,116 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+ */
18
+
19
+ import { TypeSettings } from "TypesStandard/Settings"
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { TypeActions } from "TypesStandard/Actions"
22
+ import { Bootstrap } from "@Bootstrap"
23
+ import { SetDebug } from "@Utilities/SetDebug"
24
+ import { GetMatched } from "@Utilities/GetMatched"
25
+ import { GetStringText } from "@Formatting/GetStringText"
26
+ import { GetCleanedEvent } from "@BuilderComponents/GetCleanedEvent"
27
+ import { GenerateAudioMessage } from "@Audio/GenerateAudioMessage"
28
+ import { TaskGenerateText } from "@Tasks/TaskGenerateText"
29
+ import { TaskGenerateJSON } from "@Tasks/TaskGenerateJSON"
30
+ import { TaskSendNTFY } from "@Tasks/TaskSendNTFY"
31
+ import { TaskSendWebhook } from "@Tasks/TaskSendWebhook"
32
+ import { GenerateGraphic } from "@Image/GenerateGraphic"
33
+ import { QueueManager } from "@Utilities/QueueManager"
34
+
35
+ const Webhooks = new QueueManager({ Concurrency: 1 });
36
+ const NTFY = new QueueManager({ Concurrency: 5 });
37
+
38
+ export const CreateTasks = async (events: TypeEvent[]): Promise<void> => {
39
+
40
+ const settings = Bootstrap.Settings as TypeSettings;
41
+ const { ActionSettings, GlobalSettings, NotifyServer } = settings;
42
+ const actions = ActionSettings as TypeActions[];
43
+ for (const event of events) {
44
+ const tick = performance.now()
45
+ const { properties } = event;
46
+ const isActioning = Array.isArray(actions) && actions.length > 0;
47
+ if (!isActioning) { continue }
48
+ for (const action of actions) {
49
+ const { Events, Webhook, NotificationServer, Uploads } = action;
50
+ const isValidAction = GetMatched({ Strings: Events, String: properties.event });
51
+
52
+ if ((Events.length == 0 || isValidAction)) {
53
+ const a = performance.now();
54
+ const [audio, text, json, image] = await Promise.all([
55
+ Uploads?.AUDIO && GlobalSettings?.ArchiveSettings?.AudioDirectory ? GenerateAudioMessage({
56
+ Directory: GlobalSettings?.ArchiveSettings?.AudioDirectory + `/${properties?.regions_string ?? `MC`}`,
57
+ Title: (`${properties.event}_${properties.metadata.tracking}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim(),
58
+ Message: properties.description,
59
+ Header: properties.metadata.header
60
+ }).then((result) => { return result; }) : Promise.resolve(null),
61
+
62
+ Uploads?.TEXT && GlobalSettings?.ArchiveSettings?.TextDirectory ? TaskGenerateText({
63
+ String: properties.metadata.raw,
64
+ Directory: GlobalSettings?.ArchiveSettings?.TextDirectory + `/${properties?.regions_string ?? `MC`}`,
65
+ Filename: (`${properties.event}_${properties.metadata.tracking}.txt`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
66
+ }).then((result) => { return result; }) : Promise.resolve(null),
67
+
68
+ Uploads?.JSON && GlobalSettings?.ArchiveSettings?.JSONDirectory ? TaskGenerateJSON({
69
+ String: JSON.stringify(GetCleanedEvent(event), null, 2),
70
+ Directory: GlobalSettings?.ArchiveSettings?.JSONDirectory + `/${properties?.regions_string ?? `MC`}`,
71
+ Filename: (`${properties.event}_${properties.metadata.tracking}.json`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
72
+ }).then((result) => { return result; }) : Promise.resolve(null),
73
+
74
+ Uploads?.IMAGE && GlobalSettings?.ArchiveSettings?.ImageDirectory ? GenerateGraphic({
75
+ Event: event,
76
+ File: {
77
+ Directory: GlobalSettings?.ArchiveSettings?.ImageDirectory + `/${properties?.regions_string ?? `MC`}`,
78
+ Name: (`${properties.event}_${properties.metadata.tracking}.png`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim()
79
+ }
80
+ }).then((result) => { return result; }) : Promise.resolve(null)
81
+ ]);
82
+
83
+
84
+ SetDebug({ Title: `Tasks/Generative`, Message: `${Math.round(performance.now() - a)}ms` })
85
+
86
+ const b = performance.now();
87
+ await Promise.all([
88
+ NotificationServer?.Enabled && NotifyServer?.Enabled && NotificationServer?.Topic ? NTFY.enqueue(() => TaskSendNTFY({
89
+ Event: event,
90
+ Priority: NotificationServer?.Priority ?? 5,
91
+ Body: GetStringText(event),
92
+ Topic: NotificationServer?.Topic
93
+ })) : Promise.resolve(null),
94
+ Webhook?.Enabled && Webhook?.Destination ? Webhooks.enqueue(() => TaskSendWebhook({
95
+ Event: event,
96
+ Webhook: {
97
+ Enabled: Webhook?.Enabled,
98
+ Destination: Webhook?.Destination,
99
+ Message: Webhook?.Message,
100
+ Title: Webhook?.Title,
101
+ Ratelimit: Webhook?.Ratelimit
102
+ },
103
+ Attachments: {
104
+ Image: image,
105
+ Text: text,
106
+ Audio: audio,
107
+ Json: json
108
+ }
109
+ })) : Promise.resolve(null)
110
+ ]);
111
+ SetDebug({ Title: `Tasks/Send`, Message: `${Math.round(performance.now() - b)}ms` })
112
+ }
113
+ }
114
+ SetDebug({ Title: `Tasks/CompletedEventTask`, Message: `${Math.round(performance.now() - tick)}ms` })
115
+ }
116
+ }
@@ -11,25 +11,24 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
20
  import { mkdir, writeFile } from "fs/promises"
21
21
 
22
22
  interface TaskGenerateJSONOptions {
23
- string: string;
24
- directory: string;
25
- filename: string;
23
+ String: string;
24
+ Directory: string;
25
+ Filename: string;
26
26
  }
27
27
 
28
- export const TaskGenerateJSON = async function(options: TaskGenerateJSONOptions): Promise<string> {
29
- const { string, directory, filename } = options;
30
- if (directory) {
31
- await mkdir(directory, { recursive: true });
32
- await writeFile(directory + "/" + filename, `${string}${"\n".repeat(5)}`);
28
+ export const TaskGenerateJSON = async function({ String, Directory, Filename }: TaskGenerateJSONOptions): Promise<string> {
29
+ if (Directory) {
30
+ await mkdir(Directory, { recursive: true });
31
+ await writeFile(Directory + "/" + Filename, `${String}${"\n".repeat(5)}`);
33
32
  }
34
- return string;
33
+ return String;
35
34
  }