@atmosx/event-product-parser 3.0.55 → 3.0.61

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 (156) hide show
  1. package/.github/CODE_OF_CONDUCT.md +9 -9
  2. package/.github/CONTRIBUTING.md +29 -29
  3. package/.github/LICENSE +17 -17
  4. package/.github/SECURITY.md +20 -20
  5. package/.github/SUPPORTED_EVENTS.md +369 -369
  6. package/.github/docs/docs-functions.md +30 -0
  7. package/.github/docs/docs-general-configurations.md +209 -0
  8. package/.github/docs/docs-integrations.md +37 -0
  9. package/.github/docs/docs-listeners.md +28 -0
  10. package/.github/docs/docs-source-configuration.md +218 -0
  11. package/.github/docs/docs-technical.md +50 -0
  12. package/.github/logo.png +0 -0
  13. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  14. package/.github/samples/SAMPLE_GEOJSON.json +204 -0
  15. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +119 -0
  16. package/.vscode/settings.json +3 -3
  17. package/README.md +167 -0
  18. package/dist/cjs/index.cjs +1439 -1277
  19. package/dist/esm/index.mjs +1420 -1258
  20. package/package.json +47 -52
  21. package/src/@building/{building.create.ts → CreateEvent.ts} +55 -55
  22. package/src/@building/{building.clean.ts → GetCleanedEvent.ts} +29 -29
  23. package/src/@building/{building.attachments.ts → GetEventAttachments.ts} +85 -82
  24. package/src/@building/{building.enhance.ts → GetEventEnhancedName.ts} +54 -59
  25. package/src/@building/{building.geometry.ts → GetEventGeometry.ts} +47 -47
  26. package/src/@building/{building.headers.ts → GetEventHeader.ts} +36 -36
  27. package/src/@building/{building.polygon.ts → GetEventNodes.ts} +72 -69
  28. package/src/@building/{building.office.ts → GetEventOffice.ts} +42 -42
  29. package/src/@building/{building.properties.ts → GetEventProperties.ts} +95 -95
  30. package/src/@building/{building.signature.ts → GetEventSignature.ts} +60 -60
  31. package/src/@building/{building.tags.ts → GetEventTags.ts} +29 -24
  32. package/src/@building/{building.tracking.ts → GetEventTracking.ts} +67 -67
  33. package/src/@core/{core.clearEvents.ts → ClearEvents.ts} +30 -30
  34. package/src/@core/{core.createListener.ts → CreateListener.ts} +23 -23
  35. package/src/@core/{core.getEvents.ts → GetEvents.ts} +23 -23
  36. package/src/@core/{core.getNodes.ts → GetNodes.ts} +23 -23
  37. package/src/@core/{core.getRandomEvent.ts → GetRandomEvent.ts} +23 -23
  38. package/src/@core/{core.getVersion.ts → GetVersion.ts} +23 -23
  39. package/src/@core/{core.manualEvent.ts → ManualEvent.ts} +56 -38
  40. package/src/@core/{core.query.ts → QueryStanza.ts} +38 -38
  41. package/src/@core/{core.setNode.ts → SetNode.ts} +80 -80
  42. package/src/@core/{core.start.ts → StartService.ts} +60 -60
  43. package/src/@core/{core.stop.ts → StopService.ts} +31 -31
  44. package/src/@enums/AWIPS.ts +366 -0
  45. package/src/{@dictionaries/dictionaries.actions.ts → @enums/Actions.ts} +27 -27
  46. package/src/{@dictionaries/dictionaries.cancellation.ts → @enums/Cancellation.ts} +30 -30
  47. package/src/{@dictionaries/dictionaries.causes.ts → @enums/Causes.ts} +35 -35
  48. package/src/{@dictionaries/dictionaries.correlations.ts → @enums/Correlations.ts} +42 -42
  49. package/src/{@dictionaries/dictionaries.enhanced.ts → @enums/Enhanced.ts} +69 -69
  50. package/src/{@dictionaries/dictionaries.events.ts → @enums/Events.ts} +82 -82
  51. package/src/{@dictionaries/dictionaries.expressions.ts → @enums/Expressions.ts} +28 -28
  52. package/src/@enums/GlobalFilter.ts +24 -0
  53. package/src/{@dictionaries/dictionaries.hail.ts → @enums/Hail.ts} +37 -35
  54. package/src/{@dictionaries/dictionaries.icao.ts → @enums/ICAO.ts} +258 -258
  55. package/src/{@dictionaries/dictionaries.matches.ts → @enums/Matches.ts} +54 -54
  56. package/src/{@dictionaries/dictionaries.products.ts → @enums/Products.ts} +24 -24
  57. package/src/{@dictionaries/dictionaries.records.ts → @enums/Records.ts} +25 -25
  58. package/src/{@dictionaries/dictionaries.severity.ts → @enums/Severity.ts} +27 -27
  59. package/src/{@dictionaries/dictionaries.shapefiles.ts → @enums/Shapefiles.ts} +35 -35
  60. package/src/{@dictionaries/dictionaries.states.ts → @enums/States.ts} +71 -71
  61. package/src/{@dictionaries/dictionaries.status.ts → @enums/Status.ts} +30 -30
  62. package/src/{@dictionaries/dictionaries.global.ts → @enums/Strings.ts} +22 -24
  63. package/src/@enums/Tags.ts +167 -0
  64. package/src/{@dictionaries/dictionaries.testing.ts → @enums/Testing.ts} +24 -24
  65. package/src/@events/{events.api.ts → ParseAPI.ts} +116 -116
  66. package/src/@events/{events.text.ts → ParseText.ts} +87 -84
  67. package/src/@events/{events.ugc.ts → ParseUGC.ts} +93 -89
  68. package/src/@events/{events.vtec.ts → ParseVTEC.ts} +86 -86
  69. package/src/@manager/MakeEvents.ts +106 -0
  70. package/src/@manager/{manager.rmEvent.ts → RemoveEvent.ts} +69 -71
  71. package/src/@manager/{manager.setHash.ts → SetHash.ts} +35 -35
  72. package/src/@manager/Tasks.ts +246 -0
  73. package/src/@manager/{manager.updateEvents.ts → UpdateEvents.ts} +34 -34
  74. package/src/@manager/{manager.updateNodes.ts → UpdateNode.ts} +61 -53
  75. package/src/{@building/building.validate.ts → @manager/ValidateEvents.ts} +141 -154
  76. package/src/@modules/@database/{database.cache.ts → GetCachedEvents.ts} +49 -49
  77. package/src/@modules/@database/{database.broadcastify.ts → ImportBroadcastify.ts} +69 -66
  78. package/src/@modules/@database/{database.shapefiles.ts → ImportShapefiles.ts} +92 -92
  79. package/src/@modules/@database/{database.stanza.ts → ImportStanza.ts} +46 -46
  80. package/src/@modules/@database/{database.init.ts → InitializeDatabase.ts} +58 -58
  81. package/src/@modules/@eas/{eas.setEasTone.ts → GenerateEASMessage.ts} +144 -151
  82. package/src/@modules/@eas/{eas.getCleanDescription.ts → GetCleanDescription.ts} +91 -91
  83. package/src/@modules/@eas/{eas.getFloatPCM16.ts → GetFloatPCM16.ts} +29 -29
  84. package/src/@modules/@eas/{eas.getMergedPCM16.ts → GetMergedPCM16.ts} +32 -32
  85. package/src/@modules/@eas/{eas.getPCM16.ts → GetPCM16.ts} +52 -52
  86. package/src/@modules/@eas/{eas.getPCMToFloat.ts → GetPCMToFloat.ts} +26 -26
  87. package/src/@modules/@eas/{eas.getSampledPCM16.ts → GetSampledPCM16.ts} +36 -36
  88. package/src/@modules/@eas/{eas.getTTS.ts → GetTTS.ts} +54 -54
  89. package/src/@modules/@eas/{eas.getWavPCM16.ts → GetWavPCM16.ts} +52 -52
  90. package/src/@modules/@eas/{eas.setAFSK.ts → SetAFSK.ts} +51 -51
  91. package/src/@modules/@eas/{eas.setAsciiToBits.ts → SetAsciiToBits.ts} +31 -31
  92. package/src/@modules/@eas/{eas.setAttentionTone.ts → SetAttentionTone.ts} +40 -40
  93. package/src/@modules/@eas/{eas.setNoise.ts → SetNoise.ts} +32 -32
  94. package/src/@modules/@eas/{eas.setRadioEffect.ts → SetRadioEffect.ts} +50 -50
  95. package/src/@modules/@eas/{eas.setSameHeader.ts → SetSameHeader.ts} +44 -44
  96. package/src/@modules/@stanza/{stanza.getAwipsType.ts → GetAwipsType.ts} +47 -45
  97. package/src/@modules/@stanza/{stanza.validate.ts → ValidateStanza.ts} +49 -49
  98. package/src/@modules/@utilities/{utilities.createHttp.ts → CreateHttp.ts} +83 -83
  99. package/src/@modules/@utilities/{utilities.getFormattedTime.ts → GetFormattedTime.ts} +43 -43
  100. package/src/@modules/@utilities/{utilities.getLatestIssuance.ts → GetLatestIssuance.ts} +32 -32
  101. package/src/@modules/@utilities/{utilities.getMatched.ts → GetMatched.ts} +33 -33
  102. package/src/@modules/@utilities/{utilities.getSettings.ts → GetSettings.ts} +25 -25
  103. package/src/@modules/@utilities/{utilities.getShapeNearestPoint.ts → GetShapeNearestPoint.ts} +114 -114
  104. package/src/@modules/@utilities/{utilities.setCronSchedule.ts → SetCronSchedule.ts} +94 -94
  105. package/src/@modules/@utilities/{utilities.setDebug.ts → SetDebug.ts} +37 -38
  106. package/src/@modules/@utilities/{utilities.setEventEmit.ts → SetEventEmit.ts} +41 -41
  107. package/src/@modules/@utilities/{utilities.setListener.ts → SetListener.ts} +30 -30
  108. package/src/@modules/@utilities/{utilities.setSettings.ts → SetSettings.ts} +42 -42
  109. package/src/@modules/@utilities/{utilities.setSleep.ts → SetSleep.ts} +33 -33
  110. package/src/@modules/@utilities/{utilities.setTimeoutAction.ts → SetTimeoutAction.ts} +63 -63
  111. package/src/@modules/@utilities/{utilities.setWarning.ts → SetWarning.ts} +34 -34
  112. package/src/@modules/@xmpp/{xmpp.xDeploy.ts → DeployXMPP.ts} +57 -57
  113. package/src/@modules/@xmpp/{xmpp.xError.ts → ErrorXMPP.ts} +26 -26
  114. package/src/@modules/@xmpp/{xmpp.xOffline.ts → OfflineXMPP.ts} +36 -36
  115. package/src/@modules/@xmpp/{xmpp.xOnline.ts → OnlineXMPP.ts} +45 -45
  116. package/src/@modules/@xmpp/{xmpp.xReconnect.ts → ReconnectXMPP.ts} +64 -64
  117. package/src/@modules/@xmpp/{xmpp.xStanza.ts → StanzaXMPP.ts} +62 -62
  118. package/src/@parsers/@hvtec/{hvtec.extract.ts → HVExtract.ts} +39 -39
  119. package/src/@parsers/@pvtec/{pvtec.expires.ts → GetExpiry.ts} +25 -25
  120. package/src/@parsers/@pvtec/{pvtec.extract.ts → VTECExtract.ts} +48 -48
  121. package/src/@parsers/@text/{text.getDescriptionFromProduct.ts → GetDescriptionFromProduct.ts} +59 -52
  122. package/src/@parsers/@text/{text.getEmbedText.ts → GetEmbededText.ts} +55 -55
  123. package/src/@parsers/@text/{text.getPolygonFromProduct.ts → GetPolygonFromProduct.ts} +52 -52
  124. package/src/@parsers/@text/{text.getStringText.ts → GetStringText.ts} +57 -53
  125. package/src/@parsers/@text/{text.getTextFromProduct.ts → GetTextFromProduct.ts} +42 -42
  126. package/src/@parsers/@text/{text.getXML.ts → GetXML.ts} +60 -60
  127. package/src/@parsers/@ugc/{ugc.getCache.ts → GetCache.ts} +23 -23
  128. package/src/@parsers/@ugc/{ugc.expiry.ts → GetExpiry.ts} +31 -31
  129. package/src/@parsers/@ugc/{ugc.locations.ts → GetLocations.ts} +56 -56
  130. package/src/@parsers/@ugc/{ugc.header.ts → GetUGCHeader.ts} +29 -29
  131. package/src/@parsers/@ugc/{ugc.coordinates.ts → GetZonePolygon.ts} +110 -110
  132. package/src/@parsers/@ugc/{ugc.zones.ts → GetZones.ts} +51 -51
  133. package/src/@parsers/@ugc/{ugc.setCache.ts → SetCache.ts} +27 -27
  134. package/src/@parsers/@ugc/{ugc.extract.ts → UGCExtract.ts} +36 -36
  135. package/src/@types/{type.listener.ts → Actions.ts} +37 -38
  136. package/src/@types/{type.attributes.ts → Attributes.ts} +28 -28
  137. package/src/@types/{type.event.ts → Event.ts} +69 -69
  138. package/src/@types/{type.hvtec.ts → HVTEC.ts} +25 -25
  139. package/src/@types/{type.hash.ts → Hash.ts} +24 -24
  140. package/src/@types/{type.properties.ts → Properties.ts} +77 -77
  141. package/src/@types/{type.settings.ts → Settings.ts} +99 -93
  142. package/src/@types/{type.stanza.ts → Stanza.ts} +37 -37
  143. package/src/@types/{type.compiled.ts → StanzaCompiled.ts} +35 -34
  144. package/src/@types/{type.ugc.ts → UGC.ts} +24 -24
  145. package/src/@types/{type.pvtec.ts → VTEC.ts} +30 -30
  146. package/src/bootstrap.ts +128 -124
  147. package/src/index.ts +74 -74
  148. package/tsconfig.json +13 -13
  149. package/tsup.config.ts +15 -15
  150. package/.github/README.md +0 -384
  151. package/src/@dictionaries/dictionaries.awips.ts +0 -364
  152. package/src/@dictionaries/dictionaries.strings.ts +0 -22
  153. package/src/@dictionaries/dictionaries.tags.ts +0 -93
  154. package/src/@manager/manager.mkEvent.ts +0 -98
  155. package/src/@manager/manager.updateListener.ts +0 -180
  156. package/testing/init.js +0 -91
@@ -1,48 +1,48 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeSettings } from "../@types/type.settings"
21
- import { TypeEvent } from "../@types/type.event"
22
- import { getSettings } from "../@modules/@utilities/utilities.getSettings";
23
- import { getZonePolygon } from "../@parsers/@ugc/ugc.coordinates";
24
-
25
- interface GetGeometryResponse {
26
- type: `Polygon` | `MultiPolygon`
27
- coordinates: any[]
28
- }
29
-
30
- export const getEventGeometry = (event: TypeEvent): GetGeometryResponse => {
31
- const settings = getSettings() as TypeSettings
32
- const generated = event?.properties?.geocode?.polygon ?? null;
33
- const ugc = event?.properties?.geocode?.ugc ?? null;
34
- let geo: GetGeometryResponse = {
35
- type: `Polygon`,
36
- coordinates: generated != null ? JSON.parse(Buffer.from(generated, 'base64').toString('utf-8')) : null
37
- }
38
- if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc != null) {
39
- geo = getZonePolygon({zones: ugc, isUnion: false})
40
- if (geo == null) {
41
- geo = {
42
- type: `Polygon`,
43
- coordinates: []
44
- }
45
- }
46
- }
47
- return geo;
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeSettings } from "../@types/Settings"
21
+ import { TypeEvent } from "../@types/Event"
22
+ import { GetSettings } from "../@modules/@utilities/GetSettings";
23
+ import { getZonePolygon } from "../@parsers/@ugc/GetZonePolygon";
24
+
25
+ interface GetGeometryResponse {
26
+ type: `Polygon` | `MultiPolygon`
27
+ coordinates: any[]
28
+ }
29
+
30
+ export const GetEventGeometry = (event: TypeEvent): GetGeometryResponse => {
31
+ const settings = GetSettings() as TypeSettings
32
+ const generated = event?.properties?.geocode?.polygon ?? null;
33
+ const ugc = event?.properties?.geocode?.ugc ?? null;
34
+ let geo: GetGeometryResponse = {
35
+ type: `Polygon`,
36
+ coordinates: generated != null ? JSON.parse(Buffer.from(generated, 'base64').toString('utf-8')) : null
37
+ }
38
+ if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc != null) {
39
+ geo = getZonePolygon({zones: ugc, isUnion: false})
40
+ if (geo == null) {
41
+ geo = {
42
+ type: `Polygon`,
43
+ coordinates: []
44
+ }
45
+ }
46
+ }
47
+ return geo;
48
48
  }
@@ -1,37 +1,37 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypePVTEC } from "../@types/type.pvtec";
21
- import { TypeEventProperties } from "../@types/type.properties";
22
-
23
- interface GetHeaderOptions {
24
- properties: TypeEventProperties
25
- vtec?: TypePVTEC
26
- getType: {
27
- type: string
28
- prefix: string
29
- }
30
- }
31
-
32
- export const getEventHeader = (options: GetHeaderOptions): string => {
33
- const properties = options.properties
34
- const vtec = options.vtec ?? null
35
- const ugc = properties.geocode.ugc != null ? properties.geocode.ugc.join(`-`) : `0`;
36
- return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc}-${vtec?.status ?? `Issued`}-${new Date().toISOString().replace(/[-:]/g, '').split('.')[0]}-${properties.geocode.office.office ?? `KWNS`}`
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypePVTEC } from "../@types/VTEC";
21
+ import { TypeEventProperties } from "../@types/Properties";
22
+
23
+ interface GetHeaderOptions {
24
+ properties: TypeEventProperties
25
+ vtec?: TypePVTEC
26
+ getType: {
27
+ type: string
28
+ prefix: string
29
+ }
30
+ }
31
+
32
+ export const GetEventHeader = (options: GetHeaderOptions): string => {
33
+ const properties = options.properties
34
+ const vtec = options.vtec ?? null
35
+ const ugc = properties.geocode.ugc != null ? properties.geocode.ugc.join(`-`) : `0`;
36
+ return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc}-${vtec?.status ?? `Issued`}-${new Date().toISOString().replace(/[-:]/g, '').split('.')[0]}-${properties.geocode.office.office ?? `KWNS`}`
37
37
  }
@@ -1,70 +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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeEvent } from "../@types/type.event"
21
- import { bootstrap } from "../bootstrap"
22
- import { getEventGeometry } from "./building.geometry"
23
- import { getShapeNearestPoint } from "../@modules/@utilities/utilities.getShapeNearestPoint"
24
-
25
- interface GetEventNodesResponse {
26
- nodes: {
27
- id?: string | number
28
- coordinates: [number, number]
29
- nearest: [number, number]
30
- miles: number | null
31
- kilometers: number | null
32
- proximity: boolean
33
- }[]
34
- filtered: boolean
35
- updated: number
36
- }
37
-
38
- export const getEventNodes = async (event: TypeEvent): Promise<GetEventNodesResponse> => {
39
- const metadata = { nodes: [], proximity: false, filtered: false }
40
- const geometry = await getEventGeometry(event);
41
- if (!geometry || !geometry.coordinates) {
42
- return { nodes: [], filtered: false, updated: Date.now() }
43
- }
44
- const nodes = bootstrap.cache.nodes.features;
45
- for (const node of nodes) {
46
- const [longitude, latitude] = node.geometry.coordinates;
47
- const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude])
48
- const miles = getPoint.distance ?? null;
49
- const kilometers = Number((miles * 1.609344).toFixed(3));
50
-
51
- const info = {
52
- id: node.properties?.identifier,
53
- coordinates: [longitude, latitude],
54
- nearest: getPoint.point,
55
- miles,
56
- kilometers,
57
- proximity: getPoint.proximity
58
- }
59
- metadata.nodes.push(info)
60
- if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
61
- metadata.proximity = true;
62
- info.proximity = true;
63
- }
64
- }
65
- return {
66
- nodes: metadata.nodes,
67
- filtered: metadata.proximity,
68
- updated: Date.now()
69
- }
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEvent } from "../@types/Event"
21
+ import { bootstrap } from "../bootstrap"
22
+ import { GetEventGeometry } from "./GetEventGeometry"
23
+ import { GetShapeNearestPoint } from "../@modules/@utilities/GetShapeNearestPoint"
24
+
25
+ interface GetEventNodesResponse {
26
+ nodes: {
27
+ id?: string | number
28
+ coordinates: [number, number]
29
+ nearest: [number, number]
30
+ miles: number | null
31
+ kilometers: number | null
32
+ proximity: boolean
33
+ }[]
34
+ filtered: boolean
35
+ updated: number
36
+ }
37
+
38
+ export const GetEventNodes = async (event: TypeEvent): Promise<GetEventNodesResponse> => {
39
+ const nodes = bootstrap.cache.nodes.features;
40
+ if (!nodes || nodes.length === 0) {
41
+ return { nodes: [], filtered: true, updated: Date.now() };
42
+ }
43
+ const metadata = { nodes: [], proximity: false, filtered: false };
44
+ const geometry = await GetEventGeometry(event);
45
+ if (!geometry || !geometry.coordinates) {
46
+ return { nodes: [], filtered: false, updated: Date.now() }
47
+ }
48
+ for (const node of nodes) {
49
+ const [longitude, latitude] = node.geometry.coordinates;
50
+ const getPoint = GetShapeNearestPoint(geometry.coordinates, [longitude, latitude])
51
+ const miles = getPoint.distance ?? null;
52
+ const kilometers = Number((miles * 1.609344).toFixed(3));
53
+
54
+ const info = {
55
+ id: node.properties?.identifier,
56
+ coordinates: [longitude, latitude],
57
+ nearest: getPoint.point,
58
+ miles,
59
+ kilometers,
60
+ proximity: false
61
+ }
62
+ metadata.nodes.push(info)
63
+ if (miles != null && (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering) && (miles < bootstrap.settings.GlobalSettings.NodeMaxDistance)) {
64
+ metadata.proximity = true;
65
+ info.proximity = true;
66
+ }
67
+ }
68
+ return {
69
+ nodes: metadata.nodes,
70
+ filtered: metadata.proximity,
71
+ updated: Date.now()
72
+ }
70
73
  }
@@ -1,43 +1,43 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeAttributes } from "../@types/type.attributes";
21
- import { TypePVTEC } from "../@types/type.pvtec";
22
- import { dict_icao } from "../@dictionaries/dictionaries.icao";
23
-
24
- interface GetOfficeOptions {
25
- attributes: TypeAttributes
26
- organization: string
27
- pVtec: TypePVTEC
28
- }
29
-
30
- interface GetOfficeResponse {
31
- office: string | null
32
- name: string | null
33
- }
34
-
35
- export const getEventOffice = (options: GetOfficeOptions): GetOfficeResponse => {
36
- const office = options.pVtec != null
37
- ? options.pVtec?.tracking?.split(`.`)[0] : (options.attributes?.cccc ??
38
- (options.organization != null ?
39
- (Array.isArray(options.organization) ? options.organization?.[0] : options.organization)
40
- : null));
41
- const name = dict_icao?.[office] ?? null;
42
- return { office, name };
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeAttributes } from "../@types/Attributes";
21
+ import { TypePVTEC } from "../@types/VTEC";
22
+ import { EnumICAO } from "../@enums/ICAO";
23
+
24
+ interface GetOfficeOptions {
25
+ attributes: TypeAttributes
26
+ organization: string
27
+ pVtec: TypePVTEC
28
+ }
29
+
30
+ interface GetOfficeResponse {
31
+ office: string | null
32
+ name: string | null
33
+ }
34
+
35
+ export const GetEventOffice = (options: GetOfficeOptions): GetOfficeResponse => {
36
+ const office = options.pVtec != null
37
+ ? options.pVtec?.tracking?.split(`.`)[0] : (options.attributes?.cccc ??
38
+ (options.organization != null ?
39
+ (Array.isArray(options.organization) ? options.organization?.[0] : options.organization)
40
+ : null));
41
+ const name = EnumICAO?.[office] ?? null;
42
+ return { office, name };
43
43
  }
@@ -1,96 +1,96 @@
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
-
16
- Internal Package: @atmosx/event-product-parser
17
-
18
- */
19
-
20
- import { TypeEventProperties } from "../@types/type.properties";
21
- import { TypeAttributes } from "../@types/type.attributes";
22
- import { TypeUGC } from "../@types/type.ugc";
23
- import { TypePVTEC } from "../@types/type.pvtec";
24
- import { TypeHVTEC } from "../@types/type.hvtec";
25
- import { dict_expressions } from "../@dictionaries/dictionaries.expressions";
26
- import { getDescriptionFromProduct } from "../@parsers/@text/text.getDescriptionFromProduct";
27
- import { getPolygonFromProduct } from "../@parsers/@text/text.getPolygonFromProduct";
28
- import { getTextFromProduct } from "../@parsers/@text/text.getTextFromProduct";
29
- import { getEventOffice } from "./building.office";
30
- import { getEventTags } from "./building.tags";
31
-
32
- interface GetPropertiesOptions {
33
- message: string
34
- attributes: TypeAttributes
35
- ugc?: TypeUGC
36
- pVtec?: TypePVTEC
37
- hVtec?: TypeHVTEC
38
- }
39
-
40
- export const properties = (options: GetPropertiesOptions): TypeEventProperties => {
41
- const organization = options.message.match(dict_expressions.wmo)?.[0] ?? null
42
- const polygons = getPolygonFromProduct(options.message)
43
- const properties = {
44
- locations: options?.ugc?.locations?.join(`; `) ?? null,
45
- locations_array: options?.ugc?.locations ?? [],
46
- description: getDescriptionFromProduct({ message: options.message, handle: options?.pVtec?.vtec ?? null }),
47
- attributes: options.attributes,
48
- geocode: {
49
- office: getEventOffice({ attributes: options.attributes, organization: organization, pVtec: options.pVtec }),
50
- organization: organization,
51
- ugc: options?.ugc?.zones ?? [],
52
- polygon: polygons.length > 0 ? Buffer.from(JSON.stringify([polygons])).toString('base64') : null,
53
- polygon_generated: polygons.length > 0 ? true : false
54
- },
55
- parameters: {
56
- tags: getEventTags(options.message),
57
- instructions: getTextFromProduct({ message: options.message, find: [`For your protection`, `do not`, `use extreme caution`], append: `...`, removal: [`.`]}) ?? null,
58
- source: getTextFromProduct({ message: options.message, find: [`SOURCE...`], removal: [`.`]}) ?? null,
59
- hazards: getTextFromProduct({ message: options.message, find: [`HAZARD...`], removal: [`.`]}) ?? null,
60
- impacts: getTextFromProduct({ message: options.message, find: [`IMPACT...`], removal: [`.`]}) ?? null,
61
- estimated_hail_size: getTextFromProduct({ message: options.message, find: [`MAX HAIL SIZE...`, `HAIL...`], removal: ['in']}) ?? null,
62
- estimated_wind_gusts: getTextFromProduct({ message: options.message, find: [`MAX WIND GUST...`, `WIND...`]}) ?? null,
63
- damage_threat: getTextFromProduct({ message: options.message, find: [`DAMAGE THREAT...`], removal: []}) ?? null,
64
- tornado_threat: getTextFromProduct({ message: options.message, find: [`TORNADO...`, `WATERSPOUT...`] }) ?? null,
65
- flood_threat: getTextFromProduct({ message: options.message, find: [`FLASH FLOOD...`]}) ?? null,
66
- wind_threat: getTextFromProduct({ message: options.message, find: [`WIND THREAT...`]}) ?? null,
67
- hail_threat: getTextFromProduct({ message: options.message, find: [`HAIL THREAT...`], removal: []}) ?? null,
68
- },
69
- discussion_parameters: {
70
- discussion_number: getTextFromProduct({ message: options.message, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })?.toString()?.padStart(4, "0") ?? null,
71
- discussion_concerning: getTextFromProduct({ message: options.message, find: [`Concerning...`] }) ?? null,
72
- discussion_max_tornado: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] }) ?? null,
73
- discussion_max_hail: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] }) ?? null,
74
- discussion_max_wind: getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] }) ?? null,
75
- discussion_watch_issuance: getTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`]}) ?? null,
76
- },
77
- watch_parameters: {
78
- watch_number: (options?.pVtec?.is_watch) && (getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })?.replace(/(WT|WS|)/g, '')?.trim()?.toString()?.padStart(4, "0") ?? options?.pVtec?.tracking?.slice(-4)?.toString()?.padStart(4, "0") ?? null),
79
- watch_type: options.message.includes(`TORNADO WATCH`) ? `Tornado` : options?.message.includes(`SEVERE`) ? `Severe` : null,
80
- additional_tornadoes_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
81
- strong_tornadoes_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
82
- severe_wind_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
83
- severe_hail_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
84
- hail_2in_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] }) ?? null,
85
- combined_hail_wind_probability: getTextFromProduct({ message: options.message, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
86
- max_hail_in: getTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] }) ?? null,
87
- max_wind_surface: getTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] }) ?? null,
88
- max_tops_x100feet: getTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] }) ?? null,
89
- pds_watch: (getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES` ? true : null)
90
- }
91
- }
92
- if (isNaN(Number(properties.watch_parameters.watch_number))) {
93
- properties.watch_parameters.watch_number = null
94
- }
95
- return properties;
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: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Internal Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeEventProperties } from "../@types/Properties";
21
+ import { TypeAttributes } from "../@types/Attributes";
22
+ import { TypeUGC } from "../@types/UGC";
23
+ import { TypePVTEC } from "../@types/VTEC";
24
+ import { TypeHVTEC } from "../@types/HVTEC";
25
+ import { EnumExpressions } from "../@enums/Expressions";
26
+ import { GetDescriptionFromProduct } from "../@parsers/@text/GetDescriptionFromProduct";
27
+ import { getPolygonFromProduct } from "../@parsers/@text/GetPolygonFromProduct";
28
+ import { GetTextFromProduct } from "../@parsers/@text/GetTextFromProduct";
29
+ import { GetEventOffice } from "./GetEventOffice";
30
+ import { GetEventTags } from "./GetEventTags";
31
+
32
+ interface GetEventPropertiesOptions {
33
+ message: string
34
+ attributes: TypeAttributes
35
+ ugc?: TypeUGC
36
+ pVtec?: TypePVTEC
37
+ hVtec?: TypeHVTEC
38
+ }
39
+
40
+ export const GetEventProperties = (options: GetEventPropertiesOptions): TypeEventProperties => {
41
+ const organization = options.message.match(EnumExpressions.wmo)?.[0] ?? null
42
+ const polygons = getPolygonFromProduct(options.message)
43
+ const properties = {
44
+ locations: options?.ugc?.locations?.join(`; `) ?? null,
45
+ locations_array: options?.ugc?.locations ?? [],
46
+ description: GetDescriptionFromProduct({ message: options.message, handle: options?.pVtec?.vtec ?? null }),
47
+ attributes: options.attributes,
48
+ geocode: {
49
+ office: GetEventOffice({ attributes: options.attributes, organization: organization, pVtec: options.pVtec }),
50
+ organization: organization,
51
+ ugc: options?.ugc?.zones ?? [],
52
+ polygon: polygons.length > 0 ? Buffer.from(JSON.stringify([polygons])).toString('base64') : null,
53
+ polygon_generated: polygons.length > 0 ? true : false
54
+ },
55
+ parameters: {
56
+ tags: GetEventTags(options.message),
57
+ instructions: GetTextFromProduct({ message: options.message, find: [`For your protection`, `do not`, `use extreme caution`], append: `...`, removal: [`.`]}) ?? null,
58
+ source: GetTextFromProduct({ message: options.message, find: [`SOURCE...`], removal: [`.`]}) ?? null,
59
+ hazards: GetTextFromProduct({ message: options.message, find: [`HAZARD...`], removal: [`.`]}) ?? null,
60
+ impacts: GetTextFromProduct({ message: options.message, find: [`IMPACT...`], removal: [`.`]}) ?? null,
61
+ estimated_hail_size: GetTextFromProduct({ message: options.message, find: [`MAX HAIL SIZE...`, `HAIL...`], removal: ['in']}) ?? null,
62
+ estimated_wind_gusts: GetTextFromProduct({ message: options.message, find: [`MAX WIND GUST...`, `WIND...`]}) ?? null,
63
+ damage_threat: GetTextFromProduct({ message: options.message, find: [`DAMAGE THREAT...`], removal: []}) ?? null,
64
+ tornado_threat: GetTextFromProduct({ message: options.message, find: [`TORNADO...`, `WATERSPOUT...`] }) ?? null,
65
+ flood_threat: GetTextFromProduct({ message: options.message, find: [`FLASH FLOOD...`]}) ?? null,
66
+ wind_threat: GetTextFromProduct({ message: options.message, find: [`WIND THREAT...`]}) ?? null,
67
+ hail_threat: GetTextFromProduct({ message: options.message, find: [`HAIL THREAT...`], removal: []}) ?? null,
68
+ },
69
+ discussion_parameters: {
70
+ discussion_number: GetTextFromProduct({ message: options.message, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })?.toString()?.padStart(4, "0") ?? null,
71
+ discussion_concerning: GetTextFromProduct({ message: options.message, find: [`Concerning...`] }) ?? null,
72
+ discussion_max_tornado: GetTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] }) ?? null,
73
+ discussion_max_hail: GetTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] }) ?? null,
74
+ discussion_max_wind: GetTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] }) ?? null,
75
+ discussion_watch_issuance: GetTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`]}) ?? null,
76
+ },
77
+ watch_parameters: {
78
+ watch_number: options?.pVtec?.is_watch ? ( GetTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })?.replace(/(WT|WS|)/g, '')?.trim()?.toString()?.padStart(4, "0") ?? options?.pVtec?.tracking?.slice(-4)?.toString()?.padStart(4, "0") ?? null) : null,
79
+ watch_type: options.message.includes(`TORNADO WATCH`) ? `Tornado` : options?.message.includes(`SEVERE`) ? `Severe` : null,
80
+ additional_tornadoes_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
81
+ strong_tornadoes_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] }) ?? null,
82
+ severe_wind_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
83
+ severe_hail_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
84
+ hail_2in_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] }) ?? null,
85
+ combined_hail_wind_probability: GetTextFromProduct({ message: options.message, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] }) ?? null,
86
+ max_hail_in: GetTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] }) ?? null,
87
+ max_wind_surface: GetTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] }) ?? null,
88
+ max_tops_x100feet: GetTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] }) ?? null,
89
+ pds_watch: (GetTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES` ? true : null)
90
+ }
91
+ }
92
+ if (isNaN(Number(properties.watch_parameters.watch_number))) {
93
+ properties.watch_parameters.watch_number = null
94
+ }
95
+ return properties;
96
96
  }