@atmosx/event-product-parser 3.0.621 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/.github/CHANGELOGS.md +52 -0
  2. package/.github/CODE_OF_CONDUCT.md +24 -1
  3. package/.github/CONTRIBUTING.md +22 -3
  4. package/.github/FUNDING.yaml +3 -0
  5. package/.github/LICENSE +24 -1
  6. package/.github/SECURITY.md +25 -6
  7. package/.github/docs/chapters/general-configurations.md +109 -0
  8. package/.github/docs/chapters/sources-and-attributes.md +219 -0
  9. package/README.md +56 -146
  10. package/dist/index.cjs +25333 -0
  11. package/package.json +17 -11
  12. package/pnpm-workspace.yaml +4 -0
  13. package/src/bootstrap.ts +67 -52
  14. package/src/components/audio/GenerateAudioMessage.ts +149 -0
  15. package/src/{@modules/@eas → components/audio/components}/GetCleanDescription.ts +2 -2
  16. package/src/{@modules/@eas → components/audio/components}/GetFloatPCM16.ts +2 -2
  17. package/src/{@modules/@eas → components/audio/components}/GetMergedPCM16.ts +2 -2
  18. package/src/{@modules/@eas → components/audio/components}/GetPCM16.ts +13 -8
  19. package/src/{@modules/@eas → components/audio/components}/GetPCMToFloat.ts +2 -2
  20. package/src/{@modules/@eas → components/audio/components}/GetSampledPCM16.ts +14 -8
  21. package/src/{@modules/@eas → components/audio/components}/GetTTS.ts +17 -10
  22. package/src/{@modules/@eas → components/audio/components}/GetWavPCM16.ts +7 -7
  23. package/src/{@modules/@eas → components/audio/components}/SetAFSK.ts +13 -8
  24. package/src/{@modules/@eas → components/audio/components}/SetAsciiToBits.ts +2 -2
  25. package/src/{@modules/@eas → components/audio/components}/SetAttentionTone.ts +11 -6
  26. package/src/{@modules/@eas → components/audio/components}/SetNoise.ts +12 -7
  27. package/src/{@modules/@eas → components/audio/components}/SetRadioEffect.ts +12 -7
  28. package/src/{@modules/@eas → components/audio/components}/SetSameHeader.ts +22 -14
  29. package/src/components/database/CreateQuery.ts +39 -0
  30. package/src/components/database/InitializeDatabase.ts +71 -0
  31. package/src/components/database/imports/Boundaires.ts +168 -0
  32. package/src/{@modules/@database/ImportBroadcastify.ts → components/database/imports/Broadcastify.ts} +15 -25
  33. package/src/components/database/imports/Census.ts +87 -0
  34. package/src/{@modules/@database/ImportShapefiles.ts → components/database/imports/Shapefiles.ts} +24 -27
  35. package/src/{@modules/@database/ImportStanza.ts → components/database/imports/Stanza.ts} +15 -19
  36. package/src/components/events/CreateEvents.ts +88 -0
  37. package/src/components/events/FilterEvents.ts +149 -0
  38. package/src/{@building/CreateEvent.ts → components/events/ProcessStanza.ts} +22 -24
  39. package/src/components/events/RemoveEvents.ts +74 -0
  40. package/src/{@building → components/events/components}/GetCleanedEvent.ts +2 -2
  41. package/src/{@building → components/events/components}/GetEventAttachments.ts +14 -12
  42. package/src/components/events/components/GetEventDirection.ts +28 -0
  43. package/src/{@building → components/events/components}/GetEventEnhancedName.ts +5 -8
  44. package/src/{@building → components/events/components}/GetEventGeometry.ts +19 -13
  45. package/src/{@building → components/events/components}/GetEventHeader.ts +13 -13
  46. package/src/components/events/components/GetEventMerged.ts +51 -0
  47. package/src/{@building → components/events/components}/GetEventNodes.ts +22 -20
  48. package/src/{@building → components/events/components}/GetEventOffice.ts +13 -13
  49. package/src/components/events/components/GetEventPopulation.ts +58 -0
  50. package/src/components/events/components/GetEventProperties.ts +106 -0
  51. package/src/{@building → components/events/components}/GetEventSignature.ts +9 -9
  52. package/src/{@building → components/events/components}/GetEventTags.ts +3 -3
  53. package/src/components/events/components/GetEventTheme.ts +26 -0
  54. package/src/components/events/components/GetEventTracking.ts +64 -0
  55. package/src/{@modules/@database → components/events/utilities}/GetCachedEvents.ts +18 -15
  56. package/src/{@manager → components/events/utilities}/SetHash.ts +18 -13
  57. package/src/{@manager → components/events/utilities}/UpdateEvents.ts +12 -12
  58. package/src/{@manager → components/events/utilities}/UpdateNode.ts +14 -14
  59. package/src/{@parsers/@text → components/formatting}/GetEmbededText.ts +14 -8
  60. package/src/{@parsers/@text → components/formatting}/GetStringText.ts +15 -11
  61. package/src/{@modules/@utilities → components/geometry}/GetShapeNearestPoint.ts +24 -19
  62. package/src/components/geometry/GetUnionPolygon.ts +36 -0
  63. package/src/components/images/GenerateGraphic.ts +242 -0
  64. package/src/components/images/components/CreateRectangle.ts +22 -0
  65. package/src/components/images/components/CreateText.ts +22 -0
  66. package/src/components/images/modules/CreateSVG.ts +37 -0
  67. package/src/components/images/modules/GetGeographicalBoundaries.ts +72 -0
  68. package/src/components/images/modules/GetGeographicalCities.ts +58 -0
  69. package/src/components/images/modules/GetGeographicalEvents.ts +48 -0
  70. package/src/components/images/modules/GetGeometryBounds.ts +82 -0
  71. package/src/components/images/modules/GetParsedBoundary.ts +58 -0
  72. package/src/components/images/modules/GetSVGPath.ts +53 -0
  73. package/src/components/images/modules/NormalizePolygon.ts +57 -0
  74. package/src/{@modules/@stanza → components/stanza}/GetAwipsType.ts +16 -17
  75. package/src/{@modules/@stanza → components/stanza}/ValidateStanza.ts +27 -15
  76. package/src/{@modules/@utilities → components/utilities}/CreateHttp.ts +26 -26
  77. package/src/components/utilities/EmitThread.ts +97 -0
  78. package/src/{@modules/@utilities → components/utilities}/GetLatestIssuance.ts +2 -2
  79. package/src/{@modules/@utilities → components/utilities}/GetMatched.ts +10 -5
  80. package/src/components/utilities/QueueManager.ts +70 -0
  81. package/src/{@modules/@utilities → components/utilities}/SetDebug.ts +13 -13
  82. package/src/components/utilities/SetEventEmit.ts +42 -0
  83. package/src/{@modules/@utilities → components/utilities}/SetSettings.ts +7 -7
  84. package/src/{@modules/@utilities → components/utilities}/SetSleep.ts +5 -5
  85. package/src/components/utilities/SetTimeoutAction.ts +64 -0
  86. package/src/components/utilities/SetWarning.ts +47 -0
  87. package/src/{@modules/@xmpp → components/xmpp}/DeployXMPP.ts +20 -20
  88. package/src/{@core/CreateListener.ts → components/xmpp/ErrorXMPP.ts} +8 -5
  89. package/src/{@modules/@xmpp → components/xmpp}/OfflineXMPP.ts +13 -13
  90. package/src/{@modules/@xmpp → components/xmpp}/OnlineXMPP.ts +18 -18
  91. package/src/components/xmpp/ReconnectXMPP.ts +64 -0
  92. package/src/{@modules/@xmpp → components/xmpp}/StanzaXMPP.ts +26 -26
  93. package/src/{@enums → enums}/AWIPS.ts +2 -2
  94. package/src/{@enums → enums}/Actions.ts +2 -2
  95. package/src/{@enums → enums}/Cancellation.ts +2 -2
  96. package/src/{@enums → enums}/Causes.ts +2 -2
  97. package/src/{@enums → enums}/Correlations.ts +2 -2
  98. package/src/{@enums → enums}/Enhanced.ts +4 -3
  99. package/src/{@enums → enums}/Events.ts +2 -2
  100. package/src/{@enums → enums}/Expressions.ts +3 -3
  101. package/src/{@enums → enums}/GlobalFilter.ts +2 -2
  102. package/src/{@enums → enums}/Hail.ts +2 -2
  103. package/src/{@enums → enums}/ICAO.ts +2 -2
  104. package/src/{@enums → enums}/Matches.ts +8 -3
  105. package/src/{@enums → enums}/Products.ts +2 -2
  106. package/src/{@enums → enums}/Records.ts +2 -2
  107. package/src/{@enums → enums}/Severity.ts +2 -2
  108. package/src/{@enums → enums}/Shapefiles.ts +2 -2
  109. package/src/{@enums → enums}/States.ts +68 -4
  110. package/src/{@enums → enums}/Status.ts +2 -2
  111. package/src/{@enums → enums}/Strings.ts +2 -2
  112. package/src/{@enums → enums}/Tags.ts +9 -4
  113. package/src/{@enums → enums}/Testing.ts +2 -2
  114. package/src/enums/Themes.ts +70 -0
  115. package/src/events/ParseAPI.ts +133 -0
  116. package/src/{@events → events}/ParseText.ts +24 -22
  117. package/src/{@events → events}/ParseUGC.ts +27 -26
  118. package/src/{@events → events}/ParseVTEC.ts +37 -36
  119. package/src/{@core → exports}/ClearEvents.ts +9 -9
  120. package/src/{@core → exports}/GetEvents.ts +4 -4
  121. package/src/exports/GetNearestCity.ts +45 -0
  122. package/src/{@core → exports}/GetNodes.ts +4 -4
  123. package/src/{@core → exports}/GetRandomEvent.ts +4 -4
  124. package/src/{@core → exports}/GetVersion.ts +4 -4
  125. package/src/exports/ManualEvent.ts +55 -0
  126. package/src/{@core → exports}/QueryStanza.ts +12 -11
  127. package/src/exports/SetNode.ts +100 -0
  128. package/src/{@core → exports}/StartService.ts +23 -22
  129. package/src/{@core → exports}/StopService.ts +10 -10
  130. package/src/index.ts +57 -37
  131. package/src/{@parsers/@hvtec → parsers/hvtec}/HVExtract.ts +7 -7
  132. package/src/{@parsers/@text → parsers/text}/GetDescriptionFromProduct.ts +20 -21
  133. package/src/parsers/text/GetPolygonFromProduct.ts +71 -0
  134. package/src/{@parsers/@text → parsers/text}/GetTextFromProduct.ts +12 -12
  135. package/src/parsers/ugc/GetCache.ts +24 -0
  136. package/src/{@parsers/@ugc → parsers/ugc}/GetExpiry.ts +2 -2
  137. package/src/{@parsers/@ugc/GetUGCHeader.ts → parsers/ugc/GetHeader.ts} +4 -4
  138. package/src/{@parsers/@ugc → parsers/ugc}/GetLocations.ts +10 -10
  139. package/src/parsers/ugc/GetZonePolygon.ts +73 -0
  140. package/src/{@parsers/@ugc → parsers/ugc}/GetZones.ts +3 -3
  141. package/src/{@parsers/@ugc → parsers/ugc}/SetCache.ts +13 -8
  142. package/src/{@parsers/@ugc → parsers/ugc}/UGCExtract.ts +14 -14
  143. package/src/{@parsers/@pvtec → parsers/vtec}/GetExpiry.ts +2 -2
  144. package/src/{@parsers/@pvtec → parsers/vtec}/VTECExtract.ts +17 -17
  145. package/src/tasks/CreateTasks.ts +116 -0
  146. package/src/tasks/TaskGenerateJSON.ts +34 -0
  147. package/src/tasks/TaskGenerateText.ts +34 -0
  148. package/src/tasks/TaskSendNTFY.ts +96 -0
  149. package/src/tasks/TaskSendWebhook.ts +107 -0
  150. package/src/{@types → types/event}/Attributes.ts +2 -3
  151. package/src/{@types → types/event}/Event.ts +8 -7
  152. package/src/{@types → types/event}/HVTEC.ts +2 -2
  153. package/src/{@types → types/event}/Properties.ts +17 -3
  154. package/src/{@types → types/event}/Stanza.ts +2 -2
  155. package/src/{@types → types/event}/VTEC.ts +8 -8
  156. package/src/{@types → types/standard}/Actions.ts +3 -3
  157. package/src/{@types → types/standard}/Hash.ts +5 -5
  158. package/src/{@modules/@utilities/GetSettings.ts → types/standard/Nodes.ts} +15 -7
  159. package/src/{@types → types/standard}/Settings.ts +19 -12
  160. package/src/{@types → types/standard}/StanzaCompiled.ts +15 -15
  161. package/src/{@types → types/standard}/UGC.ts +5 -5
  162. package/tools/build.js +32 -0
  163. package/tsconfig.json +32 -1
  164. package/.github/SUPPORTED_EVENTS.md +0 -370
  165. package/.github/docs/docs-functions.md +0 -30
  166. package/.github/docs/docs-general-configurations.md +0 -209
  167. package/.github/docs/docs-integrations.md +0 -37
  168. package/.github/docs/docs-listeners.md +0 -28
  169. package/.github/docs/docs-source-configuration.md +0 -218
  170. package/.github/docs/docs-technical.md +0 -50
  171. package/.github/logo.png +0 -0
  172. package/.github/samples/SAMPLE_EAS_GENERATION.wav +0 -0
  173. package/.github/samples/SAMPLE_GEOJSON.json +0 -204
  174. package/.github/samples/SAMPLE_TEXT_PRODUCT.txt +0 -119
  175. package/dist/cjs/index.cjs +0 -8005
  176. package/dist/esm/index.mjs +0 -7985
  177. package/src/@building/GetEventProperties.ts +0 -96
  178. package/src/@building/GetEventTracking.ts +0 -68
  179. package/src/@core/ManualEvent.ts +0 -56
  180. package/src/@core/SetNode.ts +0 -81
  181. package/src/@events/ParseAPI.ts +0 -117
  182. package/src/@manager/MakeEvents.ts +0 -106
  183. package/src/@manager/RemoveEvent.ts +0 -70
  184. package/src/@manager/Tasks.ts +0 -246
  185. package/src/@manager/ValidateEvents.ts +0 -142
  186. package/src/@modules/@database/InitializeDatabase.ts +0 -59
  187. package/src/@modules/@eas/GenerateEASMessage.ts +0 -144
  188. package/src/@modules/@utilities/GetFormattedTime.ts +0 -43
  189. package/src/@modules/@utilities/SetCronSchedule.ts +0 -94
  190. package/src/@modules/@utilities/SetEventEmit.ts +0 -41
  191. package/src/@modules/@utilities/SetListener.ts +0 -30
  192. package/src/@modules/@utilities/SetTimeoutAction.ts +0 -64
  193. package/src/@modules/@utilities/SetWarning.ts +0 -34
  194. package/src/@modules/@xmpp/ErrorXMPP.ts +0 -27
  195. package/src/@modules/@xmpp/ReconnectXMPP.ts +0 -64
  196. package/src/@parsers/@text/GetPolygonFromProduct.ts +0 -53
  197. package/src/@parsers/@text/GetXML.ts +0 -61
  198. package/src/@parsers/@ugc/GetCache.ts +0 -24
  199. package/src/@parsers/@ugc/GetZonePolygon.ts +0 -111
  200. package/tsup.config.ts +0 -16
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@atmosx/event-product-parser",
3
- "version": "3.0.621",
3
+ "version": "3.1.0",
4
4
  "description": "NOAA Weather Wire & NWS API Parser - Built for standalone and Project AtmosphericX Integration.",
5
- "main": "dist/cjs/index.cjs",
6
- "module": "dist/esm/index.mjs",
5
+ "main": "dist/index.cjs",
7
6
  "repository": {
8
7
  "type": "git",
9
8
  "url": "git+https://github.com/AtmosphericX/event-product-parser",
10
- "branch": "v3-beta-branch"
9
+ "branch": "b3.1"
11
10
  },
12
11
  "scripts": {
13
12
  "start": "cd ./test && node ./index.js",
14
- "build": "tsup && cd ./test && node ./index.js",
15
- "publish": "tsup && npm publish --access public",
16
- "publish-beta-branch": "tsup && npm publish --tag v3-beta-branch --access public"
13
+ "build": "node ./tools/build.js && cd ./test && node index.js",
14
+ "watch": "node ./tools/build.js --watch",
15
+ "publish": "node ./tools/build.js && npm publish --access public",
16
+ "publish-b3.1": "node ./tools/build.js && npm publish --tag b3.1 --access public"
17
17
  },
18
18
  "keywords": [
19
19
  "NWWS",
@@ -32,17 +32,23 @@
32
32
  },
33
33
  "homepage": "https://github.com/AtmosphericX/event-product-parser#readme",
34
34
  "dependencies": {
35
- "@atmosx/event-product-parser": "link:",
36
35
  "@xmpp/client": "0.14.0",
37
36
  "better-sqlite3": "12.9.0",
38
37
  "croner": "10.0.1",
38
+ "d3-geo": "3.1.1",
39
+ "esbuild": "0.28.1",
39
40
  "jszip": "3.10.1",
40
41
  "polygon-clipping": "0.15.7",
41
42
  "shapefile": "0.6.6",
43
+ "sharp": "0.35.3",
44
+ "topojson-client": "3.1.0",
42
45
  "typescript": "5.9.3"
43
46
  },
44
47
  "devDependencies": {
45
- "@types/node": "25.2.0",
46
- "tsup": "8.5.1"
48
+ "@types/better-sqlite3": "7.6.13",
49
+ "@types/d3-geo": "3.1.0",
50
+ "@types/shapefile": "0.6.4",
51
+ "@types/topojson-client": "3.1.5",
52
+ "@types/xmpp__client": "0.14.1"
47
53
  }
48
- }
54
+ }
@@ -0,0 +1,4 @@
1
+ allowBuilds:
2
+ better-sqlite3: true
3
+ esbuild: true
4
+ minimumReleaseAge: 43830
package/src/bootstrap.ts CHANGED
@@ -11,53 +11,63 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
  */
19
19
 
20
- import path from 'path'
21
- import { EventEmitter } from 'node:events';
20
+ import { TypeEvent } from "TypesEvent/Event"
21
+ import { TypeHash } from "TypesStandard/Hash"
22
+ import { TypeActions } from "TypesStandard/Actions"
23
+ import { TypeNode } from "TypesStandard/Nodes"
24
+ import { EnumThemes } from "@Enums/Themes"
25
+ import { EventEmitter } from "node:events"
26
+ import { client } from "@xmpp/client"
27
+ import { Database } from "better-sqlite3"
28
+ import { join } from "path"
22
29
 
23
- export const bootstrap = {
24
- version: `3.0.621`,
25
- isReady: true,
26
- ratelimits: {},
27
- session_xmpp: null,
28
- database: null,
29
- cron: null,
30
- listener: new EventEmitter(),
31
- ansi_colors: {
32
- RED: `\x1b[31m`, GREEN: `\x1b[32m`, YELLOW: `\x1b[33m`,
33
- BLUE: `\x1b[34m`, MAGENTA: `\x1b[35m`, CYAN: `\x1b[36m`,
34
- WHITE: `\x1b[37m`, RESET: `\x1b[0m`
30
+ export const Bootstrap = {
31
+ Version: `b3.1`,
32
+ Ready: true,
33
+ Ratelimits: {} as Record<string, number[]>,
34
+ Session: null as ReturnType<typeof client>,
35
+ Database: null as Database,
36
+ Job: null as unknown,
37
+ Listener: new EventEmitter(),
38
+ Colors: {
39
+ Red: `\x1b[31m`, Green: `\x1b[32m`, Yellow: `\x1b[33m`,
40
+ Blue: `\x1b[34m`, Magenta: `\x1b[35m`, Cyan: `\x1b[36m`,
41
+ White: `\x1b[37m`, Reset: `\x1b[0m`
35
42
  },
36
- cache: {
37
- lastStanza: null,
38
- isConnected: false,
39
- isReconnecting: false,
40
- tReconnects: 0,
41
- sigHault: false,
42
- events: {type: "FeatureCollection", features: []},
43
- nodes: {type: "FeatureCollection", features: []},
44
- hashes: [],
45
- processed: [],
46
- ugc: new Map<string, string[]>()
43
+ Cache: {
44
+ LastStanzaTime: null as number,
45
+ Connected: false,
46
+ Reconnecting: false,
47
+ TotalReconnects: 0,
48
+ Hault: false,
49
+ Events: {type: "FeatureCollection", features: [] as TypeEvent[]},
50
+ Nodes: {type: "FeatureCollection", features: [] as TypeNode[]},
51
+ Hashes: [] as TypeHash[],
52
+ Parsed: [] as TypeEvent[],
53
+ UGC: new Map<string, string[]>()
47
54
  },
48
- settings: {
49
- Database: path.join(process.cwd(), 'shapefiles.db'),
55
+ Settings: {
56
+ Timezone: "UTC",
57
+ Database: join(process.cwd(), 'shapefiles.db'),
58
+ DeveloperDisableEvents: false,
50
59
  EnableWireService: false,
51
- EnableDebugging: false,
60
+ DeveloperMode: false,
52
61
  EnableJournal: true,
62
+ DeveloperEventLogging: false,
53
63
  NOAAWeatherWireServiceSettings: {
54
64
  ReconnectionSettings: {
55
65
  Enabled: true,
56
66
  ReconnectionInterval: 60,
57
67
  },
58
68
  CredentialSettings: {
59
- Username: null,
60
- Password: null,
69
+ Username: null as string,
70
+ Password: null as string,
61
71
  Nickname: "@atmosx/event-product-parser/3.0",
62
72
  },
63
73
  CacheSettings: {
@@ -80,45 +90,50 @@ export const bootstrap = {
80
90
  BroadcastifyDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/broadcastify.json`,
81
91
  BroadcastifyTags: [`Ham`, `Air`, `Fire`, `Public Safety`, `Weather`, `EMS`, `Police`, `Rail`]
82
92
  },
93
+ BoundarySettings: {
94
+ BoundaryDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/counties-10m.json`,
95
+ CityDatabase: `https://scriptkitty.cafe/ftp/@atmosphericx/assets/cities500.json`
96
+ },
83
97
  NotifyServer: {
84
98
  Enabled: false,
85
99
  Server: `https://ntfy.sh`,
86
- Timezone: "UTC",
87
100
  MediaStorage: {
88
- EAS: null,
89
- TEXT: null,
90
- JSON: null,
101
+ AUDIO: null as string,
102
+ TEXT: null as string,
103
+ JSON: null as string,
104
+ IMAGE: null as string
91
105
  },
92
106
  Credentials: {
93
- Username: null,
94
- Password: null
107
+ Username: null as string,
108
+ Password: null as string
95
109
  }
96
110
  },
97
- ActionSettings: [],
111
+ ActionSettings: [] as TypeActions[],
98
112
  GlobalSettings: {
99
- EventManagement: true,
100
113
  DisableGeometryParsing: false,
101
114
  UseShapefileCoordinates: true,
102
- SPCWatchesOnly: true,
103
- ShapefileSkipPoints: 15,
104
- NodeTTL: 60,
115
+ CensusPopulationData: true,
116
+ NodePolygonTTL: 60,
105
117
  NodeMaxDistance: 120,
106
118
  EventFiltering: {
107
- ListeningEvents: [],
108
- ListeningICAO: [],
109
- ListeningUGC: [],
110
- ListeningStates: [],
111
- IgnoredICAO: [],
119
+ ListeningEvents: [] as string[],
120
+ ListeningICAO: [] as string[],
121
+ ListeningUGC: [] as string[],
122
+ ListeningStates: [] as string[],
123
+ IgnoredICAO: [] as string[],
112
124
  IgnoredEvents: [`Test Message`],
113
125
  NodeLocationFiltering: false,
114
126
  IgnoreTestProducts: true,
115
127
  },
128
+ Themes: EnumThemes,
116
129
  ArchiveSettings: {
117
130
  TTL: 60,
118
- JSONDirectory: null,
119
- TextDirectory: null,
120
- EasDirectory: null,
121
- EasToneout: null
131
+ ImageDirectory: `Archive/Images` as string,
132
+ JSONDirectory: `Archive/Products` as string,
133
+ TextDirectory: `Archive/Text` as string,
134
+ AudioDirectory: `Archive/Audio` as string,
135
+ Logo: null as string,
136
+ AudioToneout: null as string
122
137
  }
123
138
  }
124
139
  },
@@ -0,0 +1,149 @@
1
+ /*
2
+ _ _ _ __ __
3
+ /\ | | | | (_) \ \ / /
4
+ / \ | |_ _ __ ___ ___ ___ _ __ | |__ ___ _ __ _ ___ \ V /
5
+ / /\ \| __| '_ ` _ \ / _ \/ __| '_ \| '_ \ / _ \ '__| |/ __| > <
6
+ / ____ \ |_| | | | | | (_) \__ \ |_) | | | | __/ | | | (__ / . \
7
+ /_/ \_\__|_| |_| |_|\___/|___/ .__/|_| |_|\___|_| |_|\___/_/ \_\
8
+ | |
9
+ |_|
10
+
11
+ Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
+ Discord: https://atmosphericx-discord.scriptkitty.cafe
13
+ Ko-Fi: https://ko-fi.com/k3yomi
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
+
16
+ Independent Package: @atmosx/event-product-parser
17
+
18
+ */
19
+
20
+ import { TypeSettings } from "TypesStandard/Settings"
21
+ import { Bootstrap } from "@Bootstrap"
22
+ import { GetWavPCM16 } from "@AudioComponents/GetWavPCM16"
23
+ import { GetSampledPCM16 } from "@AudioComponents/GetSampledPCM16"
24
+ import { SetRadioEffect } from "@AudioComponents/SetRadioEffect"
25
+ import { SetSameHeader } from "@AudioComponents/SetSameHeader"
26
+ import { SetAttentionTone } from "@AudioComponents/SetAttentionTone"
27
+ import { GetMergedPCM16 } from "@AudioComponents/GetMergedPCM16"
28
+ import { SetNoise } from "@AudioComponents/SetNoise"
29
+ import { GetPCM16 } from "@AudioComponents/GetPCM16"
30
+ import { GetTTS } from "@AudioComponents/GetTTS"
31
+ import { GetCleanDescription } from "@AudioComponents/GetCleanDescription"
32
+ import { SetWarning } from "@Utilities/SetWarning"
33
+ import { SetDebug } from "@Utilities/SetDebug"
34
+ import { join } from "path"
35
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from "fs"
36
+ import { execSync } from "child_process"
37
+ import { platform } from "os"
38
+
39
+ interface GenerateAudioMessageOptions {
40
+ Message: string
41
+ Header: string
42
+ Directory?: string
43
+ Title: string
44
+ }
45
+
46
+ export const GenerateAudioMessage = async ({ Message, Directory, Header, Title }: GenerateAudioMessageOptions): Promise<string> => {
47
+ const tick = performance.now()
48
+ const settings = Bootstrap.Settings as TypeSettings;
49
+ const prefix = settings.GlobalSettings.ArchiveSettings.AudioToneout;
50
+ let title = (Title ?? `${Math.random().toString(36).substring(2, 15)}-${Header.replace(/[^a-zA-Z0-9]/g, '')}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
51
+ if (!Message || !Header) {
52
+ SetWarning({
53
+ Title: `Audio`,
54
+ Message: `Message and header are required to generate an audio message.`
55
+ })
56
+ return null;
57
+ }
58
+ let buffTTS: Buffer;
59
+ let buffRadio: any;
60
+ let buffFull: any[] = [];
61
+
62
+ if (!Directory) {
63
+ SetWarning({
64
+ Title: `Audio`,
65
+ Message: `Audio directory is not set in the settings. Please set it to generate audio messages.`
66
+ });
67
+ return null;
68
+ }
69
+
70
+ if (!existsSync(Directory)) {
71
+ mkdirSync(Directory, { recursive: true });
72
+ }
73
+ const tmpTTS = join(Directory, `/${title}-tts.wav`)
74
+ const outTTS = join(Directory, `/${title}.wav`)
75
+ const vPlatform = platform();
76
+
77
+ if (vPlatform === 'darwin') {
78
+ SetWarning({
79
+ Title: `Audio`,
80
+ Message: `Audio tone generation is not supported on macOS.`
81
+ });
82
+ return null
83
+ }
84
+
85
+
86
+ await new Promise<void>((resolve, reject) => {
87
+ const tMsg = GetCleanDescription(Message)
88
+ GetTTS({Text: tMsg, OutputPath: tmpTTS}).then(() => {
89
+ resolve();
90
+ });
91
+ });
92
+ if (!existsSync(tmpTTS)) {
93
+ return null;
94
+ }
95
+ buffTTS = readFileSync(tmpTTS);
96
+ const vWav = GetWavPCM16(buffTTS);
97
+ const vSamples = GetSampledPCM16({Int16: vWav.Samples, OriginalRate: vWav.SampleRate, TargetRate: 8000})
98
+ const vRadio = SetRadioEffect({Int16: vSamples, SampleRate: 8000});
99
+
100
+ if (existsSync(prefix)) {
101
+ let tBuffer = readFileSync(prefix);
102
+ let tWav = GetWavPCM16(tBuffer);
103
+
104
+ if (tWav == null) {
105
+ try {
106
+ const converted = join(Directory, `/${title}-tts-fixed.wav`)
107
+ execSync(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: 'ignore' })
108
+ if (existsSync(converted)) {
109
+ tBuffer = readFileSync(converted)
110
+ tWav = GetWavPCM16(tBuffer)
111
+ try { unlinkSync(converted) } catch {}
112
+ }
113
+ } catch (e) {}
114
+ }
115
+
116
+ if (tWav == null) {
117
+ SetWarning({
118
+ Title: `EAS`,
119
+ Message: `Intro tone isn't a valid .WAV file or isn't in PCM 16-bit format. Converted attempt failed; please convert it then try again.`
120
+ })
121
+ return null;
122
+ }
123
+
124
+ const tSamples = (tWav.SampleRate != 8000 ? GetSampledPCM16({Int16: tWav.Samples, OriginalRate: tWav.SampleRate, TargetRate: 8000}) : tWav.Samples)
125
+ buffRadio = SetRadioEffect({Int16: tSamples, SampleRate: 8000})
126
+ }
127
+
128
+ buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8000))] : [];
129
+ buffFull.push(
130
+ SetSameHeader({ VTEC: Header, Repeats: 3, SampleRate: 8000, PreMarkSec: 1.1, GapSec: 0.5 }),
131
+ new Int16Array(Math.floor(0.5 * 8000)),
132
+ SetAttentionTone({ MS: 8, SampleRate: 8000 }),
133
+ new Int16Array(Math.floor(0.5 * 8000)),
134
+ vRadio
135
+ )
136
+ for (let i = 0; i < 3; i++) {
137
+ buffFull.push(SetSameHeader({ VTEC: Header, Repeats: 1, SampleRate: 8000, PreMarkSec: 0.5, GapSec: 0.1 }))
138
+ buffFull.push(new Int16Array(Math.floor(0.5 * 8000)));
139
+ }
140
+ const aSamples = GetMergedPCM16(buffFull);
141
+ const aFinal = SetNoise({ Int16: aSamples, NoiseLevel: 0.002 });
142
+ const aBuffer = GetPCM16({ Samples: Array.from(aFinal).map(v => ({ value: v })), SampleRate: 8000 });
143
+ writeFileSync(outTTS, aBuffer)
144
+ try{ unlinkSync(tmpTTS) } catch {}
145
+ SetDebug({ Title: `GenerateEASMessage`, Message: `${Math.round(performance.now() - tick)}ms` })
146
+ return outTTS;
147
+ }
148
+
149
+
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
@@ -11,19 +11,24 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
20
20
 
21
- export const GetPCM16 = (samples: Record<string, number>[], sampleRate: number): Buffer => {
21
+ interface GetPCM16Options {
22
+ Samples: Record<string, number>[]
23
+ SampleRate: number
24
+ }
25
+
26
+ export const GetPCM16 = ({ Samples, SampleRate }: GetPCM16Options): Buffer => {
22
27
  let o = 0;
23
28
  const bytesPerSample = 2;
24
29
  const blockAlign = 1 * bytesPerSample;
25
- const byteRate = sampleRate * blockAlign;
26
- const subchunk2Size = samples.length * bytesPerSample;
30
+ const byteRate = SampleRate * blockAlign;
31
+ const subchunk2Size = Samples.length * bytesPerSample;
27
32
  const chunkSize = 36 + subchunk2Size;
28
33
  const buffer = Buffer.alloc(44 + subchunk2Size);
29
34
 
@@ -35,7 +40,7 @@ export const GetPCM16 = (samples: Record<string, number>[], sampleRate: number):
35
40
  buffer.writeUInt32LE(16, o); o += 4;
36
41
  buffer.writeUInt16LE(1, o); o += 2;
37
42
  buffer.writeUInt16LE(1, o); o += 2;
38
- buffer.writeUInt32LE(sampleRate, o); o += 4;
43
+ buffer.writeUInt32LE(SampleRate, o); o += 4;
39
44
  buffer.writeUInt32LE(byteRate, o); o += 4;
40
45
  buffer.writeUInt16LE(blockAlign, o); o += 2;
41
46
  buffer.writeUInt16LE(16, o); o += 2;
@@ -43,8 +48,8 @@ export const GetPCM16 = (samples: Record<string, number>[], sampleRate: number):
43
48
  buffer.write("data", o); o += 4;
44
49
  buffer.writeUInt32LE(subchunk2Size, o); o += 4;
45
50
 
46
- for (let i = 0; i < samples.length; i++, o += 2) {
47
- buffer.writeInt16LE(samples[i].value, o);
51
+ for (let i = 0; i < Samples.length; i++, o += 2) {
52
+ buffer.writeInt16LE(Samples[i].value, o);
48
53
  }
49
54
  return buffer;
50
55
  }
@@ -11,9 +11,9 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
@@ -11,24 +11,30 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
20
20
 
21
- export const GetSampledPCM16 = (int16: Int16Array, originalRate: number, targetRate: number): Int16Array => {
22
- if (originalRate === targetRate) return int16;
23
- const ratio = targetRate / originalRate;
24
- const outLen = Math.max(1, Math.round(int16.length * ratio));
21
+ interface GetSampledPCM16Options {
22
+ Int16: Int16Array
23
+ OriginalRate: number
24
+ TargetRate: number
25
+ }
26
+
27
+ export const GetSampledPCM16 = ({ Int16, OriginalRate, TargetRate }: GetSampledPCM16Options): Int16Array => {
28
+ if (OriginalRate === TargetRate) return Int16;
29
+ const ratio = TargetRate / OriginalRate;
30
+ const outLen = Math.max(1, Math.round(Int16.length * ratio));
25
31
  const out = new Int16Array(outLen);
26
32
  for (let i = 0; i < outLen; i++) {
27
33
  const pos = i / ratio;
28
34
  const i0 = Math.floor(pos);
29
- const i1 = Math.min(i0 + 1, int16.length - 1);
35
+ const i1 = Math.min(i0 + 1, Int16.length - 1);
30
36
  const frac = pos - i0;
31
- const v = int16[i0] * (1 - frac) + int16[i1] * frac;
37
+ const v = Int16[i0] * (1 - frac) + Int16[i1] * frac;
32
38
  out[i] = Math.round(v);
33
39
  }
34
40
  return out;
@@ -11,33 +11,40 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
20
20
 
21
- import { platform } from 'os'
22
- import { writeFileSync } from "fs"
23
- import { execSync } from 'child_process'
21
+ import { platform } from "os"
22
+ import { writeFileSync, unlinkSync} from "fs"
23
+ import { execSync } from "child_process"
24
24
 
25
- export const GetTTS = async (text: string, outputPath: string): Promise<void> => {
25
+
26
+ interface GetTTSOptions {
27
+ Text: string
28
+ OutputPath: string
29
+ }
30
+
31
+ export const GetTTS = async ({ Text, OutputPath }: GetTTSOptions): Promise<void> => {
26
32
  const vPlatform = platform();
27
33
  switch (vPlatform) {
28
34
  case 'win32': {
29
35
  try {
30
- const txtPath = outputPath + ".txt";
31
- writeFileSync(txtPath, text, "utf8");
36
+ const txtPath = OutputPath + ".txt";
37
+ writeFileSync(txtPath, Text, "utf8");
32
38
  const command = [
33
39
  "Add-Type -AssemblyName System.Speech;",
34
40
  `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
35
41
  `$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
36
- `$speak.SetOutputToWaveFile('${outputPath}');`,
42
+ `$speak.SetOutputToWaveFile('${OutputPath}');`,
37
43
  `$speak.Speak($text);`,
38
44
  `$speak.Dispose();`
39
45
  ].join(" ");
40
46
  execSync(`powershell -Command "${command}"`, { stdio: 'inherit' })
47
+ try{ unlinkSync(txtPath) } catch {}
41
48
  } catch(error) {
42
49
  console.error('Error occurred while generating TTS:', error);
43
50
  }
@@ -45,7 +52,7 @@ export const GetTTS = async (text: string, outputPath: string): Promise<void> =>
45
52
  }
46
53
  case 'linux':
47
54
  try {
48
- execSync(`espeak -w "${outputPath}" "${text.replace(/"/g, '\\"')}"`);
55
+ execSync(`espeak -w "${OutputPath}" "${Text.replace(/"/g, '\\"')}"`);
49
56
  } catch {}
50
57
  break;
51
58
  default: break;
@@ -11,18 +11,18 @@
11
11
  Created with ♥ by the AtmosphericX Team (KiyoWx, StarflightWx, & CJ Ziegler)
12
12
  Discord: https://atmosphericx-discord.scriptkitty.cafe
13
13
  Ko-Fi: https://ko-fi.com/k3yomi
14
- Documentation: http://localhost/documentation | https://atmosphericx.scriptkitty.cafe/documentation
14
+ Documentation: https://atmosphericx.scriptkitty.cafe/documentation
15
15
 
16
- Internal Package: @atmosx/event-product-parser
16
+ Independent Package: @atmosx/event-product-parser
17
17
 
18
18
 
19
19
  */
20
20
 
21
21
  interface getWavPCM16Response {
22
- samples: Int16Array
23
- sampleRate: number
24
- channels: number
25
- bitsPerSample: number
22
+ Samples: Int16Array
23
+ SampleRate: number
24
+ Channels: number
25
+ BitsPerSample: number
26
26
  }
27
27
 
28
28
  export const GetWavPCM16 = (buffer: Buffer): getWavPCM16Response => {
@@ -46,7 +46,7 @@ export const GetWavPCM16 = (buffer: Buffer): getWavPCM16Response => {
46
46
  const bitsPerSample = fmt.readUInt16LE(14);
47
47
  if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) { return null; }
48
48
  const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
49
- return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
49
+ return { Samples: new Int16Array(samples), SampleRate: sampleRate, Channels: channels, BitsPerSample: bitsPerSample };
50
50
  }
51
51
 
52
52