@atmosx/event-product-parser 3.0.4 → 3.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +1 -1
- package/.github/README.md +163 -0
- package/.github/SUPPORTED_EVENTS.md +370 -0
- package/.github/docs/docs-functions.md +30 -0
- package/.github/docs/docs-general-configurations.md +209 -0
- package/.github/docs/docs-integrations.md +37 -0
- package/.github/docs/docs-listeners.md +28 -0
- package/.github/docs/docs-source-configuration.md +218 -0
- package/.github/docs/docs-technical.md +50 -0
- package/.github/logo.png +0 -0
- package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
- package/.github/samples/SAMPLE_GEOJSON.json +204 -0
- package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +119 -0
- package/dist/cjs/index.cjs +4677 -13422
- package/dist/esm/index.mjs +3159 -11906
- package/package.json +3 -9
- package/src/@building/{building.create.ts → CreateEvent.ts} +25 -11
- package/src/@building/{building.clean.ts → GetCleanedEvent.ts} +2 -2
- package/src/@building/GetEventAttachments.ts +86 -0
- package/src/@building/{building.enhance.ts → GetEventEnhancedName.ts} +11 -12
- package/src/@building/{building.geometry.ts → GetEventGeometry.ts} +7 -7
- package/src/@building/{building.headers.ts → GetEventHeader.ts} +3 -3
- package/src/@building/{building.polygon.ts → GetEventNodes.ts} +13 -11
- package/src/@building/{building.office.ts → GetEventOffice.ts} +6 -6
- package/src/@building/GetEventProperties.ts +96 -0
- package/src/@building/{building.signature.ts → GetEventSignature.ts} +14 -15
- package/src/@building/{building.tags.ts → GetEventTags.ts} +9 -4
- package/src/@building/{building.tracking.ts → GetEventTracking.ts} +15 -15
- package/src/@building/{building.validate.ts → ValidateEvents.ts} +67 -60
- package/src/@core/{core.clearEvents.ts → ClearEvents.ts} +3 -4
- package/src/@core/{core.createListener.ts → CreateListener.ts} +3 -3
- package/src/@core/{core.getEvents.ts → GetEvents.ts} +1 -2
- package/src/@core/{core.getNodes.ts → GetNodes.ts} +1 -2
- package/src/@core/{core.getRandomEvent.ts → GetRandomEvent.ts} +1 -2
- package/src/@core/{core.getVersion.ts → GetVersion.ts} +1 -2
- package/src/@core/ManualEvent.ts +56 -0
- package/src/@core/QueryStanza.ts +39 -0
- package/src/@core/{core.setNode.ts → SetNode.ts} +8 -8
- package/src/@core/{core.start.ts → StartService.ts} +21 -21
- package/src/@core/{core.stop.ts → StopService.ts} +1 -1
- package/src/@enums/AWIPS.ts +366 -0
- package/src/{@dictionaries/dictionaries.eventActions.ts → @enums/Actions.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventCancelMessages.ts → @enums/Cancellation.ts} +2 -1
- package/src/{@dictionaries/dictionaries.eventCauses.ts → @enums/Causes.ts} +1 -1
- package/src/{@dictionaries/dictionaries.statusCorrelationText.ts → @enums/Correlations.ts} +1 -1
- package/src/@enums/Enhanced.ts +70 -0
- package/src/{@dictionaries/dictionaries.eventTypes.ts → @enums/Events.ts} +1 -1
- package/src/{@dictionaries/dictionaries.regExp.ts → @enums/Expressions.ts} +2 -1
- package/src/@enums/GlobalFilter.ts +24 -0
- package/src/{@dictionaries/dictionaries.hailStrings.ts → @enums/Hail.ts} +7 -2
- package/src/{@dictionaries/dictionaries.officeICAOs.ts → @enums/ICAO.ts} +3 -1
- package/src/@enums/Matches.ts +55 -0
- package/src/{@dictionaries/dictionaries.eventProducts.ts → @enums/Products.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventRecords.ts → @enums/Records.ts} +1 -1
- package/src/{@dictionaries/dictionaries.eventSeverity.ts → @enums/Severity.ts} +1 -1
- package/src/{@dictionaries/dictionaries.shapefileLinks.ts → @enums/Shapefiles.ts} +1 -1
- package/src/@enums/States.ts +72 -0
- package/src/{@dictionaries/dictionaries.eventStatus.ts → @enums/Status.ts} +1 -1
- package/src/@enums/Strings.ts +22 -0
- package/src/@enums/Tags.ts +167 -0
- package/src/{@dictionaries/dictionaries.testSignatures.ts → @enums/Testing.ts} +3 -2
- package/src/@events/{events.api.ts → ParseAPI.ts} +42 -38
- package/src/@events/{events.text.ts → ParseText.ts} +25 -18
- package/src/@events/{events.ugc.ts → ParseUGC.ts} +28 -19
- package/src/@events/{events.vtec.ts → ParseVTEC.ts} +21 -21
- package/src/@manager/CreateActions.ts +213 -0
- package/src/@manager/{manager.mkEvent.ts → MakeEvent.ts} +34 -31
- package/src/@manager/RemoveEvent.ts +70 -0
- package/src/@manager/{manager.setHash.ts → SetHash.ts} +8 -9
- package/src/@manager/{manager.updateEvents.ts → UpdateEvents.ts} +9 -9
- package/src/@manager/{manager.updateNodes.ts → UpdateNode.ts} +24 -17
- package/src/@modules/@database/{database.cache.ts → GetCachedEvents.ts} +10 -8
- package/src/@modules/@database/ImportBroadcastify.ts +70 -0
- package/src/@modules/@database/{database.shapefiles.ts → ImportShapefiles.ts} +17 -20
- package/src/@modules/@database/{database.stanza.ts → ImportStanza.ts} +5 -6
- package/src/@modules/@database/{database.init.ts → InitializeDatabase.ts} +25 -11
- package/src/@modules/@eas/GenerateEASMessage.ts +144 -0
- package/src/@modules/@eas/GetCleanDescription.ts +91 -0
- package/src/@modules/@eas/{eas.getFloatPCM16.ts → GetFloatPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getMergedPCM16.ts → GetMergedPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getPCM16.ts → GetPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.getPCMToFloat.ts → GetPCMToFloat.ts} +1 -1
- package/src/@modules/@eas/{eas.getSampledPCM16.ts → GetSampledPCM16.ts} +1 -1
- package/src/@modules/@eas/GetTTS.ts +54 -0
- package/src/@modules/@eas/{eas.getWavPCM16.ts → GetWavPCM16.ts} +1 -1
- package/src/@modules/@eas/{eas.setAFSK.ts → SetAFSK.ts} +1 -2
- package/src/@modules/@eas/{eas.setAsciiToBits.ts → SetAsciiToBits.ts} +1 -2
- package/src/@modules/@eas/{eas.setAttentionTone.ts → SetAttentionTone.ts} +1 -1
- package/src/@modules/@eas/{eas.setNoise.ts → SetNoise.ts} +6 -5
- package/src/@modules/@eas/{eas.setRadioEffect.ts → SetRadioEffect.ts} +6 -5
- package/src/@modules/@eas/{eas.setSameHeader.ts → SetSameHeader.ts} +7 -8
- package/src/@modules/@stanza/{stanza.getAwipsType.ts → GetAwipsType.ts} +11 -9
- package/src/@modules/@stanza/{stanza.validate.ts → ValidateStanza.ts} +9 -9
- package/src/@modules/@utilities/CreateHttp.ts +83 -0
- package/src/@modules/@utilities/{utilities.getFormattedTime.ts → GetFormattedTime.ts} +1 -1
- package/src/@modules/@utilities/GetLatestIssuance.ts +32 -0
- package/src/@modules/@utilities/GetMatched.ts +33 -0
- package/src/@modules/@utilities/{utilities.getSettings.ts → GetSettings.ts} +2 -2
- package/src/@modules/@utilities/{utilities.getShapeNearestPoint.ts → GetShapeNearestPoint.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setCronSchedule.ts → SetCronSchedule.ts} +41 -12
- package/src/{@types/types.webhook.ts → @modules/@utilities/SetDebug.ts} +16 -6
- package/src/@modules/@utilities/{utilities.setEventEmit.ts → SetEventEmit.ts} +5 -5
- package/src/@modules/@utilities/{utilities.setListener.ts → SetListener.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setSettings.ts → SetSettings.ts} +2 -2
- package/src/@modules/@utilities/{utilities.setSleep.ts → SetSleep.ts} +1 -1
- package/src/@modules/@utilities/{utilities.setTimeoutAction.ts → SetTimeoutAction.ts} +8 -3
- package/src/@modules/@utilities/{utilities.setWarning.ts → SetWarning.ts} +2 -2
- package/src/@modules/@xmpp/{xmpp.xDeploy.ts → DeployXMPP.ts} +13 -14
- package/src/@modules/@xmpp/{xmpp.xError.ts → ErrorXMPP.ts} +1 -3
- package/src/@modules/@xmpp/{xmpp.xOffline.ts → OfflineXMPP.ts} +3 -4
- package/src/@modules/@xmpp/{xmpp.xOnline.ts → OnlineXMPP.ts} +6 -5
- package/src/@modules/@xmpp/{xmpp.xReconnect.ts → ReconnectXMPP.ts} +8 -8
- package/src/@modules/@xmpp/{xmpp.xStanza.ts → StanzaXMPP.ts} +11 -11
- package/src/@parsers/@hvtec/{hvtec.extract.ts → HVExtract.ts} +10 -10
- package/src/@parsers/@pvtec/{pvtec.expires.ts → GetExpiry.ts} +1 -1
- package/src/@parsers/@pvtec/{pvtec.extract.ts → VTECExtract.ts} +17 -17
- package/src/@parsers/@text/{text.getDescriptionFromProduct.ts → GetDescriptionFromProduct.ts} +12 -5
- package/src/@parsers/@text/GetEmbededText.ts +56 -0
- package/src/@parsers/@text/{text.getPolygonFromProduct.ts → GetPolygonFromProduct.ts} +31 -10
- package/src/@parsers/@text/GetStringText.ts +58 -0
- package/src/@parsers/@text/{text.getTextFromProduct.ts → GetTextFromProduct.ts} +1 -1
- package/src/@parsers/@text/{text.getXML.ts → GetXML.ts} +1 -1
- package/src/@parsers/@ugc/GetCache.ts +24 -0
- package/src/@parsers/@ugc/{ugc.expiry.ts → GetExpiry.ts} +1 -1
- package/src/@parsers/@ugc/{ugc.locations.ts → GetLocations.ts} +35 -7
- package/src/@parsers/@ugc/{ugc.header.ts → GetUGCHeader.ts} +3 -3
- package/src/@parsers/@ugc/{ugc.coordinates.ts → GetZonePolygon.ts} +4 -3
- package/src/@parsers/@ugc/SetCache.ts +28 -0
- package/src/@parsers/@ugc/{ugc.extract.ts → UGCExtract.ts} +6 -6
- package/src/@types/Actions.ts +37 -0
- package/src/@types/{type.event.ts → Event.ts} +7 -5
- package/src/@types/{type.properties.ts → Properties.ts} +11 -8
- package/src/@types/{types.settings.ts → Settings.ts} +31 -7
- package/src/@types/{types.compiled.ts → StanzaCompiled.ts} +2 -1
- package/src/bootstrap.ts +33 -9
- package/src/index.ts +26 -24
- package/tsup.config.ts +1 -1
- package/README.md +0 -349
- package/dist/index.d.mts +0 -239
- package/dist/index.d.ts +0 -239
- package/src/@building/building.properties.ts +0 -89
- package/src/@dictionaries/dictionaries.betterEventNames.ts +0 -99
- package/src/@dictionaries/dictionaries.eventAwipAbreviations.ts +0 -364
- package/src/@dictionaries/dictionaries.eventTags.ts +0 -93
- package/src/@dictionaries/dictionaries.eventsMatchText.ts +0 -36
- package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +0 -68
- package/src/@manager/manager.rmEvent.ts +0 -49
- package/src/@manager/manager.updateWebhooks.ts +0 -50
- package/src/@modules/@eas/eas.setEasTone.ts +0 -137
- package/src/@modules/@utilities/utilities.createHttp.ts +0 -85
- package/src/@modules/@utilities/utilities.createWebhook.ts +0 -115
- package/test.js +0 -91
- /package/{CODE_OF_CONDUCT.md → .github/CODE_OF_CONDUCT.md} +0 -0
- /package/{LICENSE → .github/LICENSE} +0 -0
- /package/{SECURITY.md → .github/SECURITY.md} +0 -0
- /package/src/@parsers/@ugc/{ugc.zones.ts → GetZones.ts} +0 -0
- /package/src/@types/{types.attributes.ts → Attributes.ts} +0 -0
- /package/src/@types/{types.hvtec.ts → HVTEC.ts} +0 -0
- /package/src/@types/{types.hash.ts → Hash.ts} +0 -0
- /package/src/@types/{types.stanza.ts → Stanza.ts} +0 -0
- /package/src/@types/{types.ugc.ts → UGC.ts} +0 -0
- /package/src/@types/{types.pvtec.ts → VTEC.ts} +0 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://atmosphericx.scriptkitty.cafe">
|
|
3
|
+
<img src="../logo.png" alt="@atmosx/event-product-parser" width="800"/>
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<p>A TypeScript/JavaScript library for parsing and ingesting NOAA and NWS Weather Text Products</p>
|
|
7
|
+
<small>A project built and maintained with ❤️ by the AtmosphericX team</small>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://atmosphericx.scriptkitty.cafe"><b>Documentation</b></a> |
|
|
10
|
+
<a href="https://github.com/AtmosphericX"><b>Repositories</b></a> |
|
|
11
|
+
<a href="https://www.npmjs.com/search?q=%40atmosx"><b>NPM Packages</b></a> |
|
|
12
|
+
<a href="https://atmosphericx-discord.scriptkitty.cafe"><b>Community Discord</b></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<br><br>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 4.0 - General Configurations
|
|
19
|
+
|
|
20
|
+
`@atmosx/event-product-parser` provides a wide range of configuration options, from basic event handling and management to advanced filtering capabilities and customizable event properties. This section provides a comprehensive overview of every available configuration, including event settings, filtering options, and parser behavior, along with detailed explanations and practical examples to help you configure the parser for your specific use case.
|
|
21
|
+
|
|
22
|
+
# 4.1 - Event Management & History
|
|
23
|
+
|
|
24
|
+
**EventManagement** is a core configuration that controls how parsed events are managed throughout their lifecycle. When enabled, the parser automatically stores events in an internal, memory-safe cache, allowing it to efficiently track event issuance, updates, cancellations, upgrades, and expiration. This eliminates the need to implement and maintain your own event caching solution while ensuring event state remains consistent and up to date.
|
|
25
|
+
|
|
26
|
+
Enabling **EventManagement** also unlocks the [ActionSettings](TODO) configuration, which allows you to define actions that are automatically executed after events have been parsed.
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { Manager } from '@atmosx/event-product-parser';
|
|
30
|
+
|
|
31
|
+
const client = new Manager({
|
|
32
|
+
GlobalSettings: {
|
|
33
|
+
EventManagement: true, // Enable event management
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
* Disabling **EventManagement** prevents the parser from tracking previously seen events. As a result, event expiration, cancellation, and update notifications will no longer be emitted. It is **strongly recommended** to leave this option enabled unless you have a specific reason to disable it.
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# 4.2 - Geometry Configurations
|
|
42
|
+
|
|
43
|
+
`@atmosx/event-product-parser` provides configuration options for managing geometry properties associated with each event. These settings allow you to control how event geometries are handled during the receiving, parsing, and memory management stages of the event lifecycle.
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
GlobalSettings: {
|
|
47
|
+
DisableGeometryParsing: false, // Disables geometry parsing
|
|
48
|
+
UseShapefileCoordinates: true, // Uses UGC shapefile coordinate database
|
|
49
|
+
ShapefileSkipPoints: 0, // Skips points while building geometry for shapefiles
|
|
50
|
+
},
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## 4.2.1 - Disable Geometry Parsing
|
|
54
|
+
|
|
55
|
+
The **DisableGeometryParsing** configuration is used to disable event geometry parsing. It was originally introduced as a way to reduce memory usage and improve parsing performance. However, with the introduction of memory-safe event caching, this configuration is now considered redundant and provides limited benefits in most use cases.
|
|
56
|
+
|
|
57
|
+
It is recommended to keep geometry parsing enabled unless you have a specific requirement to exclude geometry data from processed events.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
GlobalSettings: {
|
|
61
|
+
DisableGeometryParsing: true,
|
|
62
|
+
},
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 4.2.2 – Force Shapefile Coordinates
|
|
66
|
+
|
|
67
|
+
The **UseShapefileCoordinates** configuration allows you to obtain geographic coordinates and location information for spatial features. Shapefiles store geometry data such as points, lines, and polygons, which can be used to identify the exact position of features on a map.
|
|
68
|
+
|
|
69
|
+
When this feature is enabled, coordinate data is retrieved from the shapefile database instead of relying on raw polygon coordinate values. Disabling this feature will use the polygon coordinates provided directly in the raw text data.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
GlobalSettings: {
|
|
73
|
+
UseShapefileCoordinates: true
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Example raw polygon coordinates:
|
|
78
|
+
|
|
79
|
+
```text
|
|
80
|
+
LAT...LON 4587 6965 4585 6968 4588 6971 4587 6972
|
|
81
|
+
4584 6970 4576 6972 4576 6976 4577 6978
|
|
82
|
+
4574 6981 4566 6974 4565 6970 4558 6971
|
|
83
|
+
4553 6978 4530 6970 4567 7054 4573 7038
|
|
84
|
+
4580 7042 4589 7026 4596 7026 4598 6968
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 4.2.3 - Shapefile Skip Points
|
|
88
|
+
|
|
89
|
+
The **ShapefileSkipPoints** configuration allows you to skip a specified number of points when building geometry for shapefiles. This can be useful for reducing the complexity of the resulting geometry or for performance reasons. This uses the [polygon-clipping](https://www.npmjs.com/package/polygon-clipping) library.
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
GlobalSettings: {
|
|
93
|
+
ShapefileSkipPoints: 2, // Skip every 2nd point
|
|
94
|
+
},
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
# 4.3 – Tracking Node Settings
|
|
98
|
+
|
|
99
|
+
Tracking nodes are GPS-based longitude/latitude filters used to monitor and manage geographic locations. They allow the system to match, filter, and process data based on specified coordinate positions.
|
|
100
|
+
|
|
101
|
+
Each tracking node is defined by a longitude and latitude location, which is used to determine whether incoming geographic data falls within the configured tracking criteria. This enables location-based filtering and tracking of relevant points or areas. For more information, see [Creating & Configuring Tracking Nodes](TODO).
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
GlobalSettings: {
|
|
106
|
+
NodeTTL: 60 // Time-To-Live (Event Updating)
|
|
107
|
+
NodeMaxDistance: 125 // Miles (Radius)
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 4.3.1 - NodeTTL
|
|
112
|
+
|
|
113
|
+
**NodeTTL** defines how frequently events are updated against your configured tracking node filters.
|
|
114
|
+
During each update cycle, the system evaluates:
|
|
115
|
+
|
|
116
|
+
* Whether the event is inside the tracking node area.
|
|
117
|
+
* The distance from the tracking node (in miles and kilometers).
|
|
118
|
+
* The nearest point distance from the associated polygon boundary.
|
|
119
|
+
|
|
120
|
+
## 4.3.2 - Max Distance
|
|
121
|
+
|
|
122
|
+
**NodeMaxDistance**, defined in *miles*, specifies the maximum distance an event can be from a tracking node before it is filtered out. Events within this distance threshold will continue to be processed by the tracking node filters, while events beyond the configured distance will be ignored.
|
|
123
|
+
|
|
124
|
+
## 4.3.3 - Tracking Node Properties
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"type": "Feature",
|
|
128
|
+
"geometry": {
|
|
129
|
+
"type": "Polygon",
|
|
130
|
+
"coordinates": [[]]
|
|
131
|
+
},
|
|
132
|
+
"properties": {
|
|
133
|
+
"metadata": {
|
|
134
|
+
"nodes": [
|
|
135
|
+
{
|
|
136
|
+
"id": "Tracking Node Test",
|
|
137
|
+
"coordinates": [[]],
|
|
138
|
+
"nearest": [0, 0],
|
|
139
|
+
"miles": 52.1,
|
|
140
|
+
"kilometers": 83.8,
|
|
141
|
+
"proximity": false
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"filtered_proximity": false,
|
|
145
|
+
"updated": 000000000000
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
# 4.4 - Advanced Event Filters
|
|
152
|
+
Filtering is a critical component of `@atmosx/event-product-parser`, allowing your service to selectively process or ignore incoming data. Advanced event filters provide control over events, ICAO identifiers, [UGC (Universal Geographic Code)](https://www.weather.gov/media/documentation/docs/NWS_Geolocation.pdf) areas, states, and geographic locations.
|
|
153
|
+
|
|
154
|
+
These settings allow you to define which data should be processed, as well as exclude unwanted events, locations, or test products.
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
GlobalSettings: {
|
|
159
|
+
EventFiltering: {
|
|
160
|
+
ListeningEvents: [],
|
|
161
|
+
ListeningICAO: [],
|
|
162
|
+
ListeningUGC: [],
|
|
163
|
+
ListeningStates: [],
|
|
164
|
+
IgnoredICAO: [],
|
|
165
|
+
IgnoredEvents: [],
|
|
166
|
+
NodeLocationFiltering: false,
|
|
167
|
+
IgnoreTestProducts: true,
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## 4.4.1 – Events & Wildcards
|
|
173
|
+
|
|
174
|
+
Events can be filtered by using either the **wildcard** syntax or by providing the complete event name.
|
|
175
|
+
|
|
176
|
+
Using wildcards allows you to match multiple related events without needing to define each event individually. For more precise filtering, the full event name can be provided to match only a specific event type.
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
GlobalSettings: {
|
|
180
|
+
EventFiltering: {
|
|
181
|
+
ListeningEvents: [
|
|
182
|
+
`*Tornado Warning*`,
|
|
183
|
+
`Tornado Emergency`,
|
|
184
|
+
`*Thunderstorm Warning*`,
|
|
185
|
+
`Fire Weather Warning`
|
|
186
|
+
]
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
In the configuration above, the `*` character is used as a wildcard to match any text before or after the specified value.
|
|
191
|
+
|
|
192
|
+
* `*Tornado Warning*` matches any event containing **"Tornado Warning"** anywhere in the name.
|
|
193
|
+
* `Tornado Emergency` matches only the exact name **"Tornado Emergency"**.
|
|
194
|
+
* `*Thunderstorm Warning*` matches any event containing **"Thunderstorm Warning"** anywhere in the name.
|
|
195
|
+
* `Fire Weather Warning` matches only the exact name **"Fire Weather Warning"**.
|
|
196
|
+
|
|
197
|
+
Additionally, all events can be processed by setting **ListeningEvents** to an empty array (`[]`). This disables event name filtering and allows all available events to be accepted.
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
## 4.4.2 - ICAOs
|
|
202
|
+
## 4.4.3 - UGC
|
|
203
|
+
## 4.4.4 - States
|
|
204
|
+
## 4.4.5 - Ignoring Filters
|
|
205
|
+
## 4.4.6 - Node Location Filtering
|
|
206
|
+
## 4.4.7 - Test Products
|
|
207
|
+
# 4.5 - Archive Configurations
|
|
208
|
+
## 4.5.1 - TTL (Time-To-Live)
|
|
209
|
+
## 4.5.2 - EAS Toneout
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://atmosphericx.scriptkitty.cafe">
|
|
3
|
+
<img src="../logo.png" alt="@atmosx/event-product-parser" width="800"/>
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<p>A TypeScript/JavaScript library for parsing and ingesting NOAA and NWS Weather Text Products</p>
|
|
7
|
+
<small>A project built and maintained with ❤️ by the AtmosphericX team</small>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://atmosphericx.scriptkitty.cafe"><b>Documentation</b></a> |
|
|
10
|
+
<a href="https://github.com/AtmosphericX"><b>Repositories</b></a> |
|
|
11
|
+
<a href="https://www.npmjs.com/search?q=%40atmosx"><b>NPM Packages</b></a> |
|
|
12
|
+
<a href="https://atmosphericx-discord.scriptkitty.cafe"><b>Community Discord</b></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<br><br>
|
|
16
|
+
|
|
17
|
+
# 5.0 - Actions / Integrations
|
|
18
|
+
|
|
19
|
+
# 5.1 - Action Events & Wildcards
|
|
20
|
+
|
|
21
|
+
# 5.2 - Discord Webhooks
|
|
22
|
+
## 5.2.1 - Ratelimiting
|
|
23
|
+
|
|
24
|
+
# 5.3 - NTFY Push Notifications
|
|
25
|
+
## 5.3.1 - Server Configuration
|
|
26
|
+
## 5.3.2 - Action Configuration
|
|
27
|
+
|
|
28
|
+
# 5.4 - Broadcastify Feed Attachments
|
|
29
|
+
## 5.4.1 - Tag Filtering
|
|
30
|
+
|
|
31
|
+
# 5.5 - Mock EAS Generator
|
|
32
|
+
## 5.5.1 - Linux Prerequisites
|
|
33
|
+
## 5.5.2 - Limitations
|
|
34
|
+
|
|
35
|
+
# 5.6 - Event Archiving
|
|
36
|
+
## 5.6.1 - Raw Text Product Archiving
|
|
37
|
+
## 5.6.2 - GeoJSON Archiving
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://atmosphericx.scriptkitty.cafe">
|
|
3
|
+
<img src="../logo.png" alt="@atmosx/event-product-parser" width="800"/>
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<p>A TypeScript/JavaScript library for parsing and ingesting NOAA and NWS Weather Text Products</p>
|
|
7
|
+
<small>A project built and maintained with ❤️ by the AtmosphericX team</small>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://atmosphericx.scriptkitty.cafe"><b>Documentation</b></a> |
|
|
10
|
+
<a href="https://github.com/AtmosphericX"><b>Repositories</b></a> |
|
|
11
|
+
<a href="https://www.npmjs.com/search?q=%40atmosx"><b>NPM Packages</b></a> |
|
|
12
|
+
<a href="https://atmosphericx-discord.scriptkitty.cafe"><b>Community Discord</b></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<br><br>
|
|
16
|
+
|
|
17
|
+
# 6.0 - Listeners
|
|
18
|
+
# 6.1 - XMPP / NWS Status
|
|
19
|
+
# 6.2 - Test Products
|
|
20
|
+
# 6.3 - Expired Products
|
|
21
|
+
# 6.4 - Specific Product Types
|
|
22
|
+
# 6.5 - Filtered Products
|
|
23
|
+
# 6.6 - Cache Updates
|
|
24
|
+
# 6.7 - Tracking Node Updates
|
|
25
|
+
# 6.8 - Storm Prediction Center Products
|
|
26
|
+
# 6.9 - Debugging
|
|
27
|
+
# 6.10 - Logs / Journal
|
|
28
|
+
# 6.11 - Wildcard
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://atmosphericx.scriptkitty.cafe">
|
|
3
|
+
<img src="../logo.png" alt="@atmosx/event-product-parser" width="800"/>
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<p>A TypeScript/JavaScript library for parsing and ingesting NOAA and NWS Weather Text Products</p>
|
|
7
|
+
<small>A project built and maintained with ❤️ by the AtmosphericX team</small>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://atmosphericx.scriptkitty.cafe"><b>Documentation</b></a> |
|
|
10
|
+
<a href="https://github.com/AtmosphericX"><b>Repositories</b></a> |
|
|
11
|
+
<a href="https://www.npmjs.com/search?q=%40atmosx"><b>NPM Packages</b></a> |
|
|
12
|
+
<a href="https://atmosphericx-discord.scriptkitty.cafe"><b>Community Discord</b></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<br><br>
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# 3.0 - Source Configurations
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
`@atmosx/event-product-parser` supports multiple source configurations that allow you to customize how weather data is ingested and processed. These configurations define the external services, connection methods, and parsing used by the parser to receive weather products. The available source configurations provide flexibility for different data ingestion requirements, allowing you to choose the appropriate source based on your application's needs while maintaining a consistent parsing experience.
|
|
22
|
+
|
|
23
|
+
# 3.1 - NOAA Weather Wire Service
|
|
24
|
+
[NOAA Weather Wire Service](https://www.weather.gov/nwws) is a real-time dissemination service that delivers official weather information, alerts, forecasts, products, and warnings in text format from NWS Weather Forecast Offices and National Centers.
|
|
25
|
+
|
|
26
|
+
This service is designed for television and radio broadcasters, emergency managers, commercial alerting providers, private weather services, and other organizations that require rapid access to weather products.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
Each alert, forecast, and observation is delivered over [XMPP](https://xmpp.org/) using the standardized [WMO Header Format](#34---geojson--wmo-formatting). This provides a consistent structure for automated processing.
|
|
30
|
+
|
|
31
|
+
Accessing the NOAA Weather Wire Service requires credentials, which can be obtained by sending an email to [NWWS.Issue@noaa.gov](mailto:NWWS.Issue@noaa.gov).
|
|
32
|
+
|
|
33
|
+
When requesting access, provide the following information:
|
|
34
|
+
|
|
35
|
+
* Name (First and Last)
|
|
36
|
+
* Company
|
|
37
|
+
* Address
|
|
38
|
+
* State, City, and ZIP Code
|
|
39
|
+
* Telephone Number
|
|
40
|
+
* Account Information: Single or Multiple Accounts
|
|
41
|
+
|
|
42
|
+
NWS processing of your request may take as long as 10 days or more depending on critical weather days and NWS priority requirements.
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
# 3.2 - National Weather Service API
|
|
46
|
+
The [National Weather Service](https://www.weather.gov/) provides a [RESTful API](https://www.weather.gov/documentation/services-web-api) for programmatically accessing weather data and products.
|
|
47
|
+
|
|
48
|
+
Compared to the [NOAA Weather Wire Service](#31---noaa-weather-wire-service), the API introduces additional latency, with data typically delayed by 1 to 2 minutes on average. This delay is one of the primary tradeoffs when using the API instead of NOAA Weather Wire Service for real-time weather product ingestion.
|
|
49
|
+
|
|
50
|
+
The NWS API is best suited for applications that require on demand access to weather data rather than the lowest possible latency delivery of operational weather products. All responses are provided in [GeoJSON](https://geojson.org/) format, making the data straightforward to parse and integrate into applications.
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
# 3.3 - NOAA Weather Wire Service vs NWS RESTful API
|
|
54
|
+
There are significant differences between these two sources. [NOAA Weather Wire Service](#31---noaa-weather-wire-service) requires authenticated access and is optimized for real-time product delivery, while the [NWS RESTful API](#32---national-weather-service-api) is publicly accessible and designed for on demand data retrieval.
|
|
55
|
+
|
|
56
|
+
| Feature | NOAA Weather Wire Service | NWS RESTful API |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| Authentication | ✅ | ❌ |
|
|
59
|
+
| Real-time Delivery | ✅ | ❌ |
|
|
60
|
+
| WMO Formatting | ✅ | ❌ |
|
|
61
|
+
| Persistent Connection | ✅ | ❌ |
|
|
62
|
+
| Low Latency Products | ✅ | ❌ |
|
|
63
|
+
| Easy to Use | ❌ | ✅ |
|
|
64
|
+
| Publicly Accessible | ❌ | ✅ |
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
# 3.4 - GeoJSON & WMO Formatting
|
|
68
|
+
|
|
69
|
+
`@atmosx/event-product-parser` supports two primary data formats when ingesting weather products. The [NOAA Weather Wire Service](#31---noaa-weather-wire-service) uses [WMO Format](#342---wmo-format), while the [National Weather Service API](#32---national-weather-service-api) uses [GeoJSON](#341---geojson).
|
|
70
|
+
|
|
71
|
+
## 3.4.1 - GeoJSON
|
|
72
|
+
[GeoJSON](https://geojson.org/) is a format for encoding a variety of geographic data structures. It is based on the JavaScript Object Notation (JSON) standard and is widely used for representing geographic features in web applications.
|
|
73
|
+
|
|
74
|
+
You can view a real-world sample [here](/.github/samples/SAMPLE_GEOJSON.json).
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"type": "Feature",
|
|
79
|
+
"geometry": {
|
|
80
|
+
"type": "Polygon",
|
|
81
|
+
"coordinates": [[]]
|
|
82
|
+
},
|
|
83
|
+
"properties": {}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## 3.4.2 - WMO Format
|
|
88
|
+
**WMO Format** (World Meteorological Organization Format) is a standardized structure used for exchanging meteorological data, including observations, forecasts, and warnings. It provides a consistent format for weather products, allowing meteorological organizations and systems around the world to reliably share and process weather information.
|
|
89
|
+
|
|
90
|
+
A real-world example of a WMO-formatted product can be found [here](/.github/samples/SAMPLE_TEXT_PRODUCT.txt).
|
|
91
|
+
```text
|
|
92
|
+
000
|
|
93
|
+
WUUS51 KLOT 000000
|
|
94
|
+
SVRGYX
|
|
95
|
+
ILC001-ILC002-
|
|
96
|
+
/O.NEW.XXXX.XX.X.0000.000000T0000Z-000000T0000Z/
|
|
97
|
+
|
|
98
|
+
BULLETIN - IMMEDIATE BROADCAST REQUESTED
|
|
99
|
+
|
|
100
|
+
Severe Thunderstorm Warning
|
|
101
|
+
|
|
102
|
+
National Weather Service
|
|
103
|
+
|
|
104
|
+
XXXX PM Timezone Weekday Month DD 2026
|
|
105
|
+
|
|
106
|
+
TEST EXAMPLE - TEXT EXAMPLE - TEST EXAMPLE
|
|
107
|
+
|
|
108
|
+
&&
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
LAT...LON 4587 6965 4585 6968 4588 6971 4587 6972
|
|
113
|
+
|
|
114
|
+
4584 6970 4576 6972 4576 6976 4577 6978
|
|
115
|
+
|
|
116
|
+
4574 6981 4566 6974 4565 6970 4558 6971
|
|
117
|
+
|
|
118
|
+
4553 6978 4530 6970 4567 7054 4573 7038
|
|
119
|
+
|
|
120
|
+
4580 7042 4589 7026 4596 7026 4598 6968
|
|
121
|
+
|
|
122
|
+
TIME...MOT...LOC 1650Z 313DEG 52KT 4600 7042
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# 3.5 - Configuring NOAA Weather Wire Service
|
|
127
|
+
|
|
128
|
+
Configuring `@atmosx/event-product-parser` to use the [NOAA Weather Wire Service](#31---noaa-weather-wire-service) requires setting up the necessary credentials and connection parameters to establish a persistent connection to the service. This can be configured through the **Manager** class within your application.
|
|
129
|
+
|
|
130
|
+
* Keep in mind that settings configured within `NOAAWeatherWireServiceSettings` only apply to the [NOAA Weather Wire Service](#31---noaa-weather-wire-service) source and do not affect the [National Weather Service API](#32---national-weather-service-api) source.
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { Manager } from '@atmosx/event-product-parser';
|
|
134
|
+
|
|
135
|
+
const client = new Manager({
|
|
136
|
+
EnableWireService: true, // Enable NOAA Weather Wire Service (NWWS)
|
|
137
|
+
NOAAWeatherWireServiceSettings: {
|
|
138
|
+
CredentialSettings: {
|
|
139
|
+
Username: `USERNAME`, // Case sensitive
|
|
140
|
+
Password: `PASSWORD`, // Case sensitive
|
|
141
|
+
Nickname: `NICKNAME`, // Visible to other connected users
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
* Only **one** source can be enabled at a time. (*This project does not use fallback sources*)
|
|
148
|
+
|
|
149
|
+
## 3.5.1 - Auto Reconnecting
|
|
150
|
+
|
|
151
|
+
With [XMPP](https://xmpp.org/) connections, `@atmosx/event-product-parser` can automatically reconnect to the [NOAA Weather Wire Service](#31---noaa-weather-wire-service) if the connection is interrupted.
|
|
152
|
+
|
|
153
|
+
This ensures your application can maintain a persistent connection and continue receiving weather products without requiring manual intervention after temporary network failures or service disruptions.
|
|
154
|
+
|
|
155
|
+
* This configuration only applies to the [NOAA Weather Wire Service](#31---noaa-weather-wire-service) using [XMPP](https://xmpp.org/). The [National Weather Service API](#32---national-weather-service-api) source does not require auto reconnect configuration.
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
NOAAWeatherWireServiceSettings: {
|
|
159
|
+
ReconnectionSettings: {
|
|
160
|
+
Enabled: true, // Enable auto reconnect
|
|
161
|
+
ReconnectionInterval: 60, // Time since last stanza before reconnecting (seconds)
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## 3.5.2 - Stanza Caching
|
|
167
|
+
|
|
168
|
+
Optionally, you can enable stanza caching to retain previously processed [XMPP](https://xmpp.org/) stanzas. This can help prevent data loss in the event that your application requires a fresh restart.
|
|
169
|
+
|
|
170
|
+
* Keep in mind that increasing **MaxRetentionHistory** will increase the amount of time required for `@atmosx/event-product-parser` to initialize, as more cached stanzas must be loaded and processed during startup.
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
NOAAWeatherWireServiceSettings: {
|
|
174
|
+
CacheSettings: {
|
|
175
|
+
Enabled: true, // Enable stanza caching
|
|
176
|
+
MaxDatabaseHistory: 50000, // Maximum stanzas to store in the database
|
|
177
|
+
MaxRetentionHistory: 1200, // Maximum stanzas to load during startup
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 3.5.3 - Stanza Processing Settings
|
|
183
|
+
|
|
184
|
+
While processing stanzas, each one is categorized based on its contents and characteristics. This includes formats such as [CAP (Common Alerting Protocol) v1.2](https://docs.oasis-open.org/emergency/cap/v1.2/CAP-v1.2-os.html), [VTEC](https://www.weather.gov/vtec/), [UGC](https://www.weather.gov/gis/AWIPSShapefiles), and **Raw Text** products. By default, all product categories are enabled by default which includes:
|
|
185
|
+
|
|
186
|
+
* UGC Only Products
|
|
187
|
+
* VTEC/HVTEC Only Products
|
|
188
|
+
* Raw Text (No UGC/VTEC Present)
|
|
189
|
+
|
|
190
|
+
Please keep in mind that the **Common Alerting Protocol** text products will always be skipped as they tend to be slower for ingestion and require extra steps which include parsing [XML](https://www.w3.org/TR/REC-xml/). There is **NO** longer support for this category.
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
```ts
|
|
194
|
+
NOAAWeatherWireServiceSettings: {
|
|
195
|
+
StanzaSettings: {
|
|
196
|
+
DisableUGC: false, // Disables all UGC Categories
|
|
197
|
+
DisableVTEC: false, // Disables all VTEC/HVTEC Categories
|
|
198
|
+
DisableText: false, // Disables all RawText Categories
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# 3.6 - Configuring National Weather Service API
|
|
205
|
+
|
|
206
|
+
The [National Weather Service API](#32---national-weather-service-api) requires minimal configuration compared to the [NOAA Weather Wire Service](#31---noaa-weather-wire-service). While there are fewer available settings, the API source is designed to provide simple access to weather data through RESTful requests without requiring authentication or persistent connections.
|
|
207
|
+
|
|
208
|
+
```ts
|
|
209
|
+
import { Manager } from '@atmosx/event-product-parser';
|
|
210
|
+
|
|
211
|
+
const client = new Manager({
|
|
212
|
+
EnableWireService: false, // Disable NOAA Weather Wire Service (NWWS)
|
|
213
|
+
NationalWeatherServiceSettings: {
|
|
214
|
+
CallbackInterval: 30, // How often it retrieves new products (Minimum: 15 seconds)
|
|
215
|
+
EventsEndpoint: `https://api.weather.gov/alerts/active`, // RESTful API
|
|
216
|
+
},
|
|
217
|
+
});
|
|
218
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://atmosphericx.scriptkitty.cafe">
|
|
3
|
+
<img src="../logo.png" alt="@atmosx/event-product-parser" width="800"/>
|
|
4
|
+
</a>
|
|
5
|
+
<br>
|
|
6
|
+
<p>A TypeScript/JavaScript library for parsing and ingesting NOAA and NWS Weather Text Products</p>
|
|
7
|
+
<small>A project built and maintained with ❤️ by the AtmosphericX team</small>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://atmosphericx.scriptkitty.cafe"><b>Documentation</b></a> |
|
|
10
|
+
<a href="https://github.com/AtmosphericX"><b>Repositories</b></a> |
|
|
11
|
+
<a href="https://www.npmjs.com/search?q=%40atmosx"><b>NPM Packages</b></a> |
|
|
12
|
+
<a href="https://atmosphericx-discord.scriptkitty.cafe"><b>Community Discord</b></a>
|
|
13
|
+
</p>
|
|
14
|
+
</div>
|
|
15
|
+
<br><br>
|
|
16
|
+
|
|
17
|
+
# 8.0 - Technical Parser Documentation
|
|
18
|
+
# 8.1 - Workflow & Pipeline
|
|
19
|
+
# 8.2 - Core Parsing Logic
|
|
20
|
+
## 8.2.1 - VTEC
|
|
21
|
+
### 8.2.1.1 - Product Dictionary
|
|
22
|
+
### 8.2.1.2 - Tracking
|
|
23
|
+
### 8.2.1.3 - Event Dictionary
|
|
24
|
+
### 8.2.1.4 - Status Dictionary
|
|
25
|
+
### 8.2.1.5 - Organization Sender
|
|
26
|
+
### 8.2.1.6 - Expiry Parsing
|
|
27
|
+
### 8.2.1.7 - Watch Parsing
|
|
28
|
+
### 8.2.1.8 - KWNS / SPC
|
|
29
|
+
## 8.2.2 - UGC
|
|
30
|
+
### 8.2.2.1 - Extracting Headers
|
|
31
|
+
### 8.2.2.2 - Getting Zones
|
|
32
|
+
### 8.2.2.3 - Extracting Expiry
|
|
33
|
+
### 8.2.2.4 - UGC to Zones
|
|
34
|
+
## 8.2.3 - HVTEC
|
|
35
|
+
### 8.2.3.1 - Flood Severity
|
|
36
|
+
### 8.2.3.2 - Flood Causes
|
|
37
|
+
### 8.2.3.3 - Flood Records
|
|
38
|
+
## 8.2.4 - Raw Text
|
|
39
|
+
### 8.2.4.1 - Extracting Descriptions
|
|
40
|
+
### 8.2.4.2 - Extracting Coordinates
|
|
41
|
+
### 8.2.4.3 - Extracting String Specifics
|
|
42
|
+
### 8.2.4.4 - Extracting XML
|
|
43
|
+
## 8.2.5 - Building Properties
|
|
44
|
+
## 8.2.6 - Building Geometry
|
|
45
|
+
# 8.3 - Event Validation & Filtering
|
|
46
|
+
## 8.3.1 - Enhanced Event Naming
|
|
47
|
+
## 8.3.2 - Appending Attachments
|
|
48
|
+
## 8.3.3 - Generation Hashes
|
|
49
|
+
# 8.4 - Event & History Management
|
|
50
|
+
# 8.5 - Action Workflow
|
package/.github/logo.png
ADDED
|
Binary file
|
|
Binary file
|