@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,114 +1,114 @@
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
- interface GetShapeNearestPointResponse {
21
- proximity: boolean
22
- point: [number, number]
23
- distance: number | null
24
- distanceKm?: number | null
25
- distanceMeters?: number | null
26
- }
27
-
28
- export const getShapeNearestPoint = (coordinates: number[][], point: [number, number]): GetShapeNearestPointResponse => {
29
- if (!coordinates || !point) {
30
- return { proximity: false, point: [0, 0], distance: null }
31
- }
32
- const normalize = (coords: any): any[] => {
33
- if (!Array.isArray(coords)) return [];
34
- if (typeof coords[0] === 'number' && typeof coords[1] === 'number') return [];
35
- if (Array.isArray(coords[0]) && typeof coords[0][0] === 'number') {
36
- return [[coords]];
37
- }
38
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === 'number') {
39
- return [coords];
40
- }
41
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === 'number') {
42
- return coords;
43
- }
44
- return [];
45
- }
46
- const polys = normalize(coordinates);
47
- if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
48
- const lon = point[0];
49
- const lat = point[1];
50
- const pointInRing = (pt: [number, number], ring: number[][]): boolean => {
51
- let x = pt[0], y = pt[1];
52
- let inside = false;
53
- for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
54
- const xi = ring[i][0], yi = ring[i][1];
55
- const xj = ring[j][0], yj = ring[j][1];
56
- const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi);
57
- if (intersect) inside = !inside;
58
- }
59
- return inside;
60
- };
61
-
62
- const toRadians = (deg: number) => (deg * Math.PI) / 180;
63
- const haversineMiles = (a: [number, number], b: [number, number]) => {
64
- const R = 3958.8;
65
- const dLat = toRadians(b[1] - a[1]);
66
- const dLon = toRadians(b[0] - a[0]);
67
- const lat1 = toRadians(a[1]);
68
- const lat2 = toRadians(b[1]);
69
- const sinDLat = Math.sin(dLat / 2);
70
- const sinDLon = Math.sin(dLon / 2);
71
- const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
72
- return R * c;
73
- };
74
- let minDistance = Infinity;
75
- let closestPoint: [number, number] | null = null;
76
- for (const poly of polys) {
77
- const outer = poly[0];
78
- const holes = poly.slice(1);
79
- if (pointInRing(point, outer)) {
80
- let inHole = false;
81
- for (const hole of holes) {
82
- if (pointInRing(point, hole)) { inHole = true; break; }
83
- }
84
- if (!inHole) {
85
- return { proximity: true, point, distance: 0 };
86
- }
87
- }
88
- for (const ring of poly) {
89
- for (let i = 0; i < ring.length - 1; i++) {
90
- const start = [ring[i][0], ring[i][1]] as [number, number];
91
- const end = [ring[i+1][0], ring[i+1][1]] as [number, number];
92
- const A = lon - start[0];
93
- const B = lat - start[1];
94
- const C = end[0] - start[0];
95
- const D = end[1] - start[1];
96
- const lenSq = C*C + D*D;
97
- const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A*C + B*D) / lenSq));
98
- const candidate: [number, number] = [start[0] + t*C, start[1] + t*D];
99
- const dist = haversineMiles([lon, lat], candidate);
100
- if (!isNaN(dist) && dist < minDistance) {
101
- minDistance = Number(dist.toFixed(3));
102
- closestPoint = candidate;
103
- }
104
- }
105
- }
106
- }
107
- if (!isFinite(minDistance) || closestPoint == null) {
108
- return { proximity: false, point: [0,0], distance: null };
109
- }
110
- const distanceMiles = minDistance;
111
- const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
112
- const distanceMeters = Math.round(distanceKm * 1000);
113
- return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
114
- }
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
+ interface GetShapeNearestPointResponse {
21
+ proximity: boolean
22
+ point: [number, number]
23
+ distance: number | null
24
+ distanceKm?: number | null
25
+ distanceMeters?: number | null
26
+ }
27
+
28
+ export const GetShapeNearestPoint = (coordinates: number[][], point: [number, number]): GetShapeNearestPointResponse => {
29
+ if (!coordinates || !point) {
30
+ return { proximity: false, point: [0, 0], distance: null }
31
+ }
32
+ const normalize = (coords: any): any[] => {
33
+ if (!Array.isArray(coords)) return [];
34
+ if (typeof coords[0] === 'number' && typeof coords[1] === 'number') return [];
35
+ if (Array.isArray(coords[0]) && typeof coords[0][0] === 'number') {
36
+ return [[coords]];
37
+ }
38
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === 'number') {
39
+ return [coords];
40
+ }
41
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === 'number') {
42
+ return coords;
43
+ }
44
+ return [];
45
+ }
46
+ const polys = normalize(coordinates);
47
+ if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
48
+ const lon = point[0];
49
+ const lat = point[1];
50
+ const pointInRing = (pt: [number, number], ring: number[][]): boolean => {
51
+ let x = pt[0], y = pt[1];
52
+ let inside = false;
53
+ for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {
54
+ const xi = ring[i][0], yi = ring[i][1];
55
+ const xj = ring[j][0], yj = ring[j][1];
56
+ const intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi);
57
+ if (intersect) inside = !inside;
58
+ }
59
+ return inside;
60
+ };
61
+
62
+ const toRadians = (deg: number) => (deg * Math.PI) / 180;
63
+ const haversineMiles = (a: [number, number], b: [number, number]) => {
64
+ const R = 3958.8;
65
+ const dLat = toRadians(b[1] - a[1]);
66
+ const dLon = toRadians(b[0] - a[0]);
67
+ const lat1 = toRadians(a[1]);
68
+ const lat2 = toRadians(b[1]);
69
+ const sinDLat = Math.sin(dLat / 2);
70
+ const sinDLon = Math.sin(dLon / 2);
71
+ const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
72
+ return R * c;
73
+ };
74
+ let minDistance = Infinity;
75
+ let closestPoint: [number, number] | null = null;
76
+ for (const poly of polys) {
77
+ const outer = poly[0];
78
+ const holes = poly.slice(1);
79
+ if (pointInRing(point, outer)) {
80
+ let inHole = false;
81
+ for (const hole of holes) {
82
+ if (pointInRing(point, hole)) { inHole = true; break; }
83
+ }
84
+ if (!inHole) {
85
+ return { proximity: true, point, distance: 0 };
86
+ }
87
+ }
88
+ for (const ring of poly) {
89
+ for (let i = 0; i < ring.length - 1; i++) {
90
+ const start = [ring[i][0], ring[i][1]] as [number, number];
91
+ const end = [ring[i+1][0], ring[i+1][1]] as [number, number];
92
+ const A = lon - start[0];
93
+ const B = lat - start[1];
94
+ const C = end[0] - start[0];
95
+ const D = end[1] - start[1];
96
+ const lenSq = C*C + D*D;
97
+ const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A*C + B*D) / lenSq));
98
+ const candidate: [number, number] = [start[0] + t*C, start[1] + t*D];
99
+ const dist = haversineMiles([lon, lat], candidate);
100
+ if (!isNaN(dist) && dist < minDistance) {
101
+ minDistance = Number(dist.toFixed(3));
102
+ closestPoint = candidate;
103
+ }
104
+ }
105
+ }
106
+ }
107
+ if (!isFinite(minDistance) || closestPoint == null) {
108
+ return { proximity: false, point: [0,0], distance: null };
109
+ }
110
+ const distanceMiles = minDistance;
111
+ const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
112
+ const distanceMeters = Math.round(distanceKm * 1000);
113
+ return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
114
+ }
@@ -1,94 +1,94 @@
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
-
21
- import { TypeSettings } from "../../@types/type.settings";
22
- import { xReconnect } from "../@xmpp/xmpp.xReconnect"
23
- import { bootstrap } from "../../bootstrap";
24
- import { createHttp } from "./utilities.createHttp";
25
- import { createEvent } from "../../@building/building.create";
26
- import { setEventEmit } from "./utilities.setEventEmit";
27
- import { readdirSync, unlinkSync, statSync, existsSync } from "fs";
28
- import { join } from "path";
29
-
30
- export const setCronSchedule = async (): Promise<void> => {
31
- const settings = bootstrap.settings as TypeSettings;
32
-
33
- const TTL = settings.GlobalSettings.ArchiveSettings.TTL
34
- const TTLCUT = Date.now() - TTL * 1000;
35
-
36
- const walk = (dir: string): void => {
37
- if (existsSync(dir)) {
38
- const entries = readdirSync(dir, { withFileTypes: true });
39
- for (const entry of entries) {
40
- const fullPath = join(dir, entry.name);
41
- if (entry.isDirectory()) { walk(fullPath); continue; }
42
- const stats = statSync(fullPath);
43
- if (stats.mtime.getTime() < TTLCUT) {
44
- try {
45
- unlinkSync(fullPath);
46
- } catch (err) {
47
- console.error(`Failed to delete ${fullPath}:`, err);
48
- }
49
- }
50
- }
51
- }
52
- };
53
- walk(settings.GlobalSettings.ArchiveSettings.TextDirectory)
54
- walk(settings.GlobalSettings.ArchiveSettings.EasDirectory)
55
- walk(settings.GlobalSettings.ArchiveSettings.EventDirectory)
56
-
57
-
58
-
59
- if (settings.EnableWireService) {
60
- if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
61
- void xReconnect(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval)
62
- }
63
- } else {
64
- const response = await createHttp({
65
- url: settings.NationalWeatherServiceSettings.EventsEndpoint,
66
- headers: {
67
- "User-Agent": "@atmosx/event-product-parser"
68
- }
69
- })
70
- if (response.error) {
71
- return setEventEmit({
72
- event: `onServiceStatus`,
73
- metadata: {
74
- type: "fetch-api",
75
- message: `Failed to fetch latest events from National Weather Service API - ${response.message}`,
76
- data: {},
77
- error: true
78
- },
79
- })
80
- }
81
- setEventEmit({
82
- event: `onServiceStatus`,
83
- metadata: {
84
- message: `Fetched latest events from National Weather Service API`,
85
- data: {},
86
- type: "fetch-api",
87
- error: false
88
- },
89
- })
90
- createEvent({ message: response.message, isNWWS: false })
91
- }
92
- }
93
-
94
-
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
+
21
+ import { TypeSettings } from "../../@types/Settings";
22
+ import { ReconnectXMPP } from "../@xmpp/ReconnectXMPP"
23
+ import { bootstrap } from "../../bootstrap";
24
+ import { CreateHttp } from "./CreateHttp";
25
+ import { CreateEvent } from "../../@building/CreateEvent";
26
+ import { SetEventEmit } from "./SetEventEmit";
27
+ import { readdirSync, unlinkSync, statSync, existsSync } from "fs";
28
+ import { join } from "path";
29
+
30
+ export const SetCronSchedule = async (): Promise<void> => {
31
+ const settings = bootstrap.settings as TypeSettings;
32
+
33
+ const TTL = settings.GlobalSettings.ArchiveSettings.TTL
34
+ const TTLCUT = Date.now() - TTL * 1000;
35
+
36
+ const walk = (dir: string): void => {
37
+ if (existsSync(dir)) {
38
+ const entries = readdirSync(dir, { withFileTypes: true });
39
+ for (const entry of entries) {
40
+ const fullPath = join(dir, entry.name);
41
+ if (entry.isDirectory()) { walk(fullPath); continue; }
42
+ const stats = statSync(fullPath);
43
+ if (stats.mtime.getTime() < TTLCUT) {
44
+ try {
45
+ unlinkSync(fullPath);
46
+ } catch (err) {
47
+ console.error(`Failed to delete ${fullPath}:`, err);
48
+ }
49
+ }
50
+ }
51
+ }
52
+ };
53
+ walk(settings.GlobalSettings.ArchiveSettings.TextDirectory)
54
+ walk(settings.GlobalSettings.ArchiveSettings.EasDirectory)
55
+ walk(settings.GlobalSettings.ArchiveSettings.JSONDirectory)
56
+
57
+
58
+
59
+ if (settings.EnableWireService) {
60
+ if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
61
+ void ReconnectXMPP(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval)
62
+ }
63
+ } else {
64
+ const response = await CreateHttp({
65
+ url: settings.NationalWeatherServiceSettings.EventsEndpoint,
66
+ headers: {
67
+ "User-Agent": "@atmosx/event-product-parser"
68
+ }
69
+ })
70
+ if (response.error) {
71
+ return SetEventEmit({
72
+ event: `onServiceStatus`,
73
+ metadata: {
74
+ type: "fetch-api",
75
+ message: `Failed to fetch latest events from National Weather Service API - ${response.message}`,
76
+ data: {},
77
+ error: true
78
+ },
79
+ })
80
+ }
81
+ SetEventEmit({
82
+ event: `onServiceStatus`,
83
+ metadata: {
84
+ message: `Fetched latest events from National Weather Service API`,
85
+ data: {},
86
+ type: "fetch-api",
87
+ error: false
88
+ },
89
+ })
90
+ await CreateEvent({ message: response.message, isNWWS: false })
91
+ }
92
+ }
93
+
94
+
@@ -1,38 +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 { TypeSettings } from "../../@types/type.settings";
21
- import { bootstrap } from "../../bootstrap"
22
-
23
- interface SetDebugOptions {
24
- title?: string
25
- message: string
26
- }
27
-
28
- export const setDebug = (options: SetDebugOptions): void => {
29
- const settings = bootstrap.settings as TypeSettings;
30
- bootstrap.listener.emit(`debug`, {
31
- message: options.message,
32
- parent: options?.title?.split(`.`)[0]?.replace(`@`, ``),
33
- function: options?.title?.split(`.`)[1]
34
- })
35
- if (settings.EnableDebugging) {
36
- console.log(`[${bootstrap.ansi_colors.BLUE}${options.title ?? `debug`}${bootstrap.ansi_colors.RESET}] ${options.message}`)
37
- }
38
- }
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 { bootstrap } from "../../bootstrap"
22
+
23
+ interface SetDebugOptions {
24
+ title?: string
25
+ message: string
26
+ }
27
+
28
+ export const SetDebug = (options: SetDebugOptions): void => {
29
+ const settings = bootstrap.settings as TypeSettings;
30
+ bootstrap.listener.emit(`debug`, {
31
+ message: options.message,
32
+ function: options.title ?? `debug`,
33
+ })
34
+ if (settings.EnableDebugging) {
35
+ console.log(`[${bootstrap.ansi_colors.BLUE}${options.title ?? `debug`}${bootstrap.ansi_colors.RESET}] ${options.message}`)
36
+ }
37
+ }
@@ -1,41 +1,41 @@
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 { bootstrap } from "../../bootstrap"
21
- import { setTimeoutAction } from "./utilities.setTimeoutAction";
22
- import { setWarning } from "./utilities.setWarning";
23
-
24
- interface SetEventEmitOptions {
25
- event: string
26
- metadata: any
27
- message?: string
28
- limited?: boolean
29
- }
30
-
31
- export const setEventEmit = (options: SetEventEmitOptions): void => {
32
- if (options.limited) {
33
- const isTimeout = setTimeoutAction({ identifier: `event.${options.event}`, addTime: true, max: 1, interval: 1 })
34
- if (isTimeout.limited) return;
35
- }
36
- bootstrap.listener.emit(options.event, options.metadata)
37
- if (options.event != `log`) { bootstrap.listener.emit(`*`, {event: options.event, data: options.metadata}) }
38
- if (options.message) {
39
- setWarning({ message: options.message })
40
- }
41
- }
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 { bootstrap } from "../../bootstrap"
21
+ import { SetTimeoutAction } from "./SetTimeoutAction";
22
+ import { SetWarning } from "./SetWarning";
23
+
24
+ interface SetEventEmitOptions {
25
+ event: string
26
+ metadata: any
27
+ message?: string
28
+ limited?: boolean
29
+ }
30
+
31
+ export const SetEventEmit = (options: SetEventEmitOptions): void => {
32
+ if (options.limited) {
33
+ const isTimeout = SetTimeoutAction({ identifier: `event.${options.event}`, addTime: true, max: 1, interval: 1 })
34
+ if (isTimeout.limited) return;
35
+ }
36
+ bootstrap.listener.emit(options.event, options.metadata)
37
+ if (options.event != `log`) { bootstrap.listener.emit(`*`, {event: options.event, data: options.metadata}) }
38
+ if (options.message) {
39
+ SetWarning({ message: options.message })
40
+ }
41
+ }
@@ -1,30 +1,30 @@
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 { bootstrap } from "../../bootstrap"
21
-
22
- interface SetListenerOptions {
23
- event: string,
24
- callback: () => void
25
- }
26
-
27
- export const setListener = (options: SetListenerOptions): (() => void) => {
28
- bootstrap.listener.on(options.event, options.callback)
29
- return () => { void bootstrap.listener.off(options.event, options.callback) };
30
- }
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 { bootstrap } from "../../bootstrap"
21
+
22
+ interface SetListenerOptions {
23
+ event: string,
24
+ callback: () => void
25
+ }
26
+
27
+ export const SetListener = (options: SetListenerOptions): (() => void) => {
28
+ bootstrap.listener.on(options.event, options.callback)
29
+ return () => { void bootstrap.listener.off(options.event, options.callback) };
30
+ }