@atmosx/event-product-parser 3.0.48 → 3.0.52

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 (141) hide show
  1. package/.vscode/settings.json +3 -3
  2. package/CODE_OF_CONDUCT.md +9 -9
  3. package/CONTRIBUTING.md +29 -29
  4. package/LICENSE +17 -17
  5. package/README.md +443 -417
  6. package/SECURITY.md +20 -20
  7. package/SUPPORTED_EVENTS.md +369 -368
  8. package/dist/cjs/index.cjs +1925 -1885
  9. package/dist/esm/index.mjs +1927 -1887
  10. package/package.json +52 -52
  11. package/src/@building/building.attachments.ts +82 -82
  12. package/src/@building/building.clean.ts +29 -29
  13. package/src/@building/building.create.ts +55 -41
  14. package/src/@building/building.enhance.ts +59 -59
  15. package/src/@building/building.geometry.ts +47 -47
  16. package/src/@building/building.headers.ts +36 -36
  17. package/src/@building/building.office.ts +42 -42
  18. package/src/@building/building.polygon.ts +69 -70
  19. package/src/@building/building.properties.ts +95 -95
  20. package/src/@building/building.signature.ts +60 -61
  21. package/src/@building/building.tags.ts +23 -23
  22. package/src/@building/building.tracking.ts +67 -67
  23. package/src/@building/building.validate.ts +152 -146
  24. package/src/@core/core.clearEvents.ts +30 -31
  25. package/src/@core/core.createListener.ts +23 -23
  26. package/src/@core/core.getEvents.ts +23 -24
  27. package/src/@core/core.getNodes.ts +23 -24
  28. package/src/@core/core.getRandomEvent.ts +23 -24
  29. package/src/@core/core.getVersion.ts +23 -24
  30. package/src/@core/core.manualEvent.ts +38 -0
  31. package/src/@core/core.query.ts +38 -38
  32. package/src/@core/core.setNode.ts +80 -80
  33. package/src/@core/core.start.ts +60 -60
  34. package/src/@core/core.stop.ts +31 -31
  35. package/src/@dictionaries/dictionaries.actions.ts +27 -27
  36. package/src/@dictionaries/dictionaries.awips.ts +363 -363
  37. package/src/@dictionaries/dictionaries.cancellation.ts +30 -30
  38. package/src/@dictionaries/dictionaries.causes.ts +35 -35
  39. package/src/@dictionaries/dictionaries.correlations.ts +42 -42
  40. package/src/@dictionaries/dictionaries.enhanced.ts +66 -109
  41. package/src/@dictionaries/dictionaries.events.ts +82 -82
  42. package/src/@dictionaries/dictionaries.expressions.ts +28 -28
  43. package/src/@dictionaries/dictionaries.global.ts +24 -0
  44. package/src/@dictionaries/dictionaries.hail.ts +35 -35
  45. package/src/@dictionaries/dictionaries.icao.ts +258 -258
  46. package/src/@dictionaries/dictionaries.matches.ts +54 -35
  47. package/src/@dictionaries/dictionaries.products.ts +24 -24
  48. package/src/@dictionaries/dictionaries.records.ts +25 -25
  49. package/src/@dictionaries/dictionaries.severity.ts +27 -27
  50. package/src/@dictionaries/dictionaries.shapefiles.ts +35 -35
  51. package/src/@dictionaries/dictionaries.states.ts +71 -71
  52. package/src/@dictionaries/dictionaries.status.ts +30 -30
  53. package/src/@dictionaries/dictionaries.tags.ts +92 -92
  54. package/src/@dictionaries/dictionaries.testing.ts +24 -24
  55. package/src/@events/events.api.ts +116 -118
  56. package/src/@events/events.text.ts +84 -81
  57. package/src/@events/events.ugc.ts +89 -85
  58. package/src/@events/events.vtec.ts +86 -87
  59. package/src/@manager/manager.mkEvent.ts +97 -88
  60. package/src/@manager/manager.rmEvent.ts +56 -49
  61. package/src/@manager/manager.setHash.ts +35 -36
  62. package/src/@manager/manager.updateEvents.ts +32 -34
  63. package/src/@manager/manager.updateListener.ts +154 -159
  64. package/src/@manager/manager.updateNodes.ts +53 -54
  65. package/src/@modules/@database/database.broadcastify.ts +66 -66
  66. package/src/@modules/@database/database.cache.ts +49 -47
  67. package/src/@modules/@database/database.init.ts +58 -57
  68. package/src/@modules/@database/database.shapefiles.ts +92 -92
  69. package/src/@modules/@database/database.stanza.ts +46 -47
  70. package/src/@modules/@eas/eas.getCleanDescription.ts +91 -91
  71. package/src/@modules/@eas/eas.getFloatPCM16.ts +29 -29
  72. package/src/@modules/@eas/eas.getMergedPCM16.ts +32 -32
  73. package/src/@modules/@eas/eas.getPCM16.ts +52 -52
  74. package/src/@modules/@eas/eas.getPCMToFloat.ts +26 -26
  75. package/src/@modules/@eas/eas.getSampledPCM16.ts +36 -36
  76. package/src/@modules/@eas/eas.getTTS.ts +54 -54
  77. package/src/@modules/@eas/eas.getWavPCM16.ts +52 -52
  78. package/src/@modules/@eas/eas.setAFSK.ts +51 -52
  79. package/src/@modules/@eas/eas.setAsciiToBits.ts +31 -32
  80. package/src/@modules/@eas/eas.setAttentionTone.ts +40 -40
  81. package/src/@modules/@eas/eas.setEasTone.ts +151 -147
  82. package/src/@modules/@eas/eas.setNoise.ts +32 -31
  83. package/src/@modules/@eas/eas.setRadioEffect.ts +50 -49
  84. package/src/@modules/@eas/eas.setSameHeader.ts +44 -45
  85. package/src/@modules/@stanza/stanza.getAwipsType.ts +45 -45
  86. package/src/@modules/@stanza/stanza.validate.ts +49 -49
  87. package/src/@modules/@utilities/utilities.createHttp.ts +70 -70
  88. package/src/@modules/@utilities/utilities.getFormattedTime.ts +43 -43
  89. package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -32
  90. package/src/@modules/@utilities/utilities.getMatched.ts +33 -0
  91. package/src/@modules/@utilities/utilities.getSettings.ts +25 -25
  92. package/src/@modules/@utilities/utilities.getShapeNearestPoint.ts +114 -114
  93. package/src/@modules/@utilities/utilities.setCronSchedule.ts +94 -94
  94. package/src/@modules/@utilities/utilities.setDebug.ts +38 -0
  95. package/src/@modules/@utilities/utilities.setEventEmit.ts +41 -41
  96. package/src/@modules/@utilities/utilities.setListener.ts +30 -30
  97. package/src/@modules/@utilities/utilities.setSettings.ts +42 -42
  98. package/src/@modules/@utilities/utilities.setSleep.ts +33 -33
  99. package/src/@modules/@utilities/utilities.setTimeoutAction.ts +62 -58
  100. package/src/@modules/@utilities/utilities.setWarning.ts +34 -34
  101. package/src/@modules/@xmpp/xmpp.xDeploy.ts +57 -58
  102. package/src/@modules/@xmpp/xmpp.xError.ts +26 -28
  103. package/src/@modules/@xmpp/xmpp.xOffline.ts +36 -37
  104. package/src/@modules/@xmpp/xmpp.xOnline.ts +45 -44
  105. package/src/@modules/@xmpp/xmpp.xReconnect.ts +64 -64
  106. package/src/@modules/@xmpp/xmpp.xStanza.ts +62 -62
  107. package/src/@parsers/@hvtec/hvtec.extract.ts +39 -39
  108. package/src/@parsers/@pvtec/pvtec.expires.ts +25 -25
  109. package/src/@parsers/@pvtec/pvtec.extract.ts +48 -48
  110. package/src/@parsers/@text/text.getDescriptionFromProduct.ts +52 -52
  111. package/src/@parsers/@text/text.getEmbed.ts +55 -57
  112. package/src/@parsers/@text/text.getPolygonFromProduct.ts +53 -32
  113. package/src/@parsers/@text/text.getTextFromProduct.ts +42 -42
  114. package/src/@parsers/@text/text.getXML.ts +60 -60
  115. package/src/@parsers/@ugc/ugc.coordinates.ts +110 -109
  116. package/src/@parsers/@ugc/ugc.expiry.ts +31 -31
  117. package/src/@parsers/@ugc/ugc.extract.ts +36 -36
  118. package/src/@parsers/@ugc/ugc.getCache.ts +24 -0
  119. package/src/@parsers/@ugc/ugc.header.ts +29 -29
  120. package/src/@parsers/@ugc/ugc.locations.ts +57 -29
  121. package/src/@parsers/@ugc/ugc.setCache.ts +28 -0
  122. package/src/@parsers/@ugc/ugc.zones.ts +51 -51
  123. package/src/@types/type.attributes.ts +28 -28
  124. package/src/@types/type.compiled.ts +34 -34
  125. package/src/@types/type.event.ts +69 -69
  126. package/src/@types/type.hash.ts +24 -24
  127. package/src/@types/type.hvtec.ts +25 -25
  128. package/src/@types/type.listener.ts +32 -32
  129. package/src/@types/type.properties.ts +77 -77
  130. package/src/@types/type.pvtec.ts +30 -30
  131. package/src/@types/type.settings.ts +84 -83
  132. package/src/@types/type.stanza.ts +37 -37
  133. package/src/@types/type.ugc.ts +24 -24
  134. package/src/bootstrap.ts +115 -112
  135. package/src/index.ts +74 -74
  136. package/test.js +92 -98
  137. package/tsconfig.json +13 -13
  138. package/tsup.config.ts +15 -15
  139. package/dist/index.d.mts +0 -299
  140. package/dist/index.d.ts +0 -299
  141. package/src/@core/core.createEvent.ts +0 -83
@@ -1104,13 +1104,13 @@ var index_exports = {};
1104
1104
  __export(index_exports, {
1105
1105
  Manager: () => Manager,
1106
1106
  clearEvents: () => clearEvents,
1107
- createEvent: () => createEvent2,
1108
1107
  default: () => index_default,
1109
1108
  getCleanedEvent: () => getCleanedEvent,
1110
1109
  getEventGeometry: () => getEventGeometry,
1111
1110
  getEvents: () => getEvents,
1112
1111
  getNodes: () => getNodes,
1113
1112
  getRandomEvent: () => getRandomEvent,
1113
+ manualEvent: () => manualEvent,
1114
1114
  query: () => query,
1115
1115
  setEasTone: () => setEasTone,
1116
1116
  setNode: () => setNode,
@@ -1124,7 +1124,7 @@ module.exports = __toCommonJS(index_exports);
1124
1124
  var import_path = __toESM(require("path"));
1125
1125
  var import_node_events = require("events");
1126
1126
  var bootstrap = {
1127
- version: `3.0.48`,
1127
+ version: `3.0.52`,
1128
1128
  isReady: true,
1129
1129
  ratelimits: {},
1130
1130
  session_xmpp: null,
@@ -1149,11 +1149,14 @@ var bootstrap = {
1149
1149
  sigHault: false,
1150
1150
  events: { type: "FeatureCollection", features: [] },
1151
1151
  nodes: { type: "FeatureCollection", features: [] },
1152
- hashes: []
1152
+ hashes: [],
1153
+ processed: [],
1154
+ ugc: /* @__PURE__ */ new Map()
1153
1155
  },
1154
1156
  settings: {
1155
1157
  Database: import_path.default.join(process.cwd(), "shapefiles.db"),
1156
- EnableWireService: true,
1158
+ EnableWireService: false,
1159
+ EnableDebugging: false,
1157
1160
  EnableJournal: true,
1158
1161
  NOAAWeatherWireServiceSettings: {
1159
1162
  ReconnectionSettings: {
@@ -1190,7 +1193,7 @@ var bootstrap = {
1190
1193
  EventManagement: true,
1191
1194
  BetterEventNames: true,
1192
1195
  DisableGeometryParsing: false,
1193
- UseShapefileCoordinates: false,
1196
+ UseShapefileCoordinates: true,
1194
1197
  SPCWatchesOnly: true,
1195
1198
  ShapefileSkipPoints: 15,
1196
1199
  NodeTTL: 60,
@@ -1322,7 +1325,7 @@ var getZonePolygon = (options) => {
1322
1325
  };
1323
1326
 
1324
1327
  // src/@building/building.geometry.ts
1325
- var getEventGeometry = (event) => __async(null, null, function* () {
1328
+ var getEventGeometry = (event) => {
1326
1329
  var _a, _b, _c, _d, _e, _f;
1327
1330
  const settings = getSettings();
1328
1331
  const generated = (_c = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.geocode) == null ? void 0 : _b.polygon) != null ? _c : null;
@@ -1332,7 +1335,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1332
1335
  coordinates: generated != null ? JSON.parse(Buffer.from(generated, "base64").toString("utf-8")) : null
1333
1336
  };
1334
1337
  if (settings.GlobalSettings.UseShapefileCoordinates && generated == null && ugc2 != null) {
1335
- geo = yield getZonePolygon({ zones: ugc2, isUnion: false });
1338
+ geo = getZonePolygon({ zones: ugc2, isUnion: false });
1336
1339
  if (geo == null) {
1337
1340
  geo = {
1338
1341
  type: `Polygon`,
@@ -1341,7 +1344,7 @@ var getEventGeometry = (event) => __async(null, null, function* () {
1341
1344
  }
1342
1345
  }
1343
1346
  return geo;
1344
- });
1347
+ };
1345
1348
 
1346
1349
  // src/@building/building.clean.ts
1347
1350
  var getCleanedEvent = (event) => {
@@ -1364,6 +1367,9 @@ var setTimeoutAction = (options) => {
1364
1367
  bootstrap.ratelimits[options == null ? void 0 : options.identifier] = [];
1365
1368
  target = bootstrap.ratelimits[options == null ? void 0 : options.identifier];
1366
1369
  }
1370
+ if (options == null ? void 0 : options.expire) {
1371
+ delete bootstrap.ratelimits[options == null ? void 0 : options.identifier];
1372
+ }
1367
1373
  if ((target == null ? void 0 : target.length) > 0) {
1368
1374
  bootstrap.ratelimits[options == null ? void 0 : options.identifier] = target.filter((ts) => Date.now() - ts < (options == null ? void 0 : options.interval) * 1e3);
1369
1375
  target = bootstrap.ratelimits[options == null ? void 0 : options.identifier];
@@ -4194,7 +4200,8 @@ var xOnline = () => {
4194
4200
  data: {},
4195
4201
  type: `online`,
4196
4202
  error: false
4197
- }
4203
+ },
4204
+ message: `Succesfully connected to NOAA Weather Wire Service as "${nickname}"`
4198
4205
  });
4199
4206
  }));
4200
4207
  };
@@ -4516,9 +4523,9 @@ var dict_awips = {
4516
4523
  SVR: `severe-thunderstorm-warning`,
4517
4524
  SVS: `severe-weather-statement`,
4518
4525
  SWOMCD: `mesoscale-discussion`,
4519
- SWODY1: `day-1`,
4520
- SWODY2: `day-2`,
4521
- SWODY3: `day-3`,
4526
+ SWODY1: `SPC-day-1-outlook`,
4527
+ SWODY2: `SPC-day-2-outlook`,
4528
+ SWODY3: `SPC-day-3-outlook`,
4522
4529
  SWS: `state-weather-summary`,
4523
4530
  SYN: `regional-weather-synopsis`,
4524
4531
  TAF: `terminal-aerodrome-forecast`,
@@ -4538,7 +4545,7 @@ var dict_awips = {
4538
4545
  TOE: `telephone-outage-emergency`,
4539
4546
  TOR: `tornado-warning`,
4540
4547
  TPT: `temperature-precipitation-table`,
4541
- TSU: `tsunami-watch`,
4548
+ TSU: `tsunami-information-statement`,
4542
4549
  TUV: `ultraviolet-index`,
4543
4550
  TVL: `travelers-forecast`,
4544
4551
  TWB: `transcribed-weather-broadcast`,
@@ -4632,6 +4639,43 @@ var validate = (options) => {
4632
4639
  return { isIgnored: true };
4633
4640
  };
4634
4641
 
4642
+ // src/@dictionaries/dictionaries.matches.ts
4643
+ var dict_matches = {
4644
+ SPS: [
4645
+ { match: /STRONG THUNDERSTORM/i, label: "Convective Special Weather Statement", statement: false },
4646
+ { match: /SPECIAL WEATHER STATEMENT/i, label: "Special Weather Statement", statement: false }
4647
+ ],
4648
+ TSU: [
4649
+ { match: /TSUNAMI WARNING/i, label: "Tsunami Warning", statement: false },
4650
+ { match: /TSUNAMI WATCH/i, label: "Tsunami Watch", statement: false },
4651
+ { match: /TSUNAMI ADVISORY/i, label: "Tsunami Advisory", statement: false },
4652
+ { match: /TSUNAMI INFORMATION STATEMENT/i, label: "Tsunami Information Statement", statement: false },
4653
+ { match: /TSUNAMI WARNING CANCELLATION/i, label: "Tsunami Cancellation", statement: false }
4654
+ ],
4655
+ TCP: [
4656
+ { match: /HURRICANE WARNING/i, label: "Hurricane Warning", statement: false },
4657
+ { match: /HURRICANE WATCH/i, label: "Hurricane Watch", statement: false },
4658
+ { match: /TROPICAL STORM WARNING/i, label: "Tropical Storm Warning", statement: false },
4659
+ { match: /TROPICAL STORM WATCH/i, label: "Tropical Storm Watch", statement: false },
4660
+ { match: /STORM SURGE WARNING/i, label: "Storm Surge Warning", statement: false },
4661
+ { match: /STORM SURGE WATCH/i, label: "Storm Surge Watch", statement: false }
4662
+ ],
4663
+ MWW: [
4664
+ { match: /SMALL CRAFT ADVISORY/i, label: "Small Craft Advisory", statement: false },
4665
+ { match: /GALE WARNING/i, label: "Gale Warning", statement: false },
4666
+ { match: /STORM WARNING/i, label: "Storm Warning", statement: false },
4667
+ { match: /HURRICANE FORCE WIND WARNING/i, label: "Hurricane Force Wind Warning", statement: false },
4668
+ { match: /HAZARDOUS SEAS WARNING/i, label: "Hazardous Seas Warning", statement: false },
4669
+ { match: /DENSE FOG ADVISORY/i, label: "Dense Fog Advisory", statement: false },
4670
+ { match: /THUNDERSTORMS/i, label: "Convective Marine Weather Statement", statement: false },
4671
+ { match: /MARINE WEATHER STATEMENT/i, label: "Marine Weather Statement", statement: false }
4672
+ ],
4673
+ PNS: [
4674
+ { match: /NOAA WEATHER WIRE SERVICE/i, label: "NOAA Weather Wire Service Report", statement: true },
4675
+ { match: /Public Information Statement/i, label: "Public Information Statement", statement: true }
4676
+ ]
4677
+ };
4678
+
4635
4679
  // src/@parsers/@text/text.getDescriptionFromProduct.ts
4636
4680
  var getDescriptionFromProduct = (options) => {
4637
4681
  let message = options.message;
@@ -4664,18 +4708,32 @@ var getDescriptionFromProduct = (options) => {
4664
4708
  // src/@parsers/@text/text.getPolygonFromProduct.ts
4665
4709
  var getPolygonFromProduct = (message) => {
4666
4710
  const coordinates = [];
4667
- const match = message.match(/LAT\.{3}LON\s+([\d\s]+)/i);
4668
- if (!match || !match[1]) return coordinates;
4669
- const coordStrings = match[1].replace(/\n/g, " ").trim().split(/\s+/);
4670
- for (let i = 0; i < coordStrings.length - 1; i += 2) {
4671
- const lat = parseFloat(coordStrings[i]) / 100;
4672
- const lon = -parseFloat(coordStrings[i + 1]) / 100;
4673
- if (!isNaN(lat) && !isNaN(lon)) {
4674
- coordinates.push([lon, lat]);
4711
+ const match = message.match(
4712
+ /LAT\.\.\.LON\s+([\s\S]*?)(?=\n[A-Z]{2,}(?:\.\.\.|:)|\$\$|&&|$)/i
4713
+ );
4714
+ if (!match) return coordinates;
4715
+ const text2 = match[1];
4716
+ const values = text2.match(/\d{4,8}/g);
4717
+ if (!values) return coordinates;
4718
+ if (values.every((v) => v.length === 8)) {
4719
+ for (const value of values) {
4720
+ const lat = parseInt(value.slice(0, 4), 10) / 100;
4721
+ const lon = -parseInt(value.slice(4, 8), 10) / 100;
4722
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4723
+ coordinates.push([lon, lat]);
4724
+ }
4725
+ }
4726
+ } else {
4727
+ for (let i = 0; i + 1 < values.length; i += 2) {
4728
+ const lat = parseInt(values[i], 10) / 100;
4729
+ const lon = -parseInt(values[i + 1], 10) / 100;
4730
+ if (Number.isFinite(lat) && Number.isFinite(lon)) {
4731
+ coordinates.push([lon, lat]);
4732
+ }
4675
4733
  }
4676
4734
  }
4677
4735
  if (coordinates.length > 2) {
4678
- coordinates.push(coordinates[0]);
4736
+ coordinates.push([...coordinates[0]]);
4679
4737
  }
4680
4738
  return coordinates;
4681
4739
  };
@@ -5101,25 +5159,6 @@ var getEventHeader = (options) => {
5101
5159
  return `ZCZC-ATMOSX-${options.getType.prefix}-${ugc2}-${(_b = vtec2 == null ? void 0 : vtec2.status) != null ? _b : `Issued`}-${(/* @__PURE__ */ new Date()).toISOString().replace(/[-:]/g, "").split(".")[0]}-${(_c = properties2.geocode.office.office) != null ? _c : `KWNS`}`;
5102
5160
  };
5103
5161
 
5104
- // src/@dictionaries/dictionaries.matches.ts
5105
- var dict_matches = {
5106
- "Special Weather Statement": "Special Weather Statement",
5107
- "Hurricane Warning": "Hurricane Warning",
5108
- "Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
5109
- "Hurricane Watch": "Hurricane Watch",
5110
- "Tropical Storm Warning": "Tropical Storm Warning",
5111
- "Tropical Storm Watch": "Tropical Storm Watch",
5112
- "High Wind Warning": "High Wind Warning",
5113
- "Gale Warning": "Gale Warning",
5114
- "Small Craft Advisory": "Small Craft Advisory",
5115
- "Small Craft Warning": "Small Craft Warning",
5116
- "Tsunami Warning": "Tsunami Warning",
5117
- "Tsunami Watch": "Tsunami Watch",
5118
- "Tsunami Advisory": "Tsunami Advisory",
5119
- "Tsunami Information Statement": "Tsunami Information Statement",
5120
- "Subscribers:": "National Weather Service Policy"
5121
- };
5122
-
5123
5162
  // src/@building/building.tracking.ts
5124
5163
  var getEventTracking = (options) => {
5125
5164
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
@@ -5144,1920 +5183,1967 @@ var getEventTracking = (options) => {
5144
5183
  return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
5145
5184
  }
5146
5185
  const wmoMatch = (_e = (_d = options.organization) == null ? void 0 : _d.wmoidentifier) == null ? void 0 : _e.match(/([A-Z]{4}\d{2})\s+([A-Z]{4})/);
5147
- const station = (_f = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _f : "N/A";
5186
+ const station = (_f = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _f : "---";
5148
5187
  if (options.organization.featureId) {
5149
5188
  const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
5150
- return `${station}.${(_h = (_g = idMatch == null ? void 0 : idMatch[0]) == null ? void 0 : _g.replace(/\./g, "")) != null ? _h : "N/A"}`;
5189
+ return `${station}.${(_h = (_g = idMatch == null ? void 0 : idMatch[0]) == null ? void 0 : _g.replace(/\./g, "")) != null ? _h : "---"}`;
5151
5190
  }
5152
- const id2 = (_i = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _i : "N/A";
5153
- return `${station}.${(_j = id2 == null ? void 0 : id2.replace(/\./g, "")) != null ? _j : "N/A"}`;
5191
+ const id2 = (_i = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _i : "---";
5192
+ return `${station}.${(_j = id2 == null ? void 0 : id2.replace(/\./g, "")) != null ? _j : "---"}`;
5154
5193
  }
5155
5194
  };
5156
5195
 
5157
- // src/@building/building.validate.ts
5158
- var import_crypto = require("crypto");
5196
+ // src/@modules/@utilities/utilities.setDebug.ts
5197
+ var setDebug = (options) => {
5198
+ var _a, _b, _c, _d;
5199
+ const settings = bootstrap.settings;
5200
+ bootstrap.listener.emit(`debug`, {
5201
+ message: options.message,
5202
+ parent: (_b = (_a = options == null ? void 0 : options.title) == null ? void 0 : _a.split(`.`)[0]) == null ? void 0 : _b.replace(`@`, ``),
5203
+ function: (_c = options == null ? void 0 : options.title) == null ? void 0 : _c.split(`.`)[1]
5204
+ });
5205
+ if (settings.EnableDebugging) {
5206
+ console.log(`[${bootstrap.ansi_colors.BLUE}${(_d = options.title) != null ? _d : `debug`}${bootstrap.ansi_colors.RESET}] ${options.message}`);
5207
+ }
5208
+ };
5159
5209
 
5160
- // src/@dictionaries/dictionaries.enhanced.ts
5161
- var dict_enhanced = {
5162
- "Tornado Warning": {
5163
- "Tornado Emergency": {
5164
- description: "tornado emergency"
5165
- },
5166
- "PDS Tornado Warning": {
5167
- description: "particularly dangerous situation",
5168
- damage: `CONSIDERABLE`
5169
- },
5170
- "Radar Confirmed Tornado Warning": {
5171
- description: "source...radar confirmed tornado.",
5172
- tornado: `OBSERVED`
5173
- },
5174
- "Confirmed Tornado Warning": {
5175
- tornado: `OBSERVED`
5176
- },
5177
- "Radar Indicated Tornado Warning": {}
5178
- },
5179
- "Fire Weather Warning": {
5180
- "PDS Fire Weather Warning": {
5181
- description: "particularly dangerous situation"
5182
- }
5183
- },
5184
- "Blizzard Warning": {
5185
- "PDS Blizzard Warning": {
5186
- description: "particularly dangerous situation"
5187
- }
5188
- },
5189
- "Ice Storm Warning": {
5190
- "PDS Ice Storm Warning": {
5191
- description: "particularly dangerous situation"
5192
- }
5193
- },
5194
- "Special Marine Warning": {
5195
- "Special Marine Warning (TPROB)": {
5196
- tornado: `POSSIBLE`
5197
- }
5198
- },
5199
- "Tornado Watch": {
5200
- "PDS Tornado Watch": {
5201
- pdswatch: true
5202
- }
5203
- },
5204
- "Severe Thunderstorm Watch": {
5205
- "PDS Severe Thunderstorm Watch": {
5206
- pdswatch: true
5207
- }
5208
- },
5209
- "Flash Flood Warning": {
5210
- "Flash Flood Emergency": {
5211
- description: "flash flood emergency"
5212
- },
5213
- "Considerable Flash Flood Warning": {
5214
- damage: `CONSIDERABLE`
5215
- }
5216
- },
5217
- "Severe Thunderstorm Warning": {
5218
- "EDS Severe Thunderstorm Warning (TPROB)": {
5219
- description: "extremely dangerous situation",
5220
- tornado: "POSSIBLE"
5221
- },
5222
- "EDS Severe Thunderstorm Warning": {
5223
- description: "extremely dangerous situation"
5224
- },
5225
- "Destructive Severe Thunderstorm Warning (TPROB)": {
5226
- damage: `DESTRUCTIVE`,
5227
- tornado: `POSSIBLE`
5228
- },
5229
- "Destructive Severe Thunderstorm Warning": {
5230
- damage: `DESTRUCTIVE`
5231
- },
5232
- "Considerable Severe Thunderstorm Warning (TPROB)": {
5233
- damage: `CONSIDERABLE`,
5234
- tornado: `POSSIBLE`
5235
- },
5236
- "Considerable Severe Thunderstorm Warning": {
5237
- damage: `CONSIDERABLE`
5238
- },
5239
- "Severe Thunderstorm Warning (TPROB)": {
5240
- tornado: `POSSIBLE`
5210
+ // src/@events/events.text.ts
5211
+ var text = (stanza) => __async(null, null, function* () {
5212
+ var _a, _b, _c, _d, _e;
5213
+ const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
5214
+ if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5215
+ for (const message of getMessages) {
5216
+ const tick = performance.now();
5217
+ const attributes = stanza == null ? void 0 : stanza.attributes;
5218
+ const props = properties({ message, attributes });
5219
+ const header = getEventHeader({ properties: props, getType: stanza.getType });
5220
+ const issued = new Date(attributes.issue);
5221
+ const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
5222
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5223
+ let event = matches == null ? void 0 : matches.label;
5224
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5225
+ if (!event) {
5226
+ event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5227
+ isStatement = true;
5241
5228
  }
5229
+ bootstrap.cache.processed.push({
5230
+ type: `Feature`,
5231
+ geometry: {
5232
+ type: `Point`,
5233
+ coordinates: []
5234
+ },
5235
+ properties: __spreadProps(__spreadValues({
5236
+ event,
5237
+ parent: event,
5238
+ status: isStatement ? `Statement` : `Issued`,
5239
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5240
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
5241
+ }, props), {
5242
+ metadata: {
5243
+ ms: performance.now() - tick,
5244
+ source: `events.text`,
5245
+ tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
5246
+ header,
5247
+ vtec: null,
5248
+ hvtec: null,
5249
+ raw: message,
5250
+ history: [
5251
+ {
5252
+ description: props.description,
5253
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5254
+ status: `Issued`
5255
+ }
5256
+ ]
5257
+ }
5258
+ })
5259
+ });
5260
+ setDebug({ title: `@events.text`, message: `Event process took ${performance.now() - tick} ms` });
5242
5261
  }
5262
+ });
5263
+
5264
+ // src/@parsers/@ugc/ugc.header.ts
5265
+ var getUGCHeader = (message) => {
5266
+ const start = message.search(dict_expressions.ugc1);
5267
+ const sub = message.substring(start);
5268
+ const end = sub.search(dict_expressions.ugc2);
5269
+ const fin = sub.substring(0, end).replace(/\s+/g, "").slice(0, -1);
5270
+ return fin != null ? fin : null;
5243
5271
  };
5244
5272
 
5245
- // src/@building/building.enhance.ts
5246
- var getEventEnhancedName = (event) => {
5247
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5248
- const configurations = bootstrap.settings;
5249
- let name = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.event;
5250
- if (!((_b = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _b.BetterEventNames)) {
5251
- return name;
5252
- }
5253
- const damage = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat;
5254
- const tornado = (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.tornado_threat;
5255
- const pdswatch = (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.watch_parameters) == null ? void 0 : _h.pds_watch;
5256
- const description = (_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.description) == null ? void 0 : _j.toLowerCase();
5257
- for (const [eventKey, eventConfig] of Object.entries(dict_enhanced)) {
5258
- if (eventKey !== name) continue;
5259
- for (const [paramKey, paramValue] of Object.entries(eventConfig)) {
5260
- let matches = true;
5261
- if (paramValue == null ? void 0 : paramValue.description) {
5262
- if (!description.includes(paramValue.description.toLowerCase())) matches = false;
5263
- }
5264
- if (paramValue == null ? void 0 : paramValue.damage) {
5265
- if (paramValue.damage !== damage) matches = false;
5266
- }
5267
- if (paramValue == null ? void 0 : paramValue.tornado) {
5268
- if (paramValue.tornado !== tornado) matches = false;
5269
- }
5270
- if (paramValue == null ? void 0 : paramValue.pdswatch) {
5271
- if (paramValue.pdswatch !== pdswatch) matches = false;
5273
+ // src/@parsers/@ugc/ugc.zones.ts
5274
+ var getZones = (header) => {
5275
+ const splits = header.split("-");
5276
+ const zones = [];
5277
+ let state = splits[0].substring(0, 2);
5278
+ const format = splits[0].substring(2, 3);
5279
+ for (const part of splits) {
5280
+ if (/^[A-Z]/.test(part)) {
5281
+ state = part.substring(0, 2);
5282
+ if (part.includes(">")) {
5283
+ const [start, end] = part.split(">");
5284
+ const startNum = parseInt(start.substring(3), 10);
5285
+ const endNum = parseInt(end, 10);
5286
+ for (let j2 = startNum; j2 <= endNum; j2++) {
5287
+ zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
5288
+ }
5289
+ } else {
5290
+ zones.push(part);
5272
5291
  }
5273
- if (matches) {
5274
- name = paramKey;
5275
- break;
5292
+ continue;
5293
+ }
5294
+ if (part.includes(">")) {
5295
+ const [start, end] = part.split(">");
5296
+ const startNum = parseInt(start, 10);
5297
+ const endNum = parseInt(end, 10);
5298
+ for (let j2 = startNum; j2 <= endNum; j2++) {
5299
+ zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
5276
5300
  }
5301
+ } else {
5302
+ zones.push(`${state}${format}${part}`);
5277
5303
  }
5278
5304
  }
5279
- return name;
5305
+ return zones.filter((item) => item !== "");
5280
5306
  };
5281
5307
 
5282
- // src/@dictionaries/dictionaries.correlations.ts
5283
- var dict_correlations = [
5284
- { type: "Statement", name: "Statement", isCancel: false, isUpdate: false, isIssued: true, isStatement: true },
5285
- { type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5286
- { type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5287
- { type: "Alert", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
5288
- { type: "Updated", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5289
- { type: "Expired", name: "Expired", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5290
- { type: "Issued", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
5291
- { type: "Extended", name: "Extended", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5292
- { type: "Correction", name: "Correction", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5293
- { type: "Upgraded", name: "Upgraded", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5294
- { type: "Cancelled", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5295
- { type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false, isStatement: false }
5296
- ];
5297
-
5298
- // src/@dictionaries/dictionaries.cancellation.ts
5299
- var dict_cancellation = [
5300
- "has been cancelled",
5301
- "subsided sufficiently for the advisory to be cancelled",
5302
- "has been cancelled",
5303
- "no tsunami threat from a nearby earthquake",
5304
- "will be allowed to expire",
5305
- "has diminished",
5306
- "and no longer",
5307
- "has been replaced",
5308
- "The threat has ended",
5309
- "has weakened below severe"
5310
- ];
5311
-
5312
- // src/@dictionaries/dictionaries.testing.ts
5313
- var dict_testing = [
5314
- `This is a test message`,
5315
- `Monitoring message only.`,
5316
- `THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY`,
5317
- "TEST MESSAGE"
5318
- ];
5308
+ // src/@parsers/@ugc/ugc.expiry.ts
5309
+ var getExpiry = (message) => {
5310
+ const match = message.match(/\b(\d{6})-/);
5311
+ if (!match) {
5312
+ return null;
5313
+ }
5314
+ const date = match == null ? void 0 : match[1];
5315
+ const day = parseInt(date == null ? void 0 : date.slice(0, 2), 10);
5316
+ const hour = parseInt(date == null ? void 0 : date.slice(2, 4), 10);
5317
+ const minute = parseInt(date == null ? void 0 : date.slice(4, 6), 10);
5318
+ const now = /* @__PURE__ */ new Date();
5319
+ const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
5320
+ return expires.toISOString();
5321
+ };
5319
5322
 
5320
- // src/@dictionaries/dictionaries.products.ts
5321
- var dict_products = {
5322
- "O": "Operational Product",
5323
- "T": "Test Product",
5324
- "E": "Experimental Product",
5325
- "X": "Experimental Product (Non-Operational)"
5323
+ // src/@parsers/@ugc/ugc.getCache.ts
5324
+ var getCache = (key) => {
5325
+ return bootstrap.cache.ugc.get(key);
5326
5326
  };
5327
5327
 
5328
- // src/@dictionaries/dictionaries.hail.ts
5329
- var dict_hail = {
5330
- ".25": "Pea",
5331
- ".50": "Penny",
5332
- ".75": "Penny",
5333
- "Up to .75": "Penny",
5334
- ".88": "Nickel",
5335
- "0.75": "Penny",
5336
- "0.88": "Nickel",
5337
- "1.00": "Quarter",
5338
- "1.25": "Half Dollar",
5339
- "1.50": "Ping Pong Ball",
5340
- "1.75": "Golf Ball",
5341
- "2.00": "Hen Egg",
5342
- "2.50": "Tennis Ball",
5343
- "2.75": "Baseball",
5344
- "4.00": "CD/DVD"
5328
+ // src/@parsers/@ugc/ugc.setCache.ts
5329
+ var setCache = (key, value) => {
5330
+ if (bootstrap.cache.ugc.size >= 5e3) {
5331
+ const firstKey = bootstrap.cache.ugc.keys().next().value;
5332
+ bootstrap.cache.ugc.delete(firstKey);
5333
+ }
5334
+ bootstrap.cache.ugc.set(key, value);
5345
5335
  };
5346
5336
 
5347
- // src/@building/building.signature.ts
5348
- var getEventSignature = (event) => {
5349
- var _a, _b, _c, _d, _e, _f, _g, _h;
5350
- const properties2 = event == null ? void 0 : event.properties;
5351
- const vtec2 = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.vtec;
5352
- const status = dict_correlations.find((c) => c.type === (properties2 == null ? void 0 : properties2.status));
5353
- const csig = dict_cancellation.find((sig) => properties2.description.toLowerCase().includes(sig.toLowerCase()));
5354
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_issued: true, is_test: false });
5355
- if ((_c = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _c.estimated_hail_size) {
5356
- properties2.parameters.estimated_hail_size += ` (${(_e = dict_hail[(_d = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _d.estimated_hail_size]) != null ? _e : "--"})`;
5357
- }
5358
- if (status) {
5359
- properties2.status = (_f = status.name) != null ? _f : properties2.status;
5360
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement });
5361
- }
5362
- if (csig) {
5363
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
5364
- }
5365
- const getProduct = (_h = (_g = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _g.split(`.`)[0]) == null ? void 0 : _h.replace(`/`, ``);
5366
- const isTestProduct = dict_products[getProduct] == `Test Product`;
5367
- if (isTestProduct || dict_testing.some((sig) => {
5368
- var _a2, _b2, _c2, _d2;
5369
- return (_d2 = (_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase())) != null ? _d2 : (_c2 = (_b2 = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _b2.instructions) == null ? void 0 : _c2.toLowerCase().includes(sig.toLowerCase());
5370
- })) {
5371
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_test: true });
5337
+ // src/@parsers/@ugc/ugc.locations.ts
5338
+ var getLocations = (zones) => __async(null, null, function* () {
5339
+ const uniqueZones = Array.from(new Set(zones));
5340
+ const results = [];
5341
+ const missing = [];
5342
+ for (let i = 0; i < uniqueZones.length; i++) {
5343
+ const zone = uniqueZones[i];
5344
+ const cached = getCache(zone);
5345
+ if (cached) {
5346
+ for (let j2 = 0; j2 < cached.length; j2++) {
5347
+ results.push(cached[j2]);
5348
+ }
5349
+ } else {
5350
+ missing.push(zone);
5351
+ }
5372
5352
  }
5373
- if (new Date(properties2.expires).getTime() < Date.now()) {
5374
- properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
5353
+ if (missing.length > 0) {
5354
+ const rows = yield bootstrap.database.prepare(
5355
+ `SELECT id, location FROM shapefiles WHERE id IN (${missing.map(() => "?").join(",")})`
5356
+ ).all(...missing);
5357
+ for (let i = 0; i < rows.length; i++) {
5358
+ const r = rows[i];
5359
+ setCache(r.id, [r.location]);
5360
+ results.push(r.location);
5361
+ }
5375
5362
  }
5376
- properties2.status_metadata = __spreadValues({}, properties2.status_metadata);
5377
- return event;
5378
- };
5363
+ return results;
5364
+ });
5379
5365
 
5380
- // src/@manager/manager.setHash.ts
5381
- var setHash = (event, entry) => {
5382
- if (entry) {
5383
- entry.hashes.push(event.properties.metadata.hash);
5384
- entry.expires = event.properties.expires;
5385
- } else {
5386
- bootstrap.cache.hashes.push({
5387
- tracking: event.properties.metadata.tracking,
5388
- hashes: [event.properties.metadata.hash],
5389
- expires: event.properties.expires
5390
- });
5391
- }
5392
- };
5366
+ // src/@parsers/@ugc/ugc.extract.ts
5367
+ var ugcExtract = (message) => __async(null, null, function* () {
5368
+ const head = getUGCHeader(message);
5369
+ const ugcs = getZones(head);
5370
+ const expires = getExpiry(message);
5371
+ const areas = yield getLocations(ugcs);
5372
+ if (!head || (ugcs == null ? void 0 : ugcs.length) == 0) return;
5373
+ return {
5374
+ zones: ugcs,
5375
+ locations: areas,
5376
+ expires
5377
+ };
5378
+ });
5393
5379
 
5394
- // src/@modules/@eas/eas.getWavPCM16.ts
5395
- var getWavPCM16 = (buffer) => {
5396
- if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
5397
- return null;
5398
- }
5399
- let fmt = null;
5400
- let data = null;
5401
- let i = 12;
5402
- while (i + 8 <= buffer.length) {
5403
- const id2 = buffer.toString("ascii", i, i + 4);
5404
- const size = buffer.readUInt32LE(i + 4);
5405
- const start = i + 8;
5406
- const end = start + size;
5407
- if (id2 === "fmt ") fmt = buffer.slice(start, end);
5408
- if (id2 === "data") data = buffer.slice(start, end);
5409
- i = end + size % 2;
5410
- }
5411
- if (!fmt || !data) return null;
5412
- const audioFormat = fmt.readUInt16LE(0);
5413
- const channels = fmt.readUInt16LE(2);
5414
- const sampleRate = fmt.readUInt32LE(4);
5415
- const bitsPerSample = fmt.readUInt16LE(14);
5416
- if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
5417
- return null;
5380
+ // src/@events/events.ugc.ts
5381
+ var ugc = (stanza) => __async(null, null, function* () {
5382
+ var _a, _b, _c, _d, _e;
5383
+ const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
5384
+ if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5385
+ for (const message of getMessages) {
5386
+ const tick = performance.now();
5387
+ const attributes = stanza == null ? void 0 : stanza.attributes;
5388
+ const ugc2 = yield ugcExtract(message);
5389
+ if (ugc2 != null) {
5390
+ const props = properties({ message, attributes, ugc: ugc2 });
5391
+ const issued = new Date(attributes.issue);
5392
+ const expires = new Date(ugc2.expires);
5393
+ const header = getEventHeader({ properties: props, getType: stanza.getType });
5394
+ const matches = (_d = dict_matches[stanza.getType.prefix]) == null ? void 0 : _d.find((match) => match.match.test(message.toUpperCase()));
5395
+ let event = matches == null ? void 0 : matches.label;
5396
+ let isStatement = (_e = matches == null ? void 0 : matches.statement) != null ? _e : false;
5397
+ if (!event) {
5398
+ event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
5399
+ isStatement = true;
5400
+ }
5401
+ bootstrap.cache.processed.push({
5402
+ type: `Feature`,
5403
+ geometry: {
5404
+ type: `Point`,
5405
+ coordinates: []
5406
+ },
5407
+ properties: __spreadProps(__spreadValues({
5408
+ event,
5409
+ parent: event,
5410
+ status: isStatement ? `Statement` : `Issued`,
5411
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5412
+ expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
5413
+ }, props), {
5414
+ metadata: {
5415
+ ms: performance.now() - tick,
5416
+ source: `events.ugc`,
5417
+ tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
5418
+ header,
5419
+ vtec: null,
5420
+ hvtec: null,
5421
+ raw: message,
5422
+ history: [
5423
+ {
5424
+ description: props.description,
5425
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5426
+ status: `Issued`
5427
+ }
5428
+ ]
5429
+ }
5430
+ })
5431
+ });
5432
+ setDebug({ title: `@events.ugc`, message: `Event process took ${performance.now() - tick} ms` });
5433
+ }
5418
5434
  }
5419
- const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
5420
- return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
5435
+ });
5436
+
5437
+ // src/@dictionaries/dictionaries.products.ts
5438
+ var dict_products = {
5439
+ "O": "Operational Product",
5440
+ "T": "Test Product",
5441
+ "E": "Experimental Product",
5442
+ "X": "Experimental Product (Non-Operational)"
5421
5443
  };
5422
5444
 
5423
- // src/@modules/@eas/eas.getSampledPCM16.ts
5424
- var getSampledPCM16 = (int16, originalRate, targetRate) => {
5425
- if (originalRate === targetRate) return int16;
5426
- const ratio = targetRate / originalRate;
5427
- const outLen = Math.max(1, Math.round(int16.length * ratio));
5428
- const out = new Int16Array(outLen);
5429
- for (let i = 0; i < outLen; i++) {
5430
- const pos = i / ratio;
5431
- const i0 = Math.floor(pos);
5432
- const i1 = Math.min(i0 + 1, int16.length - 1);
5433
- const frac = pos - i0;
5434
- const v = int16[i0] * (1 - frac) + int16[i1] * frac;
5435
- out[i] = Math.round(v);
5436
- }
5437
- return out;
5445
+ // src/@dictionaries/dictionaries.events.ts
5446
+ var dict_events = {
5447
+ "AF": "Ashfall",
5448
+ "AS": "Air Stagnation",
5449
+ "BH": "Beach Hazard",
5450
+ "BW": "Brisk Wind",
5451
+ "BZ": "Blizzard",
5452
+ "CF": "Coastal Flood",
5453
+ "DF": "Debris Flow",
5454
+ "DS": "Dust Storm",
5455
+ "EC": "Extreme Cold",
5456
+ "EH": "Excessive Heat",
5457
+ "XH": "Extreme Heat",
5458
+ "EW": "Extreme Wind",
5459
+ "FA": "Areal Flood",
5460
+ "FF": "Flash Flood",
5461
+ "FG": "Dense Fog",
5462
+ "FL": "Flood",
5463
+ "FR": "Frost",
5464
+ "FW": "Fire Weather",
5465
+ "FZ": "Freeze",
5466
+ "GL": "Gale",
5467
+ "HF": "Hurricane Force Wind",
5468
+ "HT": "Heat",
5469
+ "HU": "Hurricane",
5470
+ "HW": "High Wind",
5471
+ "HY": "Hydrologic",
5472
+ "HZ": "Hard Freeze",
5473
+ "IS": "Ice Storm",
5474
+ "LE": "Lake Effect Snow",
5475
+ "LO": "Low Water",
5476
+ "LS": "Lakeshore Flood",
5477
+ "LW": "Lake Wind",
5478
+ "MA": "Special Marine",
5479
+ "EQ": "Earthquake",
5480
+ "MF": "Dense Fog",
5481
+ "MH": "Ashfall",
5482
+ "MS": "Dense Smoke",
5483
+ "RB": "Small Craft for Rough Bar",
5484
+ "RP": "Rip Current Risk",
5485
+ "SC": "Small Craft",
5486
+ "SE": "Hazardous Seas",
5487
+ "SI": "Small Craft for Winds",
5488
+ "SM": "Dense Smoke",
5489
+ "SQ": "Snow Squall",
5490
+ "SR": "Storm",
5491
+ "SS": "Storm Surge",
5492
+ "SU": "High Surf",
5493
+ "SV": "Severe Thunderstorm",
5494
+ "SW": "Small Craft for Hazardous Seas",
5495
+ "TO": "Tornado",
5496
+ "TR": "Tropical Storm",
5497
+ "TS": "Tsunami",
5498
+ "TY": "Typhoon",
5499
+ "SP": "Special Weather",
5500
+ "UP": "Heavy Freezing Spray",
5501
+ "WC": "Wind Chill",
5502
+ "WI": "Wind",
5503
+ "WS": "Winter Storm",
5504
+ "WW": "Winter Weather",
5505
+ "ZF": "Freezing Fog",
5506
+ "ZR": "Freezing Rain",
5507
+ "ZY": "Freezing Spray"
5438
5508
  };
5439
5509
 
5440
- // src/@modules/@eas/eas.getPCMToFloat.ts
5441
- var getPCMToFloat = (int16) => {
5442
- const out = new Float32Array(int16.length);
5443
- for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
5444
- return out;
5510
+ // src/@dictionaries/dictionaries.actions.ts
5511
+ var dict_actions = {
5512
+ "W": "Warning",
5513
+ "F": "Forecast",
5514
+ "A": "Watch",
5515
+ "O": "Outlook",
5516
+ "Y": "Advisory",
5517
+ "N": "Synopsis",
5518
+ "S": "Statement"
5445
5519
  };
5446
5520
 
5447
- // src/@modules/@eas/eas.getFloatPCM16.ts
5448
- var getFloatPCM16 = (float32) => {
5449
- const out = new Int16Array(float32.length);
5450
- for (let i = 0; i < float32.length; i++) {
5451
- let v = Math.max(-1, Math.min(1, float32[i]));
5452
- out[i] = Math.round(v * 32767);
5453
- }
5454
- return out;
5521
+ // src/@dictionaries/dictionaries.status.ts
5522
+ var dict_status = {
5523
+ "NEW": "Issued",
5524
+ "CON": "Updated",
5525
+ "EXT": "Extended",
5526
+ "EXA": "Extended",
5527
+ "EXB": "Extended",
5528
+ "UPG": "Upgraded",
5529
+ "COR": "Correction",
5530
+ "ROU": "Routine",
5531
+ "CAN": "Cancelled",
5532
+ "EXP": "Expired"
5455
5533
  };
5456
5534
 
5457
- // src/@modules/@eas/eas.setRadioEffect.ts
5458
- var setRadioEffect = (int16, sampleRate) => {
5459
- const hpCut = 3555;
5460
- const lpCut = 1600;
5461
- const x = getPCMToFloat(int16);
5462
- const dt = 1 / sampleRate;
5463
- const rcHP = 1 / (2 * Math.PI * hpCut);
5464
- const aHP = rcHP / (rcHP + dt);
5465
- let yHP = 0, xPrev = 0;
5466
- for (let i = 0; i < x.length; i++) {
5467
- const xi = x[i];
5468
- yHP = aHP * (yHP + xi - xPrev);
5469
- xPrev = xi;
5470
- x[i] = yHP;
5471
- }
5472
- const rcLP = 1 / (2 * Math.PI * lpCut);
5473
- const aLP = dt / (rcLP + dt);
5474
- let yLP = 0;
5475
- for (let i = 0; i < x.length; i++) {
5476
- yLP = yLP + aLP * (x[i] - yLP);
5477
- x[i] = yLP;
5478
- }
5479
- const compGain = 2;
5480
- const norm = Math.tanh(compGain);
5481
- for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
5482
- return getFloatPCM16(x);
5535
+ // src/@parsers/@pvtec/pvtec.expires.ts
5536
+ var getExpiry2 = (dates) => {
5537
+ if ((dates == null ? void 0 : dates[1]) == `000000T0000Z`) return "Invalid Date Format";
5538
+ const expires = `${(/* @__PURE__ */ new Date()).getFullYear().toString().substring(0, 2)}${dates[1].substring(0, 2)}-${dates[1].substring(2, 4)}-${dates[1].substring(4, 6)}T${dates[1].substring(7, 9)}:${dates[1].substring(9, 11)}:00`;
5539
+ const local = new Date(new Date(expires).getTime() - 4 * 60 * 6e4);
5540
+ const pad = (n) => n.toString().padStart(2, "0");
5541
+ return `${local.getFullYear()}-${pad(local.getMonth() + 1)}-${pad(local.getDate())}T${pad(local.getHours())}:${pad(local.getMinutes())}:00.000-04:00`;
5483
5542
  };
5484
5543
 
5485
- // src/@modules/@eas/eas.setAFSK.ts
5486
- var setAFSK = (bits, sampleRate) => {
5487
- const baud = 520.83;
5488
- const markFreq = 2083.3;
5489
- const spaceFreq = 1562.5;
5490
- const amplitude = 0.6;
5491
- const twoPi = Math.PI * 2;
5492
- const result = [];
5493
- let phase = 0;
5494
- let frac = 0;
5495
- for (let b = 0; b < bits.length; b++) {
5496
- const bit = bits[b];
5497
- const freq = bit ? markFreq : spaceFreq;
5498
- const samplesPerBit = sampleRate / baud + frac;
5499
- const n = Math.round(samplesPerBit);
5500
- frac = samplesPerBit - n;
5501
- const inc = twoPi * freq / sampleRate;
5502
- for (let i = 0; i < n; i++) {
5503
- result.push(Math.round(Math.sin(phase) * amplitude * 32767));
5504
- phase += inc;
5505
- if (phase > twoPi) phase -= twoPi;
5506
- }
5507
- }
5508
- const fadeSamples = Math.floor(sampleRate * 2e-3);
5509
- for (let i = 0; i < fadeSamples; i++) {
5510
- const gain = i / fadeSamples;
5511
- result[i] = Math.round(result[i] * gain);
5512
- result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
5544
+ // src/@parsers/@pvtec/pvtec.extract.ts
5545
+ var pvExtract = (message) => {
5546
+ var _a, _b, _c, _d;
5547
+ if (!message) return null;
5548
+ const getVTECs = (_a = message.match(dict_expressions.pvtec)) != null ? _a : [];
5549
+ const vtecs = [];
5550
+ for (const vtec2 of getVTECs) {
5551
+ const sub = vtec2.split(`.`);
5552
+ if ((sub == null ? void 0 : sub.length) < 7) continue;
5553
+ const dates = (_b = sub[6]) == null ? void 0 : _b.split(`-`);
5554
+ vtecs.push({
5555
+ vtec: vtec2,
5556
+ product: dict_products[sub[0]],
5557
+ tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
5558
+ event: `${dict_events[sub[3]]} ${dict_actions[sub[4]]}`,
5559
+ status: dict_status[sub[1]],
5560
+ organization: (_d = (_c = message.match(dict_expressions.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
5561
+ expires: getExpiry2(dates),
5562
+ is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
5563
+ prediction_center: sub[2] == `KWNS` ? true : false
5564
+ });
5513
5565
  }
5514
- return Int16Array.from(result);
5566
+ return vtecs.length > 0 ? vtecs : null;
5515
5567
  };
5516
5568
 
5517
- // src/@modules/@eas/eas.setAsciiToBits.ts
5518
- var setAsciiToBits = (str) => {
5519
- const bits = [];
5520
- for (let i = 0; i < str.length; i++) {
5521
- const c = str.charCodeAt(i) & 255;
5522
- bits.push(0);
5523
- for (let b = 0; b < 8; b++) bits.push(c >> b & 1);
5524
- bits.push(1, 1);
5525
- }
5526
- return bits;
5569
+ // src/@dictionaries/dictionaries.causes.ts
5570
+ var dict_causes = {
5571
+ "SM": "Snow Melt",
5572
+ "RS": "Rain/Snow Melt",
5573
+ "ER": "Excessive Rain",
5574
+ "DM": "Dam/Levee Failure",
5575
+ "IJ": "Ice Jam",
5576
+ "GO": "Glacier Lake Outburst",
5577
+ "IC": "Ice",
5578
+ "FS": "Flash Flood / Storm Surge",
5579
+ "FT": "Tidal Effects",
5580
+ "ET": "Elevated Upstream Flow",
5581
+ "MC": "Other Multiple Causes",
5582
+ "WT": "Wind and/or Tidal Effects",
5583
+ "DR": "Reservoir Release",
5584
+ "UU": "Unknown",
5585
+ "OT": "Other Effects"
5527
5586
  };
5528
5587
 
5529
- // src/@modules/@eas/eas.getMergedPCM16.ts
5530
- var getMergedPCM16 = (arrays) => {
5531
- let total = 0;
5532
- for (const a of arrays) total += a.length;
5533
- const out = new Int16Array(total);
5534
- let o = 0;
5535
- for (const a of arrays) {
5536
- out.set(a, o);
5537
- o += a.length;
5538
- }
5539
- return out;
5588
+ // src/@dictionaries/dictionaries.records.ts
5589
+ var dict_records = {
5590
+ "NO": "No Record Expected",
5591
+ "NR": "Near Record or possible record",
5592
+ "UU": "Unknown history of records",
5593
+ "OO": "Other"
5540
5594
  };
5541
5595
 
5542
- // src/@modules/@eas/eas.setSameHeader.ts
5543
- var setSameHeader = (vtec2, repeats, sampleRate = 8e3, options = {}) => {
5544
- var _a, _b;
5545
- const preMarkSec = (_a = options.preMarkSec) != null ? _a : 0.3;
5546
- const gapSec = (_b = options.gapSec) != null ? _b : 0.1;
5547
- const bursts = [];
5548
- const gap = new Int16Array(Math.floor(gapSec * sampleRate));
5549
- for (let i = 0; i < repeats; i++) {
5550
- const bodyBits = setAsciiToBits(vtec2);
5551
- const body = setAFSK(bodyBits, sampleRate);
5552
- const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
5553
- const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
5554
- for (let j2 = 0; j2 < extendedBodyDuration; j2++) {
5555
- extendedBody[j2] = Math.round(body[j2 % body.length] * 0.2);
5556
- }
5557
- extendedBody.set(gap, extendedBodyDuration);
5558
- bursts.push(extendedBody);
5559
- if (i !== repeats - 1) bursts.push(gap);
5560
- }
5561
- return getMergedPCM16(bursts);
5596
+ // src/@dictionaries/dictionaries.severity.ts
5597
+ var dict_severity = {
5598
+ N: "Not Expected",
5599
+ 0: "Areal Flood or FF Product",
5600
+ 1: "Minor",
5601
+ 2: "Moderate",
5602
+ 3: "Major",
5603
+ U: "Unknown"
5562
5604
  };
5563
5605
 
5564
- // src/@modules/@eas/eas.setAttentionTone.ts
5565
- var setAttentionTone = (ms, sampleRate) => {
5566
- const len = Math.floor(ms * sampleRate);
5567
- const out = new Int16Array(len);
5568
- const f1 = 853;
5569
- const f2 = 960;
5570
- const twoPi = Math.PI * 2;
5571
- const amp = 0.1;
5572
- const fadeLen = Math.floor(sampleRate * 0);
5573
- for (let i = 0; i < len; i++) {
5574
- const t = i / sampleRate;
5575
- const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
5576
- let gain = 1;
5577
- if (i < fadeLen) gain = i / fadeLen;
5578
- else if (i > len - fadeLen) gain = (len - i) / fadeLen;
5579
- const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
5580
- out[i] = Math.round(v * 32767);
5606
+ // src/@parsers/@hvtec/hvtec.extract.ts
5607
+ var hvExtract = (message) => {
5608
+ var _a;
5609
+ const getHVTECs = (_a = message.match(dict_expressions.hvtec)) != null ? _a : [];
5610
+ const vtecs = [];
5611
+ for (const vtec2 of getHVTECs) {
5612
+ const sub = vtec2.split(`.`);
5613
+ if (sub.length < 7) continue;
5614
+ vtecs.push({
5615
+ hvtec: vtec2,
5616
+ severity: dict_severity[sub[1]],
5617
+ cause: dict_causes[sub[2]],
5618
+ record: dict_records[sub[6]]
5619
+ });
5581
5620
  }
5582
- return out;
5621
+ return vtecs.length > 0 ? vtecs : null;
5583
5622
  };
5584
5623
 
5585
- // src/@modules/@eas/eas.setNoise.ts
5586
- var setNoise = (int16, noiseLevel = 0.02) => {
5587
- const x = getPCMToFloat(int16);
5588
- for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
5589
- let peak = 0;
5590
- for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
5591
- if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
5592
- return getFloatPCM16(x);
5593
- };
5624
+ // src/@events/events.vtec.ts
5625
+ var vtec = (stanza) => __async(null, null, function* () {
5626
+ var _a, _b, _c, _d, _e;
5627
+ const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
5628
+ if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
5629
+ for (const message of getMessages) {
5630
+ const tick = performance.now();
5631
+ const attributes = stanza == null ? void 0 : stanza.attributes;
5632
+ const pVtec = pvExtract(message);
5633
+ const hVtec = hvExtract(message);
5634
+ const ugc2 = yield ugcExtract(message);
5635
+ if (pVtec != null && ugc2 != null) {
5636
+ for (const pv of pVtec) {
5637
+ const vtec2 = pv;
5638
+ const props = properties({ message, attributes, ugc: ugc2, pVtec: vtec2 });
5639
+ const header = getEventHeader({ properties: props, getType: stanza.getType, vtec: vtec2 });
5640
+ const issued = (_d = new Date(attributes.issue)) != null ? _d : /* @__PURE__ */ new Date();
5641
+ const expires = new Date(vtec2.expires);
5642
+ bootstrap.cache.processed.push({
5643
+ type: `Feature`,
5644
+ geometry: {
5645
+ type: `Point`,
5646
+ coordinates: []
5647
+ },
5648
+ properties: __spreadProps(__spreadValues({
5649
+ event: pv.event,
5650
+ parent: pv.event,
5651
+ status: pv.status,
5652
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5653
+ expires: !isNaN(expires.getTime()) ? expires.toISOString() : (_e = ugc2.expires) != null ? _e : new Date(issued.getTime() + 60 * 60 * 1e3).toISOString()
5654
+ }, props), {
5655
+ metadata: {
5656
+ ms: performance.now() - tick,
5657
+ source: `events.vtec`,
5658
+ tracking: getEventTracking({ type: `VTEC`, stanza, attributes, properties: props, vtec: vtec2 }),
5659
+ header,
5660
+ vtec: pv,
5661
+ hvtec: hVtec,
5662
+ raw: message,
5663
+ history: [
5664
+ {
5665
+ description: props.description,
5666
+ issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
5667
+ status: pv.status
5668
+ }
5669
+ ]
5670
+ }
5671
+ })
5672
+ });
5673
+ setDebug({ title: `@events.vtec`, message: `Event process took ${performance.now() - tick} ms` });
5674
+ }
5675
+ }
5676
+ }
5677
+ });
5594
5678
 
5595
- // src/@modules/@eas/eas.getPCM16.ts
5596
- var getPCM16 = (samples, sampleRate) => {
5597
- let o = 0;
5598
- const bytesPerSample = 2;
5599
- const blockAlign = 1 * bytesPerSample;
5600
- const byteRate = sampleRate * blockAlign;
5601
- const subchunk2Size = samples.length * bytesPerSample;
5602
- const chunkSize = 36 + subchunk2Size;
5603
- const buffer = Buffer.alloc(44 + subchunk2Size);
5604
- buffer.write("RIFF", o);
5605
- o += 4;
5606
- buffer.writeUInt32LE(chunkSize, o);
5607
- o += 4;
5608
- buffer.write("WAVE", o);
5609
- o += 4;
5610
- buffer.write("fmt ", o);
5611
- o += 4;
5612
- buffer.writeUInt32LE(16, o);
5613
- o += 4;
5614
- buffer.writeUInt16LE(1, o);
5615
- o += 2;
5616
- buffer.writeUInt16LE(1, o);
5617
- o += 2;
5618
- buffer.writeUInt32LE(sampleRate, o);
5619
- o += 4;
5620
- buffer.writeUInt32LE(byteRate, o);
5621
- o += 4;
5622
- buffer.writeUInt16LE(blockAlign, o);
5623
- o += 2;
5624
- buffer.writeUInt16LE(16, o);
5625
- o += 2;
5626
- buffer.write("data", o);
5627
- o += 4;
5628
- buffer.writeUInt32LE(subchunk2Size, o);
5629
- o += 4;
5630
- for (let i = 0; i < samples.length; i++, o += 2) {
5631
- buffer.writeInt16LE(samples[i].value, o);
5632
- }
5633
- return buffer;
5634
- };
5635
-
5636
- // src/@modules/@eas/eas.getTTS.ts
5637
- var import_os = require("os");
5638
- var import_fs = require("fs");
5639
- var import_child_process = require("child_process");
5640
- var getTTS = (text2, outputPath) => __async(null, null, function* () {
5641
- const vPlatform = (0, import_os.platform)();
5642
- switch (vPlatform) {
5643
- case "win32": {
5644
- try {
5645
- const txtPath = outputPath + ".txt";
5646
- (0, import_fs.writeFileSync)(txtPath, text2, "utf8");
5647
- const command = [
5648
- "Add-Type -AssemblyName System.Speech;",
5649
- `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
5650
- `$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
5651
- `$speak.SetOutputToWaveFile('${outputPath}');`,
5652
- `$speak.Speak($text);`,
5653
- `$speak.Dispose();`
5654
- ].join(" ");
5655
- (0, import_child_process.execSync)(`powershell -Command "${command}"`, { stdio: "inherit" });
5656
- } catch (error) {
5657
- console.error("Error occurred while generating TTS:", error);
5658
- }
5659
- break;
5660
- }
5661
- case "linux":
5662
- try {
5663
- (0, import_child_process.execSync)(`espeak -w "${outputPath}" "${text2.replace(/"/g, '\\"')}"`);
5664
- } catch (e) {
5679
+ // src/@events/events.api.ts
5680
+ var api = (stanza) => __async(null, null, function* () {
5681
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub;
5682
+ const messages = Object.values(JSON.parse(stanza.message).features);
5683
+ for (const feature of messages) {
5684
+ const tick = performance.now();
5685
+ const pVtec = (_d = pvExtract((_c = (_b = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.parameters) == null ? void 0 : _b.VTEC) == null ? void 0 : _c[0])) != null ? _d : null;
5686
+ bootstrap.cache.processed.push({
5687
+ type: `Feature`,
5688
+ geometry: {
5689
+ type: `Point`,
5690
+ coordinates: []
5691
+ },
5692
+ properties: {
5693
+ event: (_f = (_e = feature == null ? void 0 : feature.properties) == null ? void 0 : _e.event) != null ? _f : null,
5694
+ parent: (_h = (_g = feature == null ? void 0 : feature.properties) == null ? void 0 : _g.event) != null ? _h : null,
5695
+ status: (_j = (_i = feature == null ? void 0 : feature.properties) == null ? void 0 : _i.messageType) != null ? _j : null,
5696
+ issued: ((_k = feature == null ? void 0 : feature.properties) == null ? void 0 : _k.sent) ? new Date((_l = feature == null ? void 0 : feature.properties) == null ? void 0 : _l.sent).toISOString() : null,
5697
+ expires: ((_m = feature == null ? void 0 : feature.properties) == null ? void 0 : _m.expires) ? new Date((_n = feature == null ? void 0 : feature.properties) == null ? void 0 : _n.expires).toISOString() : null,
5698
+ locations: (_p = (_o = feature == null ? void 0 : feature.properties) == null ? void 0 : _o.areaDesc) != null ? _p : null,
5699
+ locations_array: ((_q = feature == null ? void 0 : feature.properties) == null ? void 0 : _q.areaDesc) ? (_r = feature == null ? void 0 : feature.properties) == null ? void 0 : _r.areaDesc.split(";") : [],
5700
+ description: (_t = (_s = feature == null ? void 0 : feature.properties) == null ? void 0 : _s.description) != null ? _t : null,
5701
+ attributes: (_v = (_u = feature == null ? void 0 : feature.properties) == null ? void 0 : _u.attributes) != null ? _v : {},
5702
+ geocode: {
5703
+ office: {
5704
+ office: pVtec ? (_w = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _w.tracking.split(`.`)[0] : null,
5705
+ name: (_y = dict_icao[pVtec ? (_x = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _x.tracking.split(`.`)[0] : null]) != null ? _y : null
5706
+ },
5707
+ organization: (_B = (_A = (_z = feature == null ? void 0 : feature.properties) == null ? void 0 : _z.parameters) == null ? void 0 : _A.WMOidentifier) == null ? void 0 : _B[0],
5708
+ ugc: (_E = (_D = (_C = feature == null ? void 0 : feature.properties) == null ? void 0 : _C.geocode) == null ? void 0 : _D.UGC) != null ? _E : [],
5709
+ polygon: ((_F = feature == null ? void 0 : feature.geometry) == null ? void 0 : _F.coordinates.length) > 0 ? Buffer.from(JSON.stringify([(_G = feature == null ? void 0 : feature.geometry) == null ? void 0 : _G.coordinates[0]])).toString("base64") : null,
5710
+ polygon_generated: ((_H = feature == null ? void 0 : feature.geometry) == null ? void 0 : _H.coordinates.length) > 0 ? true : false
5711
+ },
5712
+ parameters: {
5713
+ tags: getEventTags((_I = feature == null ? void 0 : feature.properties) == null ? void 0 : _I.description),
5714
+ instructions: (_K = (_J = feature == null ? void 0 : feature.properties) == null ? void 0 : _J.instruction) != null ? _K : null,
5715
+ source: (_M = getTextFromProduct({ message: (_L = feature == null ? void 0 : feature.properties) == null ? void 0 : _L.description, find: [`SOURCE...`], removal: [`.`] })) != null ? _M : null,
5716
+ hazards: (_O = getTextFromProduct({ message: (_N = feature == null ? void 0 : feature.properties) == null ? void 0 : _N.description, find: [`HAZARD...`], removal: [`.`] })) != null ? _O : null,
5717
+ impacts: (_Q = getTextFromProduct({ message: (_P = feature == null ? void 0 : feature.properties) == null ? void 0 : _P.description, find: [`IMPACT...`], removal: [`.`] })) != null ? _Q : null,
5718
+ estimated_hail_size: (_U = (_T = (_S = (_R = feature == null ? void 0 : feature.properties) == null ? void 0 : _R.parameters) == null ? void 0 : _S.maxHailSize) == null ? void 0 : _T[0]) != null ? _U : null,
5719
+ estimated_wind_gusts: (_Y = (_X = (_W = (_V = feature == null ? void 0 : feature.properties) == null ? void 0 : _V.parameters) == null ? void 0 : _W.maxWindGust) == null ? void 0 : _X[0]) != null ? _Y : null,
5720
+ damage_threat: (_aa = (_$ = (__ = (_Z = feature == null ? void 0 : feature.properties) == null ? void 0 : _Z.parameters) == null ? void 0 : __.thunderstormDamageThreat) == null ? void 0 : _$[0]) != null ? _aa : null,
5721
+ tornado_threat: (_ea = (_da = (_ca = (_ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _ba.parameters) == null ? void 0 : _ca.tornadoDetection) == null ? void 0 : _da[0]) != null ? _ea : null,
5722
+ flood_threat: (_ia = (_ha = (_ga = (_fa = feature == null ? void 0 : feature.properties) == null ? void 0 : _fa.parameters) == null ? void 0 : _ga.floodDetection) == null ? void 0 : _ha[0]) != null ? _ia : null,
5723
+ wind_threat: (_ma = (_la = (_ka = (_ja = feature == null ? void 0 : feature.properties) == null ? void 0 : _ja.parameters) == null ? void 0 : _ka.windThreat) == null ? void 0 : _la[0]) != null ? _ma : null,
5724
+ hail_threat: (_qa = (_pa = (_oa = (_na = feature == null ? void 0 : feature.properties) == null ? void 0 : _na.parameters) == null ? void 0 : _oa.hailThreat) == null ? void 0 : _pa[0]) != null ? _qa : null
5725
+ },
5726
+ discussion_parameters: {
5727
+ discussion_number: (_ua = (_ta = (_sa = getTextFromProduct({ message: (_ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _ra.description, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _sa.toString()) == null ? void 0 : _ta.padStart(4, "0")) != null ? _ua : null,
5728
+ discussion_concerning: (_wa = getTextFromProduct({ message: (_va = feature == null ? void 0 : feature.properties) == null ? void 0 : _va.description, find: [`Concerning...`] })) != null ? _wa : null,
5729
+ discussion_max_tornado: (_ya = getTextFromProduct({ message: (_xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _xa.description, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _ya : null,
5730
+ discussion_max_hail: (_Aa = getTextFromProduct({ message: (_za = feature == null ? void 0 : feature.properties) == null ? void 0 : _za.description, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _Aa : null,
5731
+ discussion_max_wind: (_Ca = getTextFromProduct({ message: (_Ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ba.description, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _Ca : null,
5732
+ discussion_watch_issuance: (_Ea = getTextFromProduct({ message: (_Da = feature == null ? void 0 : feature.properties) == null ? void 0 : _Da.description, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _Ea : null
5733
+ },
5734
+ watch_parameters: {
5735
+ watch_number: ((_Fa = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Fa.is_watch) && ((_Qa = (_Pa = (_Ka = (_Ja = (_Ia = (_Ha = getTextFromProduct({ message: (_Ga = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ga.description, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _Ha.replace(/(WT|WS|)/g, "")) == null ? void 0 : _Ia.trim()) == null ? void 0 : _Ja.toString()) == null ? void 0 : _Ka.padStart(4, "0")) != null ? _Pa : (_Oa = (_Na = (_Ma = (_La = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _La.tracking) == null ? void 0 : _Ma.slice(-4)) == null ? void 0 : _Na.toString()) == null ? void 0 : _Oa.padStart(4, "0")) != null ? _Qa : null),
5736
+ watch_type: ((_Ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ra.description.includes(`TORNADO WATCH`)) ? `Tornado` : ((_Sa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Sa.description.includes(`SEVERE`)) ? `Severe` : null,
5737
+ additional_tornadoes_probability: (_Ua = getTextFromProduct({ message: (_Ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ta.description, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ua : null,
5738
+ strong_tornadoes_probability: (_Wa = getTextFromProduct({ message: (_Va = feature == null ? void 0 : feature.properties) == null ? void 0 : _Va.description, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Wa : null,
5739
+ severe_wind_probability: (_Ya = getTextFromProduct({ message: (_Xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Xa.description, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ya : null,
5740
+ severe_hail_probability: (__a = getTextFromProduct({ message: (_Za = feature == null ? void 0 : feature.properties) == null ? void 0 : _Za.description, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? __a : null,
5741
+ hail_2in_probability: (_ab = getTextFromProduct({ message: (_$a = feature == null ? void 0 : feature.properties) == null ? void 0 : _$a.description, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _ab : null,
5742
+ combined_hail_wind_probability: (_cb = getTextFromProduct({ message: (_bb = feature == null ? void 0 : feature.properties) == null ? void 0 : _bb.description, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _cb : null,
5743
+ max_hail_in: (_eb = getTextFromProduct({ message: (_db = feature == null ? void 0 : feature.properties) == null ? void 0 : _db.description, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _eb : null,
5744
+ max_wind_surface: (_gb = getTextFromProduct({ message: (_fb = feature == null ? void 0 : feature.properties) == null ? void 0 : _fb.description, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _gb : null,
5745
+ max_tops_x100feet: (_ib = getTextFromProduct({ message: (_hb = feature == null ? void 0 : feature.properties) == null ? void 0 : _hb.description, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _ib : null,
5746
+ pds_watch: getTextFromProduct({ message: (_jb = feature == null ? void 0 : feature.properties) == null ? void 0 : _jb.description, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
5747
+ },
5748
+ metadata: {
5749
+ ms: performance.now() - tick,
5750
+ source: `events.api`,
5751
+ tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (_mb = (_lb = (_kb = feature == null ? void 0 : feature.properties) == null ? void 0 : _kb.parameters) == null ? void 0 : _lb.WMOidentifier) == null ? void 0 : _mb[0], featureId: feature == null ? void 0 : feature.id }, vtec: pVtec == null ? void 0 : pVtec[0] }),
5752
+ header: `ZCZC-ATMOSX-${(_ob = (_nb = feature == null ? void 0 : feature.properties) == null ? void 0 : _nb.parameters) == null ? void 0 : _ob.WMOidentifier}`,
5753
+ vtec: pVtec == null ? void 0 : pVtec[0],
5754
+ hvtec: null,
5755
+ raw: (_pb = feature == null ? void 0 : feature.properties) == null ? void 0 : _pb.description,
5756
+ history: [
5757
+ {
5758
+ description: (_qb = feature == null ? void 0 : feature.properties) == null ? void 0 : _qb.description,
5759
+ issued: ((_rb = feature == null ? void 0 : feature.properties) == null ? void 0 : _rb.sent) ? new Date((_sb = feature == null ? void 0 : feature.properties) == null ? void 0 : _sb.sent).toISOString() : null,
5760
+ status: (_ub = (_tb = feature == null ? void 0 : feature.properties) == null ? void 0 : _tb.messageType) != null ? _ub : null
5761
+ }
5762
+ ]
5763
+ }
5665
5764
  }
5666
- break;
5667
- default:
5668
- break;
5765
+ });
5766
+ setDebug({ title: `@events.api`, message: `Event process took ${performance.now() - tick} ms` });
5669
5767
  }
5670
5768
  });
5671
5769
 
5672
- // src/@modules/@eas/eas.getCleanDescription.ts
5673
- var getCleanDescription = (message) => {
5674
- const patches = [
5675
- { regex: /\.{3,}/g, replacement: ". " },
5676
- { regex: /\bUTC\b/g, replacement: "Coordinated Universal Time" },
5677
- { regex: /\bGMT\b/g, replacement: "Greenwich Mean Time" },
5678
- { regex: /\bEST\b(?!\w)/g, replacement: "Eastern Standard Time" },
5679
- { regex: /\bEDT\b(?!\w)/g, replacement: "Eastern Daylight Time" },
5680
- { regex: /\bCST\b(?!\w)/g, replacement: "Central Standard Time" },
5681
- { regex: /\bCDT\b(?!\w)/g, replacement: "Central Daylight Time" },
5682
- { regex: /\bMST\b(?!\w)/g, replacement: "Mountain Standard Time" },
5683
- { regex: /\bMDT\b(?!\w)/g, replacement: "Mountain Daylight Time" },
5684
- { regex: /\bPST\b(?!\w)/g, replacement: "Pacific Standard Time" },
5685
- { regex: /\bPDT\b(?!\w)/g, replacement: "Pacific Daylight Time" },
5686
- { regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
5687
- { regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
5688
- { regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
5689
- { regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
5690
- { regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
5691
- { regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
5692
- { regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
5693
- { regex: /\bkt\b(?!\w)/g, replacement: "knots" },
5694
- { regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
5695
- { regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
5696
- { regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
5697
- { regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
5698
- { regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
5699
- { regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
5700
- { regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
5701
- { regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
5702
- { regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
5703
- { regex: /\bin.\b(?!\w)/g, replacement: "inches" },
5704
- { regex: /\bft\b(?!\w)/g, replacement: "feet" },
5705
- { regex: /\bmi\b(?!\w)/g, replacement: "miles" },
5706
- { regex: /\bhr\b(?!\w)/g, replacement: "hour" },
5707
- { regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
5708
- { regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
5709
- { regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
5710
- { regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
5711
- { regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
5712
- { regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
5713
- { regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
5714
- { regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
5715
- { regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
5716
- { regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
5717
- { regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
5718
- { regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
5719
- { regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
5720
- ];
5721
- const hours = {
5722
- 0: "twelve",
5723
- 1: "one",
5724
- 2: "two",
5725
- 3: "three",
5726
- 4: "four",
5727
- 5: "five",
5728
- 6: "six",
5729
- 7: "seven",
5730
- 8: "eight",
5731
- 9: "nine",
5732
- 10: "ten",
5733
- 11: "eleven",
5734
- 12: "twelve"
5735
- };
5736
- const minWord = (m) => m === 0 ? "o'clock" : m < 10 ? `oh ${m}` : `${m}`;
5737
- const fmt = (h, m, ap) => `${hours[h % 12]} ${minWord(m)} ${ap}`;
5738
- for (const { regex, replacement } of patches) {
5739
- message = message.replace(regex, replacement);
5770
+ // src/@dictionaries/dictionaries.enhanced.ts
5771
+ var dict_enhanced = {
5772
+ "Tornado Warning": {
5773
+ "Tornado Emergency": { description: "tornado emergency" },
5774
+ "PDS Tornado Warning": { description: "particularly dangerous situation", damage: `CONSIDERABLE` },
5775
+ "Radar Confirmed Tornado Warning": { description: "source...radar confirmed tornado.", tornado: `OBSERVED` },
5776
+ "Confirmed Tornado Warning": { tornado: `OBSERVED` },
5777
+ "Radar Indicated Tornado Warning": {}
5778
+ },
5779
+ "Fire Weather Warning": {
5780
+ "PDS Fire Weather Warning": { description: "particularly dangerous situation" }
5781
+ },
5782
+ "Blizzard Warning": {
5783
+ "PDS Blizzard Warning": { description: "particularly dangerous situation" }
5784
+ },
5785
+ "Ice Storm Warning": {
5786
+ "PDS Ice Storm Warning": { description: "particularly dangerous situation" }
5787
+ },
5788
+ "Special Marine Warning": {
5789
+ "Special Marine Warning (TPROB)": { tornado: `POSSIBLE` }
5790
+ },
5791
+ "Tornado Watch": {
5792
+ "PDS Tornado Watch": { pdswatch: true }
5793
+ },
5794
+ "Severe Thunderstorm Watch": {
5795
+ "PDS Severe Thunderstorm Watch": { pdswatch: true }
5796
+ },
5797
+ "Flash Flood Warning": {
5798
+ "Flash Flood Emergency": { description: "flash flood emergency" },
5799
+ "Considerable Flash Flood Warning": { damage: `CONSIDERABLE` }
5800
+ },
5801
+ "Severe Thunderstorm Warning": {
5802
+ "EDS Severe Thunderstorm Warning (TPROB)": { description: "extremely dangerous situation", tornado: "POSSIBLE" },
5803
+ "EDS Severe Thunderstorm Warning": { description: "extremely dangerous situation" },
5804
+ "Destructive Severe Thunderstorm Warning (TPROB)": { damage: `DESTRUCTIVE`, tornado: `POSSIBLE` },
5805
+ "Destructive Severe Thunderstorm Warning": { damage: `DESTRUCTIVE` },
5806
+ "Considerable Severe Thunderstorm Warning (TPROB)": { damage: `CONSIDERABLE`, tornado: `POSSIBLE` },
5807
+ "Considerable Severe Thunderstorm Warning": { damage: `CONSIDERABLE` },
5808
+ "Severe Thunderstorm Warning (TPROB)": { tornado: `POSSIBLE` }
5740
5809
  }
5741
- return message.replace(/'/g, "''").replace(/\b(\d{1,2}):(\d{2})\s*(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(\d{2})\s+(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{2})(\d{2})\s+(AM|PM)\b/gi, (_, hh, mm, ap) => fmt(+hh, +mm, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(AM|PM)\b/gi, (_, h, ap) => fmt(+h, 0, ap.toUpperCase())).replace(/\*+/g, " ").replace(/-/g, " ").replace(/\n/g, " ").trim();
5742
5810
  };
5743
5811
 
5744
- // src/@modules/@eas/eas.setEasTone.ts
5745
- var import_path2 = require("path");
5746
- var import_fs2 = require("fs");
5747
- var import_child_process2 = require("child_process");
5748
- var import_os2 = require("os");
5749
- var setEasTone = (options) => __async(null, null, function* () {
5750
- var _a;
5751
- const settings = bootstrap.settings;
5752
- const directory = settings.GlobalSettings.ArchiveSettings.EasDirectory;
5753
- const prefix = settings.GlobalSettings.ArchiveSettings.EasToneout;
5754
- let message = options.message;
5755
- let header = options.header;
5756
- let title = (_a = options.title) != null ? _a : `${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}`;
5757
- if (!message || !header) {
5758
- setWarning({
5759
- title: `EAS`,
5760
- message: `Message and header are required to generate an EAS tone.`
5761
- });
5762
- return null;
5763
- }
5764
- let buffTTS;
5765
- let buffRadio;
5766
- let buffFull = [];
5767
- if (!(0, import_fs2.existsSync)(directory)) {
5768
- (0, import_fs2.mkdirSync)(directory, { recursive: true });
5769
- }
5770
- if (!(0, import_fs2.existsSync)((0, import_path2.join)(directory, `/tts`))) {
5771
- (0, import_fs2.mkdirSync)((0, import_path2.join)(directory, `/tts`), { recursive: true });
5772
- }
5773
- if (!(0, import_fs2.existsSync)((0, import_path2.join)(directory, `/encoded`))) {
5774
- (0, import_fs2.mkdirSync)((0, import_path2.join)(directory, `/encoded`), { recursive: true });
5775
- }
5776
- const tmpTTS = (0, import_path2.join)(directory, `/tts/${title}.wav`);
5777
- const outTTS = (0, import_path2.join)(directory, `/encoded/${title}.wav`);
5778
- const vPlatform = (0, import_os2.platform)();
5779
- if (vPlatform === "darwin") {
5780
- setWarning({
5781
- title: `EAS`,
5782
- message: `EAS tone generation is not supported on macOS.`
5783
- });
5784
- return null;
5785
- }
5786
- yield new Promise((resolve6, reject) => {
5787
- const tMsg = getCleanDescription(message);
5788
- getTTS(tMsg, tmpTTS).then(() => {
5789
- resolve6();
5790
- });
5791
- });
5792
- if (!(0, import_fs2.existsSync)(tmpTTS)) {
5793
- return null;
5812
+ // src/@building/building.enhance.ts
5813
+ var getEventEnhancedName = (event) => {
5814
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5815
+ const configurations = bootstrap.settings;
5816
+ let name = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.event;
5817
+ if (!((_b = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _b.BetterEventNames)) {
5818
+ return name;
5794
5819
  }
5795
- buffTTS = (0, import_fs2.readFileSync)(tmpTTS);
5796
- const vWav = getWavPCM16(buffTTS);
5797
- const vSamples = getSampledPCM16(vWav.samples, vWav.sampleRate, 8e3);
5798
- const vRadio = setRadioEffect(vSamples, 8e3);
5799
- if ((0, import_fs2.existsSync)(prefix)) {
5800
- let tBuffer = (0, import_fs2.readFileSync)(prefix);
5801
- let tWav = getWavPCM16(tBuffer);
5802
- if (tWav == null) {
5803
- try {
5804
- const converted = (0, import_path2.join)(directory, `/tts/${title}.converted.wav`);
5805
- (0, import_child_process2.execSync)(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
5806
- if ((0, import_fs2.existsSync)(converted)) {
5807
- tBuffer = (0, import_fs2.readFileSync)(converted);
5808
- tWav = getWavPCM16(tBuffer);
5809
- try {
5810
- (0, import_fs2.unlinkSync)(converted);
5811
- } catch (e) {
5812
- }
5813
- }
5814
- } catch (e) {
5820
+ const damage = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat;
5821
+ const tornado = (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.tornado_threat;
5822
+ const pdswatch = (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.watch_parameters) == null ? void 0 : _h.pds_watch;
5823
+ const description = (_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.description) == null ? void 0 : _j.toLowerCase();
5824
+ for (const [eventKey, eventConfig] of Object.entries(dict_enhanced)) {
5825
+ if (eventKey !== name) continue;
5826
+ for (const [paramKey, paramValue] of Object.entries(eventConfig)) {
5827
+ let matches = true;
5828
+ if (paramValue == null ? void 0 : paramValue.description) {
5829
+ if (!description.includes(paramValue.description.toLowerCase())) matches = false;
5830
+ }
5831
+ if (paramValue == null ? void 0 : paramValue.damage) {
5832
+ if (paramValue.damage !== damage) matches = false;
5833
+ }
5834
+ if (paramValue == null ? void 0 : paramValue.tornado) {
5835
+ if (paramValue.tornado !== tornado) matches = false;
5836
+ }
5837
+ if (paramValue == null ? void 0 : paramValue.pdswatch) {
5838
+ if (paramValue.pdswatch !== pdswatch) matches = false;
5839
+ }
5840
+ if (matches) {
5841
+ name = paramKey;
5842
+ break;
5815
5843
  }
5816
5844
  }
5817
- if (tWav == null) {
5818
- setWarning({ title: `EAS`, 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.` });
5819
- return null;
5820
- }
5821
- const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
5822
- buffRadio = setRadioEffect(tSamples, 8e3);
5823
5845
  }
5824
- buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
5825
- buffFull.push(
5826
- setSameHeader(header, 3, 8e3, {
5827
- preMarkSec: 1.1,
5828
- gapSec: 0.5
5829
- }),
5830
- new Int16Array(Math.floor(0.5 * 8e3)),
5831
- setAttentionTone(8, 8e3),
5832
- new Int16Array(Math.floor(0.5 * 8e3)),
5833
- vRadio
5834
- );
5835
- for (let i = 0; i < 3; i++) {
5836
- buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
5837
- buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
5838
- }
5839
- const aSamples = getMergedPCM16(buffFull);
5840
- const aFinal = setNoise(aSamples, 2e-3);
5841
- const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
5842
- (0, import_fs2.writeFileSync)(outTTS, aBuffer);
5843
- try {
5844
- (0, import_fs2.unlinkSync)(tmpTTS);
5845
- } catch (e) {
5846
- }
5847
- return outTTS;
5848
- });
5846
+ return name;
5847
+ };
5849
5848
 
5850
- // src/@parsers/@text/text.getEmbed.ts
5851
- var getEmebed = (event) => {
5852
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na;
5853
- const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
5854
- const isStatement = event.properties.status_metadata.is_statement;
5855
- const isExpired = event.properties.status_metadata.is_expired;
5856
- return [
5857
- line(`**Locations:**`, (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.locations) == null ? void 0 : _b.slice(0, 100)),
5858
- line(`**Issued:**`, `<t:${Math.floor(new Date(event.properties.issued).getTime() / 1e3)}:R>`, !isExpired),
5859
- line(`**Expires:**`, `<t:${Math.floor(new Date(event.properties.expires).getTime() / 1e3)}:R>`, !isStatement),
5860
- line(`**Damage Threat:**`, (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat, !isExpired),
5861
- line(`**Flood Threat:**`, (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.flood_threat, !isExpired),
5862
- line(`**Tornado Threat:**`, (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.parameters) == null ? void 0 : _h.tornado_threat, !isExpired),
5863
- line(`**Estimated Wind Gusts:**`, `${(_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.parameters) == null ? void 0 : _j.estimated_wind_gusts} ${((_l = (_k = event == null ? void 0 : event.properties) == null ? void 0 : _k.parameters) == null ? void 0 : _l.wind_threat) ? ` (${(_n = (_m = event == null ? void 0 : event.properties) == null ? void 0 : _m.parameters) == null ? void 0 : _n.wind_threat})` : ""}`, !isExpired && ((_p = (_o = event == null ? void 0 : event.properties) == null ? void 0 : _o.parameters) == null ? void 0 : _p.estimated_wind_gusts) != null),
5864
- line(`**Estimated Hail Size:**`, `${(_r = (_q = event == null ? void 0 : event.properties) == null ? void 0 : _q.parameters) == null ? void 0 : _r.estimated_hail_size} ${((_t = (_s = event == null ? void 0 : event.properties) == null ? void 0 : _s.parameters) == null ? void 0 : _t.hail_threat) ? ` (${(_v = (_u = event == null ? void 0 : event.properties) == null ? void 0 : _u.parameters) == null ? void 0 : _v.hail_threat})` : ""}`, !isExpired && ((_x = (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.parameters) == null ? void 0 : _x.estimated_hail_size) != null),
5865
- line(`**Discussion:**`, (_z = (_y = event == null ? void 0 : event.properties) == null ? void 0 : _y.discussion_parameters) == null ? void 0 : _z.discussion_number, !isExpired),
5866
- line(`**Concern:**`, (_B = (_A = event == null ? void 0 : event.properties) == null ? void 0 : _A.discussion_parameters) == null ? void 0 : _B.discussion_concerning, !isExpired),
5867
- line(`**SPC Max Tornado Threat:**`, (_D = (_C = event == null ? void 0 : event.properties) == null ? void 0 : _C.discussion_parameters) == null ? void 0 : _D.discussion_max_tornado, !isExpired),
5868
- line(`**SPC Max Hail Threat:**`, (_F = (_E = event == null ? void 0 : event.properties) == null ? void 0 : _E.discussion_parameters) == null ? void 0 : _F.discussion_max_hail, !isExpired),
5869
- line(`**SPC Max Wind Threat:**`, (_H = (_G = event == null ? void 0 : event.properties) == null ? void 0 : _G.discussion_parameters) == null ? void 0 : _H.discussion_max_wind, !isExpired),
5870
- line(`**SPC Watch Issuance Probability:**`, ((_J = (_I = event == null ? void 0 : event.properties) == null ? void 0 : _I.discussion_parameters) == null ? void 0 : _J.discussion_watch_issuance) ? `${(_L = (_K = event == null ? void 0 : event.properties) == null ? void 0 : _K.discussion_parameters) == null ? void 0 : _L.discussion_watch_issuance}%` : null, !isExpired),
5871
- line(`**Watch Number:**`, (_N = (_M = event == null ? void 0 : event.properties) == null ? void 0 : _M.watch_parameters) == null ? void 0 : _N.watch_number, !isExpired),
5872
- line(`**Strong Tornadoes Probability:**`, ((_P = (_O = event == null ? void 0 : event.properties) == null ? void 0 : _O.watch_parameters) == null ? void 0 : _P.strong_tornadoes_probability) ? `${(_R = (_Q = event == null ? void 0 : event.properties) == null ? void 0 : _Q.watch_parameters) == null ? void 0 : _R.strong_tornadoes_probability}%` : null, !isExpired),
5873
- line(`**Additional Tornadoes Probability:**`, ((_T = (_S = event == null ? void 0 : event.properties) == null ? void 0 : _S.watch_parameters) == null ? void 0 : _T.additional_tornadoes_probability) ? `${(_V = (_U = event == null ? void 0 : event.properties) == null ? void 0 : _U.watch_parameters) == null ? void 0 : _V.additional_tornadoes_probability}%` : null, !isExpired),
5874
- line(`**Combined Hail/Wind Probability:**`, ((_X = (_W = event == null ? void 0 : event.properties) == null ? void 0 : _W.watch_parameters) == null ? void 0 : _X.combined_hail_wind_probability) ? `${(_Z = (_Y = event == null ? void 0 : event.properties) == null ? void 0 : _Y.watch_parameters) == null ? void 0 : _Z.combined_hail_wind_probability}%` : null, !isExpired),
5875
- line(`**Severe Hail Probability:**`, ((_$ = (__ = event == null ? void 0 : event.properties) == null ? void 0 : __.watch_parameters) == null ? void 0 : _$.severe_hail_probability) ? `${(_ba = (_aa = event == null ? void 0 : event.properties) == null ? void 0 : _aa.watch_parameters) == null ? void 0 : _ba.severe_hail_probability}%` : null, !isExpired),
5876
- line(`**Hail >2in Probability:**`, ((_da = (_ca = event == null ? void 0 : event.properties) == null ? void 0 : _ca.watch_parameters) == null ? void 0 : _da.hail_2in_probability) ? `${(_fa = (_ea = event == null ? void 0 : event.properties) == null ? void 0 : _ea.watch_parameters) == null ? void 0 : _fa.hail_2in_probability}%` : null, !isExpired),
5877
- line(`**Max Hail Inches:**`, (_ha = (_ga = event == null ? void 0 : event.properties) == null ? void 0 : _ga.watch_parameters) == null ? void 0 : _ha.max_hail_in, !isExpired),
5878
- line(`**Severe Wind Probability:**`, ((_ja = (_ia = event == null ? void 0 : event.properties) == null ? void 0 : _ia.watch_parameters) == null ? void 0 : _ja.severe_wind_probability) ? `${(_la = (_ka = event == null ? void 0 : event.properties) == null ? void 0 : _ka.watch_parameters) == null ? void 0 : _la.severe_wind_probability}%` : null, !isExpired),
5879
- line(`**Max Surface Wind:**`, (_na = (_ma = event == null ? void 0 : event.properties) == null ? void 0 : _ma.watch_parameters) == null ? void 0 : _na.max_wind_surface, !isExpired),
5880
- line(`**Max Tops (x100 feet):**`, (_pa = (_oa = event == null ? void 0 : event.properties) == null ? void 0 : _oa.watch_parameters) == null ? void 0 : _pa.max_tops_x100feet, !isExpired),
5881
- line(`**Tags:**`, ((_sa = (_ra = (_qa = event == null ? void 0 : event.properties) == null ? void 0 : _qa.parameters) == null ? void 0 : _ra.tags) == null ? void 0 : _sa.length) > 0 ? (_ua = (_ta = event == null ? void 0 : event.properties) == null ? void 0 : _ta.parameters) == null ? void 0 : _ua.tags.join(", ") : null, !isExpired),
5882
- line(`**Sender:**`, ((_xa = (_wa = (_va = event == null ? void 0 : event.properties) == null ? void 0 : _va.geocode) == null ? void 0 : _wa.office) == null ? void 0 : _xa.name) ? `${(_Aa = (_za = (_ya = event == null ? void 0 : event.properties) == null ? void 0 : _ya.geocode) == null ? void 0 : _za.office) == null ? void 0 : _Aa.name} (${(_Da = (_Ca = (_Ba = event == null ? void 0 : event.properties) == null ? void 0 : _Ba.geocode) == null ? void 0 : _Ca.office) == null ? void 0 : _Da.office})` : (_Ga = (_Fa = (_Ea = event == null ? void 0 : event.properties) == null ? void 0 : _Ea.geocode) == null ? void 0 : _Fa.office) == null ? void 0 : _Ga.office),
5883
- line(`**Tracking:**`, (_Ia = (_Ha = event == null ? void 0 : event.properties) == null ? void 0 : _Ha.metadata) == null ? void 0 : _Ia.tracking),
5884
- line(`**Logs:**`, ((_La = (_Ka = (_Ja = event == null ? void 0 : event.properties) == null ? void 0 : _Ja.metadata) == null ? void 0 : _Ka.history) == null ? void 0 : _La.length) > 0 ? (_Na = (_Ma = event == null ? void 0 : event.properties) == null ? void 0 : _Ma.metadata) == null ? void 0 : _Na.history.length : null)
5885
- ].filter(Boolean).join("\n");
5849
+ // src/@dictionaries/dictionaries.correlations.ts
5850
+ var dict_correlations = [
5851
+ { type: "Statement", name: "Statement", isCancel: false, isUpdate: false, isIssued: true, isStatement: true },
5852
+ { type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5853
+ { type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5854
+ { type: "Alert", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
5855
+ { type: "Updated", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5856
+ { type: "Expired", name: "Expired", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5857
+ { type: "Issued", name: "Issued", isCancel: false, isUpdate: false, isIssued: true, isStatement: false },
5858
+ { type: "Extended", name: "Extended", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5859
+ { type: "Correction", name: "Correction", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5860
+ { type: "Upgraded", name: "Upgraded", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
5861
+ { type: "Cancelled", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
5862
+ { type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false, isStatement: false }
5863
+ ];
5864
+
5865
+ // src/@dictionaries/dictionaries.cancellation.ts
5866
+ var dict_cancellation = [
5867
+ "has been cancelled",
5868
+ "subsided sufficiently for the advisory to be cancelled",
5869
+ "has been cancelled",
5870
+ "no tsunami threat from a nearby earthquake",
5871
+ "will be allowed to expire",
5872
+ "has diminished",
5873
+ "and no longer",
5874
+ "has been replaced",
5875
+ "The threat has ended",
5876
+ "has weakened below severe"
5877
+ ];
5878
+
5879
+ // src/@dictionaries/dictionaries.testing.ts
5880
+ var dict_testing = [
5881
+ `This is a test message`,
5882
+ `Monitoring message only.`,
5883
+ `THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY`,
5884
+ "TEST MESSAGE"
5885
+ ];
5886
+
5887
+ // src/@dictionaries/dictionaries.hail.ts
5888
+ var dict_hail = {
5889
+ ".25": "Pea",
5890
+ ".50": "Penny",
5891
+ ".75": "Penny",
5892
+ "Up to .75": "Penny",
5893
+ ".88": "Nickel",
5894
+ "0.75": "Penny",
5895
+ "0.88": "Nickel",
5896
+ "1.00": "Quarter",
5897
+ "1.25": "Half Dollar",
5898
+ "1.50": "Ping Pong Ball",
5899
+ "1.75": "Golf Ball",
5900
+ "2.00": "Hen Egg",
5901
+ "2.50": "Tennis Ball",
5902
+ "2.75": "Baseball",
5903
+ "4.00": "CD/DVD"
5886
5904
  };
5887
5905
 
5888
- // src/@modules/@utilities/utilities.createHttp.ts
5889
- var createHttp = (options) => __async(null, null, function* () {
5890
- var _a, _b, _c, _d;
5891
- const requestOptions = {
5892
- method: (_a = options.method) != null ? _a : "GET",
5893
- headers: (_b = options.headers) != null ? _b : {
5894
- "User-Agent": "AtmosphericX",
5895
- "Accept": "application/geo+json, text/plain, */*; q=0.9",
5896
- "Accept-Language": "en-US,en;q=0.9"
5897
- },
5898
- signal: AbortSignal.timeout((_c = options.timeout) != null ? _c : 1e4),
5899
- redirect: "follow"
5900
- };
5901
- const returnHttp = function(error, status, message) {
5902
- return { error, options: requestOptions, status, message };
5903
- };
5904
- if (options == null ? void 0 : options.formData) {
5905
- requestOptions.body = options.formData;
5906
- } else if ((options == null ? void 0 : options.body) != void 0) {
5907
- requestOptions.body = options.body instanceof FormData ? options.body : typeof options.body === "string" ? options.body : JSON.stringify(options.body);
5906
+ // src/@building/building.signature.ts
5907
+ var getEventSignature = (event) => {
5908
+ var _a, _b, _c, _d, _e, _f, _g, _h;
5909
+ const properties2 = event == null ? void 0 : event.properties;
5910
+ const vtec2 = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.vtec;
5911
+ const status = dict_correlations.find((c) => c.type === (properties2 == null ? void 0 : properties2.status));
5912
+ const csig = dict_cancellation.find((sig) => properties2.description.toLowerCase().includes(sig.toLowerCase()));
5913
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_issued: true, is_test: false });
5914
+ if ((_c = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _c.estimated_hail_size) {
5915
+ properties2.parameters.estimated_hail_size += ` (${(_e = dict_hail[(_d = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _d.estimated_hail_size]) != null ? _e : "--"})`;
5916
+ }
5917
+ if (status) {
5918
+ properties2.status = (_f = status.name) != null ? _f : properties2.status;
5919
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement });
5920
+ }
5921
+ if (csig) {
5922
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
5923
+ }
5924
+ const getProduct = (_h = (_g = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _g.split(`.`)[0]) == null ? void 0 : _h.replace(`/`, ``);
5925
+ const isTestProduct = dict_products[getProduct] == `Test Product`;
5926
+ if (isTestProduct || dict_testing.some((sig) => {
5927
+ var _a2, _b2, _c2, _d2;
5928
+ return (_d2 = (_a2 = properties2.description) == null ? void 0 : _a2.toLowerCase().includes(sig.toLowerCase())) != null ? _d2 : (_c2 = (_b2 = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _b2.instructions) == null ? void 0 : _c2.toLowerCase().includes(sig.toLowerCase());
5929
+ })) {
5930
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_test: true });
5908
5931
  }
5909
- try {
5910
- const response2 = yield fetch(
5911
- (_d = options == null ? void 0 : options.url) != null ? _d : `https://api.weather.gov/alerts/active`,
5912
- requestOptions
5913
- );
5914
- const body = yield response2.text();
5915
- if (!response2.ok) {
5916
- return returnHttp(true, response2.status, `HTTP Status Code ${response2.status} (${response2.statusText})`);
5917
- }
5918
- return returnHttp(false, response2.status, body);
5919
- } catch (error) {
5920
- return returnHttp(true, 500, `Internal Server Error: ${error}`);
5932
+ if (new Date(properties2.expires).getTime() < Date.now()) {
5933
+ properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
5921
5934
  }
5922
- });
5935
+ properties2.status_metadata = __spreadValues({}, properties2.status_metadata);
5936
+ return event;
5937
+ };
5923
5938
 
5924
- // src/@manager/manager.updateListener.ts
5925
- var import_fs3 = require("fs");
5926
- var updateListener = (event) => __async(null, null, function* () {
5927
- var _a, _b, _c, _d;
5928
- const settings = bootstrap.settings;
5929
- const listeners2 = settings.ListenerSettings;
5930
- const properties2 = event.properties;
5931
- const metadata = {
5932
- file: null,
5933
- eas: null,
5934
- name: properties2.event,
5935
- status: properties2.status,
5936
- description: properties2.description,
5937
- tracking: properties2.metadata.tracking,
5938
- header: properties2.metadata.header,
5939
- raw: properties2.metadata.raw,
5940
- expired: properties2.status_metadata.is_expired,
5941
- attachments: properties2.metadata.attachments
5942
- };
5943
- for (const listener2 of listeners2) {
5944
- const events = listener2 == null ? void 0 : listener2.events;
5945
- const webhook = listener2 == null ? void 0 : listener2.webhook;
5946
- const uploads = listener2 == null ? void 0 : listener2.uploads;
5947
- const isMatched = events.some((pattern) => {
5948
- if (!pattern) return false;
5949
- if (pattern === "*" || pattern === metadata.name) return true;
5950
- if (pattern.includes("*")) {
5951
- const regex = "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
5952
- return new RegExp(regex).test(metadata.name);
5953
- }
5954
- return false;
5939
+ // src/@dictionaries/dictionaries.global.ts
5940
+ var dict_global = [
5941
+ "spc day 1 outlook",
5942
+ "spc day 2 outlook",
5943
+ "spc day 3 outlook"
5944
+ ];
5945
+
5946
+ // src/@manager/manager.setHash.ts
5947
+ var setHash = (event, entry) => {
5948
+ if (entry) {
5949
+ entry.hashes.push(event.properties.metadata.hash);
5950
+ entry.expires = event.properties.expires;
5951
+ } else {
5952
+ bootstrap.cache.hashes.push({
5953
+ tracking: event.properties.metadata.tracking,
5954
+ hashes: [event.properties.metadata.hash],
5955
+ expires: event.properties.expires
5955
5956
  });
5956
- if ((events == null ? void 0 : events.length) == 0 || isMatched) {
5957
- if (uploads == null ? void 0 : uploads.eas) {
5958
- metadata.eas = yield setEasTone({
5959
- title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
5960
- message: metadata.description,
5961
- header: metadata.header
5962
- });
5963
- }
5964
- if (uploads == null ? void 0 : uploads.file) {
5965
- const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
5966
- if (fDestination) {
5967
- if (!(0, import_fs3.existsSync)(fDestination)) {
5968
- (0, import_fs3.mkdirSync)(fDestination, { recursive: true });
5969
- }
5970
- if ((0, import_fs3.existsSync)(`${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`)) {
5971
- (0, import_fs3.appendFileSync)(`${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`, metadata.raw);
5972
- } else {
5973
- (0, import_fs3.writeFileSync)(`${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`, metadata.raw);
5974
- }
5975
- }
5976
- metadata.file = metadata.raw;
5977
- }
5978
- if (uploads == null ? void 0 : uploads.event) {
5979
- const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
5980
- if (eDestination) {
5981
- if (!(0, import_fs3.existsSync)(eDestination)) {
5982
- (0, import_fs3.mkdirSync)(eDestination, { recursive: true });
5983
- }
5984
- (0, import_fs3.writeFileSync)(`${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`, JSON.stringify(getCleanedEvent(event), null, 2));
5985
- }
5986
- }
5987
- if (webhook.enabled && webhook.destination) {
5988
- const ratelimit = setTimeoutAction({ identifier: webhook.destination, interval: webhook.ratelimit * 2, max: webhook.ratelimit, addTime: true });
5989
- const form = new FormData();
5990
- const embed = {
5991
- title: `${metadata.name} (${metadata.status})`,
5992
- description: getEmebed(event),
5993
- fields: [],
5994
- color: 16711680,
5995
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
5996
- footer: { text: (_a = webhook.title) != null ? _a : `AtmosphericX` }
5997
- };
5998
- if (ratelimit.limited) {
5999
- return;
6000
- }
6001
- if (metadata.description && !metadata.expired) {
6002
- if (metadata.description.length > 900) {
6003
- metadata.description = metadata.description.substring(0, 900) + "\n\n[Message truncated due to length]";
6004
- }
6005
- embed.fields.push({
6006
- name: "Description",
6007
- value: metadata.description ? "```\n" + metadata.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n") + "\n```" : ""
6008
- });
6009
- }
6010
- if (((_b = metadata.attachments) == null ? void 0 : _b.length) > 0) {
6011
- metadata.attachments = metadata.attachments.slice(0, 5);
6012
- embed.fields.push({
6013
- name: "Attachments",
6014
- value: metadata.attachments.map((attachment) => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + "..." : attachment.name}](${attachment.link})`).join("\n")
6015
- });
6016
- }
6017
- if (uploads == null ? void 0 : uploads.file) {
6018
- form.append("fUpload", new Blob([Buffer.from(metadata.file)], { type: "application/text" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`);
6019
- }
6020
- if (uploads == null ? void 0 : uploads.eas) {
6021
- if (metadata.eas) {
6022
- const file = (0, import_fs3.readFileSync)(metadata.eas);
6023
- form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`);
6024
- }
6025
- }
6026
- form.append("payload_json", JSON.stringify({
6027
- username: (_c = webhook.title) != null ? _c : "AtmosphericX",
6028
- content: (_d = webhook.message) != null ? _d : "",
6029
- embeds: [embed]
6030
- }));
6031
- const a = yield createHttp({
6032
- url: webhook.destination,
6033
- timeout: 5e3,
6034
- method: `POST`,
6035
- body: form
6036
- });
6037
- if (a.error) {
6038
- setWarning({ message: `Failed to send webhook: ${a.error.message}` });
6039
- }
6040
- }
6041
- }
6042
5957
  }
6043
- });
5958
+ };
6044
5959
 
6045
- // src/@modules/@utilities/utilities.getShapeNearestPoint.ts
6046
- var getShapeNearestPoint = (coordinates, point) => {
6047
- if (!coordinates || !point) {
6048
- return { proximity: false, point: [0, 0], distance: null };
5960
+ // src/@modules/@eas/eas.getWavPCM16.ts
5961
+ var getWavPCM16 = (buffer) => {
5962
+ if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
5963
+ return null;
6049
5964
  }
6050
- const normalize = (coords) => {
6051
- if (!Array.isArray(coords)) return [];
6052
- if (typeof coords[0] === "number" && typeof coords[1] === "number") return [];
6053
- if (Array.isArray(coords[0]) && typeof coords[0][0] === "number") {
6054
- return [[coords]];
6055
- }
6056
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === "number") {
6057
- return [coords];
6058
- }
6059
- if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === "number") {
6060
- return coords;
6061
- }
6062
- return [];
6063
- };
6064
- const polys = normalize(coordinates);
6065
- if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
6066
- const lon = point[0];
6067
- const lat = point[1];
6068
- const pointInRing = (pt, ring) => {
6069
- let x = pt[0], y = pt[1];
6070
- let inside = false;
6071
- for (let i = 0, j2 = ring.length - 1; i < ring.length; j2 = i++) {
6072
- const xi = ring[i][0], yi = ring[i][1];
6073
- const xj = ring[j2][0], yj = ring[j2][1];
6074
- const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi;
6075
- if (intersect) inside = !inside;
6076
- }
6077
- return inside;
6078
- };
6079
- const toRadians = (deg) => deg * Math.PI / 180;
6080
- const haversineMiles = (a, b) => {
6081
- const R = 3958.8;
6082
- const dLat = toRadians(b[1] - a[1]);
6083
- const dLon = toRadians(b[0] - a[0]);
6084
- const lat1 = toRadians(a[1]);
6085
- const lat2 = toRadians(b[1]);
6086
- const sinDLat = Math.sin(dLat / 2);
6087
- const sinDLon = Math.sin(dLon / 2);
6088
- const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
6089
- return R * c;
6090
- };
6091
- let minDistance = Infinity;
6092
- let closestPoint = null;
6093
- for (const poly of polys) {
6094
- const outer = poly[0];
6095
- const holes = poly.slice(1);
6096
- if (pointInRing(point, outer)) {
6097
- let inHole = false;
6098
- for (const hole of holes) {
6099
- if (pointInRing(point, hole)) {
6100
- inHole = true;
6101
- break;
6102
- }
6103
- }
6104
- if (!inHole) {
6105
- return { proximity: true, point, distance: 0 };
6106
- }
6107
- }
6108
- for (const ring of poly) {
6109
- for (let i = 0; i < ring.length - 1; i++) {
6110
- const start = [ring[i][0], ring[i][1]];
6111
- const end = [ring[i + 1][0], ring[i + 1][1]];
6112
- const A = lon - start[0];
6113
- const B = lat - start[1];
6114
- const C = end[0] - start[0];
6115
- const D = end[1] - start[1];
6116
- const lenSq = C * C + D * D;
6117
- const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
6118
- const candidate = [start[0] + t * C, start[1] + t * D];
6119
- const dist = haversineMiles([lon, lat], candidate);
6120
- if (!isNaN(dist) && dist < minDistance) {
6121
- minDistance = Number(dist.toFixed(3));
6122
- closestPoint = candidate;
6123
- }
6124
- }
6125
- }
5965
+ let fmt = null;
5966
+ let data = null;
5967
+ let i = 12;
5968
+ while (i + 8 <= buffer.length) {
5969
+ const id2 = buffer.toString("ascii", i, i + 4);
5970
+ const size = buffer.readUInt32LE(i + 4);
5971
+ const start = i + 8;
5972
+ const end = start + size;
5973
+ if (id2 === "fmt ") fmt = buffer.slice(start, end);
5974
+ if (id2 === "data") data = buffer.slice(start, end);
5975
+ i = end + size % 2;
6126
5976
  }
6127
- if (!isFinite(minDistance) || closestPoint == null) {
6128
- return { proximity: false, point: [0, 0], distance: null };
5977
+ if (!fmt || !data) return null;
5978
+ const audioFormat = fmt.readUInt16LE(0);
5979
+ const channels = fmt.readUInt16LE(2);
5980
+ const sampleRate = fmt.readUInt32LE(4);
5981
+ const bitsPerSample = fmt.readUInt16LE(14);
5982
+ if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
5983
+ return null;
5984
+ }
5985
+ const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
5986
+ return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
5987
+ };
5988
+
5989
+ // src/@modules/@eas/eas.getSampledPCM16.ts
5990
+ var getSampledPCM16 = (int16, originalRate, targetRate) => {
5991
+ if (originalRate === targetRate) return int16;
5992
+ const ratio = targetRate / originalRate;
5993
+ const outLen = Math.max(1, Math.round(int16.length * ratio));
5994
+ const out = new Int16Array(outLen);
5995
+ for (let i = 0; i < outLen; i++) {
5996
+ const pos = i / ratio;
5997
+ const i0 = Math.floor(pos);
5998
+ const i1 = Math.min(i0 + 1, int16.length - 1);
5999
+ const frac = pos - i0;
6000
+ const v = int16[i0] * (1 - frac) + int16[i1] * frac;
6001
+ out[i] = Math.round(v);
6002
+ }
6003
+ return out;
6004
+ };
6005
+
6006
+ // src/@modules/@eas/eas.getPCMToFloat.ts
6007
+ var getPCMToFloat = (int16) => {
6008
+ const out = new Float32Array(int16.length);
6009
+ for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
6010
+ return out;
6011
+ };
6012
+
6013
+ // src/@modules/@eas/eas.getFloatPCM16.ts
6014
+ var getFloatPCM16 = (float32) => {
6015
+ const out = new Int16Array(float32.length);
6016
+ for (let i = 0; i < float32.length; i++) {
6017
+ let v = Math.max(-1, Math.min(1, float32[i]));
6018
+ out[i] = Math.round(v * 32767);
6129
6019
  }
6130
- const distanceMiles = minDistance;
6131
- const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
6132
- const distanceMeters = Math.round(distanceKm * 1e3);
6133
- return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
6020
+ return out;
6134
6021
  };
6135
6022
 
6136
- // src/@building/building.polygon.ts
6137
- var getEventNodes = (event) => __async(null, null, function* () {
6138
- var _a, _b;
6139
- const metadata = { nodes: [], proximity: false, filtered: false };
6140
- const geometry = yield getEventGeometry(event);
6141
- if (!geometry || !geometry.coordinates) {
6142
- return { nodes: [], filtered: false, updated: Date.now() };
6023
+ // src/@modules/@eas/eas.setRadioEffect.ts
6024
+ var setRadioEffect = (int16, sampleRate) => {
6025
+ const hpCut = 3555;
6026
+ const lpCut = 1600;
6027
+ const x = getPCMToFloat(int16);
6028
+ const dt = 1 / sampleRate;
6029
+ const rcHP = 1 / (2 * Math.PI * hpCut);
6030
+ const aHP = rcHP / (rcHP + dt);
6031
+ let yHP = 0, xPrev = 0;
6032
+ for (let i = 0; i < x.length; i++) {
6033
+ const xi = x[i];
6034
+ yHP = aHP * (yHP + xi - xPrev);
6035
+ xPrev = xi;
6036
+ x[i] = yHP;
6143
6037
  }
6144
- const nodes = bootstrap.cache.nodes.features;
6145
- for (const node of nodes) {
6146
- const [longitude, latitude] = node.geometry.coordinates;
6147
- const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude]);
6148
- const miles = (_a = getPoint.distance) != null ? _a : null;
6149
- const kilometers = Number((miles * 1.609344).toFixed(3));
6150
- const info = {
6151
- id: (_b = node.properties) == null ? void 0 : _b.identifier,
6152
- coordinates: [longitude, latitude],
6153
- nearest: getPoint.point,
6154
- miles,
6155
- kilometers,
6156
- proximity: getPoint.proximity
6157
- };
6158
- metadata.nodes.push(info);
6159
- if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
6160
- metadata.proximity = true;
6161
- info.proximity = true;
6162
- }
6038
+ const rcLP = 1 / (2 * Math.PI * lpCut);
6039
+ const aLP = dt / (rcLP + dt);
6040
+ let yLP = 0;
6041
+ for (let i = 0; i < x.length; i++) {
6042
+ yLP = yLP + aLP * (x[i] - yLP);
6043
+ x[i] = yLP;
6163
6044
  }
6164
- return {
6165
- nodes: metadata.nodes,
6166
- filtered: metadata.proximity,
6167
- updated: Date.now()
6168
- };
6169
- });
6045
+ const compGain = 2;
6046
+ const norm = Math.tanh(compGain);
6047
+ for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
6048
+ return getFloatPCM16(x);
6049
+ };
6170
6050
 
6171
- // src/@manager/manager.updateNodes.ts
6172
- var updateNode = (selectedEvent) => __async(null, null, function* () {
6173
- const events = bootstrap.cache.events.features;
6174
- const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
6175
- let total = 0;
6176
- function update(evt) {
6177
- return __async(this, null, function* () {
6178
- var _a, _b, _c;
6179
- const lastUpdate = (_c = (_b = (_a = evt == null ? void 0 : evt.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.updated) != null ? _c : null;
6180
- if (lastUpdate != null && Date.now() - lastUpdate < ttl) {
6181
- return evt;
6182
- }
6183
- const node = yield getEventNodes(evt);
6184
- if (node.nodes.length > 0) {
6185
- total++;
6186
- }
6187
- evt.properties.metadata.nodes = node.nodes;
6188
- evt.properties.metadata.filtered_proximity = node.filtered;
6189
- evt.properties.metadata.updated = node.updated;
6190
- });
6191
- }
6192
- if (!selectedEvent) {
6193
- yield Promise.all(events.map((evt) => __async(null, null, function* () {
6194
- yield update(evt);
6195
- })));
6051
+ // src/@modules/@eas/eas.setAFSK.ts
6052
+ var setAFSK = (bits, sampleRate) => {
6053
+ const baud = 520.83;
6054
+ const markFreq = 2083.3;
6055
+ const spaceFreq = 1562.5;
6056
+ const amplitude = 0.6;
6057
+ const twoPi = Math.PI * 2;
6058
+ const result = [];
6059
+ let phase = 0;
6060
+ let frac = 0;
6061
+ for (let b = 0; b < bits.length; b++) {
6062
+ const bit = bits[b];
6063
+ const freq = bit ? markFreq : spaceFreq;
6064
+ const samplesPerBit = sampleRate / baud + frac;
6065
+ const n = Math.round(samplesPerBit);
6066
+ frac = samplesPerBit - n;
6067
+ const inc = twoPi * freq / sampleRate;
6068
+ for (let i = 0; i < n; i++) {
6069
+ result.push(Math.round(Math.sin(phase) * amplitude * 32767));
6070
+ phase += inc;
6071
+ if (phase > twoPi) phase -= twoPi;
6072
+ }
6196
6073
  }
6197
- if (selectedEvent) {
6198
- yield update(selectedEvent);
6074
+ const fadeSamples = Math.floor(sampleRate * 2e-3);
6075
+ for (let i = 0; i < fadeSamples; i++) {
6076
+ const gain = i / fadeSamples;
6077
+ result[i] = Math.round(result[i] * gain);
6078
+ result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
6199
6079
  }
6200
- if (total > 0) {
6201
- setEventEmit({
6202
- event: `onNodeUpdate`,
6203
- metadata: {
6204
- type: `global-update`,
6205
- updated: total
6206
- }
6207
- });
6080
+ return Int16Array.from(result);
6081
+ };
6082
+
6083
+ // src/@modules/@eas/eas.setAsciiToBits.ts
6084
+ var setAsciiToBits = (str) => {
6085
+ const bits = [];
6086
+ for (let i = 0; i < str.length; i++) {
6087
+ const c = str.charCodeAt(i) & 255;
6088
+ bits.push(0);
6089
+ for (let b = 0; b < 8; b++) bits.push(c >> b & 1);
6090
+ bits.push(1, 1);
6208
6091
  }
6209
- });
6092
+ return bits;
6093
+ };
6210
6094
 
6211
- // src/@manager/manager.mkEvent.ts
6212
- var mkEvent = (event) => __async(null, null, function* () {
6213
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
6214
- const settings = bootstrap.settings;
6215
- const features = bootstrap.cache.events.features;
6216
- const getHash = event.properties.metadata.hash;
6217
- const getTracking = event.properties.metadata.tracking;
6218
- const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
6219
- const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
6220
- const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
6221
- if (isHashed || event.properties.status_metadata.is_expired) return;
6222
- setHash(event, isEntry);
6223
- const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
6224
- if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6225
- return;
6095
+ // src/@modules/@eas/eas.getMergedPCM16.ts
6096
+ var getMergedPCM16 = (arrays) => {
6097
+ let total = 0;
6098
+ for (const a of arrays) total += a.length;
6099
+ const out = new Int16Array(total);
6100
+ let o = 0;
6101
+ for (const a of arrays) {
6102
+ out.set(a, o);
6103
+ o += a.length;
6226
6104
  }
6227
- setEventEmit({
6228
- event: `onEventStatus`,
6229
- metadata: {
6230
- type: getFeature ? `Updated` : `New`,
6231
- event
6232
- },
6233
- message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6234
- });
6235
- if (settings.GlobalSettings.EventManagement) {
6236
- if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
6237
- if (getFeature) {
6238
- const getIndex = features.indexOf(getFeature);
6239
- const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
6240
- const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
6241
- const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
6242
- const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
6243
- const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
6244
- const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
6245
- const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex((h) => h.description === v.description && h.issued === v.issued) === i);
6246
- const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
6247
- const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
6248
- bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
6249
- properties: __spreadProps(__spreadValues({}, event.properties), {
6250
- metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
6251
- history: mHistory
6252
- }),
6253
- locations: mLocations,
6254
- geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
6255
- ugc: mUgc
6256
- })
6257
- })
6258
- });
6259
- updateListener(bootstrap.cache.events.features[getIndex]);
6260
- } else {
6261
- features.push(event);
6262
- updateListener(event);
6263
- }
6105
+ return out;
6106
+ };
6107
+
6108
+ // src/@modules/@eas/eas.setSameHeader.ts
6109
+ var setSameHeader = (vtec2, repeats, sampleRate = 8e3, options = {}) => {
6110
+ var _a, _b;
6111
+ const preMarkSec = (_a = options.preMarkSec) != null ? _a : 0.3;
6112
+ const gapSec = (_b = options.gapSec) != null ? _b : 0.1;
6113
+ const bursts = [];
6114
+ const gap = new Int16Array(Math.floor(gapSec * sampleRate));
6115
+ for (let i = 0; i < repeats; i++) {
6116
+ const bodyBits = setAsciiToBits(vtec2);
6117
+ const body = setAFSK(bodyBits, sampleRate);
6118
+ const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
6119
+ const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
6120
+ for (let j2 = 0; j2 < extendedBodyDuration; j2++) {
6121
+ extendedBody[j2] = Math.round(body[j2 % body.length] * 0.2);
6264
6122
  }
6123
+ extendedBody.set(gap, extendedBodyDuration);
6124
+ bursts.push(extendedBody);
6125
+ if (i !== repeats - 1) bursts.push(gap);
6265
6126
  }
6266
- });
6127
+ return getMergedPCM16(bursts);
6128
+ };
6129
+
6130
+ // src/@modules/@eas/eas.setAttentionTone.ts
6131
+ var setAttentionTone = (ms, sampleRate) => {
6132
+ const len = Math.floor(ms * sampleRate);
6133
+ const out = new Int16Array(len);
6134
+ const f1 = 853;
6135
+ const f2 = 960;
6136
+ const twoPi = Math.PI * 2;
6137
+ const amp = 0.1;
6138
+ const fadeLen = Math.floor(sampleRate * 0);
6139
+ for (let i = 0; i < len; i++) {
6140
+ const t = i / sampleRate;
6141
+ const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
6142
+ let gain = 1;
6143
+ if (i < fadeLen) gain = i / fadeLen;
6144
+ else if (i > len - fadeLen) gain = (len - i) / fadeLen;
6145
+ const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
6146
+ out[i] = Math.round(v * 32767);
6147
+ }
6148
+ return out;
6149
+ };
6150
+
6151
+ // src/@modules/@eas/eas.setNoise.ts
6152
+ var setNoise = (int16, noiseLevel = 0.02) => {
6153
+ const x = getPCMToFloat(int16);
6154
+ for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
6155
+ let peak = 0;
6156
+ for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
6157
+ if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
6158
+ return getFloatPCM16(x);
6159
+ };
6267
6160
 
6268
- // src/@manager/manager.rmEvent.ts
6269
- var rmEvent = (event) => {
6270
- const getEvent = bootstrap.cache.events.features.find((f) => {
6271
- var _a, _b, _c, _d;
6272
- return ((_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking) === ((_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.metadata) == null ? void 0 : _d.tracking);
6273
- });
6274
- const cachedStatus = event.properties.status;
6275
- event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6276
- event.properties.status = `Expired`;
6277
- event.properties.status_metadata.is_expired = true;
6278
- if (getEvent) {
6279
- setEventEmit({
6280
- event: `onEventStatus`,
6281
- metadata: {
6282
- type: `Removed`,
6283
- event
6284
- },
6285
- message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6286
- });
6287
- setEventEmit({ event: `onExpiredProduct`, metadata: event });
6288
- if (cachedStatus != `Statement`) updateListener(event);
6289
- bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6290
- bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
6161
+ // src/@modules/@eas/eas.getPCM16.ts
6162
+ var getPCM16 = (samples, sampleRate) => {
6163
+ let o = 0;
6164
+ const bytesPerSample = 2;
6165
+ const blockAlign = 1 * bytesPerSample;
6166
+ const byteRate = sampleRate * blockAlign;
6167
+ const subchunk2Size = samples.length * bytesPerSample;
6168
+ const chunkSize = 36 + subchunk2Size;
6169
+ const buffer = Buffer.alloc(44 + subchunk2Size);
6170
+ buffer.write("RIFF", o);
6171
+ o += 4;
6172
+ buffer.writeUInt32LE(chunkSize, o);
6173
+ o += 4;
6174
+ buffer.write("WAVE", o);
6175
+ o += 4;
6176
+ buffer.write("fmt ", o);
6177
+ o += 4;
6178
+ buffer.writeUInt32LE(16, o);
6179
+ o += 4;
6180
+ buffer.writeUInt16LE(1, o);
6181
+ o += 2;
6182
+ buffer.writeUInt16LE(1, o);
6183
+ o += 2;
6184
+ buffer.writeUInt32LE(sampleRate, o);
6185
+ o += 4;
6186
+ buffer.writeUInt32LE(byteRate, o);
6187
+ o += 4;
6188
+ buffer.writeUInt16LE(blockAlign, o);
6189
+ o += 2;
6190
+ buffer.writeUInt16LE(16, o);
6191
+ o += 2;
6192
+ buffer.write("data", o);
6193
+ o += 4;
6194
+ buffer.writeUInt32LE(subchunk2Size, o);
6195
+ o += 4;
6196
+ for (let i = 0; i < samples.length; i++, o += 2) {
6197
+ buffer.writeInt16LE(samples[i].value, o);
6291
6198
  }
6292
- setEventEmit({
6293
- event: `onEventCache`,
6294
- metadata: bootstrap.cache.events,
6295
- limited: true
6296
- });
6199
+ return buffer;
6297
6200
  };
6298
6201
 
6299
- // src/@modules/@utilities/utilities.getLatestIssuance.ts
6300
- var getLatestIssuance = () => {
6301
- const now = /* @__PURE__ */ new Date();
6302
- const current = now.getUTCHours() * 100 + now.getUTCMinutes();
6303
- const issuances = [100, 600, 1300, 1630, 2e3];
6304
- let latest = issuances[0];
6305
- for (const issuance of issuances) {
6306
- if (current >= issuance) {
6307
- latest = issuance;
6202
+ // src/@modules/@eas/eas.getTTS.ts
6203
+ var import_os = require("os");
6204
+ var import_fs = require("fs");
6205
+ var import_child_process = require("child_process");
6206
+ var getTTS = (text2, outputPath) => __async(null, null, function* () {
6207
+ const vPlatform = (0, import_os.platform)();
6208
+ switch (vPlatform) {
6209
+ case "win32": {
6210
+ try {
6211
+ const txtPath = outputPath + ".txt";
6212
+ (0, import_fs.writeFileSync)(txtPath, text2, "utf8");
6213
+ const command = [
6214
+ "Add-Type -AssemblyName System.Speech;",
6215
+ `$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
6216
+ `$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
6217
+ `$speak.SetOutputToWaveFile('${outputPath}');`,
6218
+ `$speak.Speak($text);`,
6219
+ `$speak.Dispose();`
6220
+ ].join(" ");
6221
+ (0, import_child_process.execSync)(`powershell -Command "${command}"`, { stdio: "inherit" });
6222
+ } catch (error) {
6223
+ console.error("Error occurred while generating TTS:", error);
6224
+ }
6225
+ break;
6308
6226
  }
6227
+ case "linux":
6228
+ try {
6229
+ (0, import_child_process.execSync)(`espeak -w "${outputPath}" "${text2.replace(/"/g, '\\"')}"`);
6230
+ } catch (e) {
6231
+ }
6232
+ break;
6233
+ default:
6234
+ break;
6309
6235
  }
6310
- return latest.toString().padStart(4, "0");
6311
- };
6236
+ });
6312
6237
 
6313
- // src/@dictionaries/dictionaries.states.ts
6314
- var dict_states = {
6315
- "AL": "Alabama",
6316
- "AK": "Alaska",
6317
- "AZ": "Arizona",
6318
- "AR": "Arkansas",
6319
- "CA": "California",
6320
- "CO": "Colorado",
6321
- "CT": "Connecticut",
6322
- "DE": "Delaware",
6323
- "FL": "Florida",
6324
- "GA": "Georgia",
6325
- "HI": "Hawaii",
6326
- "ID": "Idaho",
6327
- "IL": "Illinois",
6328
- "IN": "Indiana",
6329
- "IA": "Iowa",
6330
- "KS": "Kansas",
6331
- "KY": "Kentucky",
6332
- "LA": "Louisiana",
6333
- "ME": "Maine",
6334
- "MD": "Maryland",
6335
- "MA": "Massachusetts",
6336
- "MI": "Michigan",
6337
- "MN": "Minnesota",
6338
- "MS": "Mississippi",
6339
- "MO": "Missouri",
6340
- "MT": "Montana",
6341
- "NE": "Nebraska",
6342
- "NV": "Nevada",
6343
- "NH": "New Hampshire",
6344
- "NJ": "New Jersey",
6345
- "NM": "New Mexico",
6346
- "NY": "New York",
6347
- "NC": "North Carolina",
6348
- "ND": "North Dakota",
6349
- "OH": "Ohio",
6350
- "OK": "Oklahoma",
6351
- "OR": "Oregon",
6352
- "PA": "Pennsylvania",
6353
- "RI": "Rhode Island",
6354
- "SC": "South Carolina",
6355
- "SD": "South Dakota",
6356
- "TN": "Tennessee",
6357
- "TX": "Texas",
6358
- "UT": "Utah",
6359
- "VT": "Vermont",
6360
- "VA": "Virginia",
6361
- "WA": "Washington",
6362
- "WV": "West Virginia",
6363
- "WI": "Wisconsin",
6364
- "WY": "Wyoming",
6365
- "DC": "District of Columbia"
6238
+ // src/@modules/@eas/eas.getCleanDescription.ts
6239
+ var getCleanDescription = (message) => {
6240
+ const patches = [
6241
+ { regex: /\.{3,}/g, replacement: ". " },
6242
+ { regex: /\bUTC\b/g, replacement: "Coordinated Universal Time" },
6243
+ { regex: /\bGMT\b/g, replacement: "Greenwich Mean Time" },
6244
+ { regex: /\bEST\b(?!\w)/g, replacement: "Eastern Standard Time" },
6245
+ { regex: /\bEDT\b(?!\w)/g, replacement: "Eastern Daylight Time" },
6246
+ { regex: /\bCST\b(?!\w)/g, replacement: "Central Standard Time" },
6247
+ { regex: /\bCDT\b(?!\w)/g, replacement: "Central Daylight Time" },
6248
+ { regex: /\bMST\b(?!\w)/g, replacement: "Mountain Standard Time" },
6249
+ { regex: /\bMDT\b(?!\w)/g, replacement: "Mountain Daylight Time" },
6250
+ { regex: /\bPST\b(?!\w)/g, replacement: "Pacific Standard Time" },
6251
+ { regex: /\bPDT\b(?!\w)/g, replacement: "Pacific Daylight Time" },
6252
+ { regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
6253
+ { regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
6254
+ { regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
6255
+ { regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
6256
+ { regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
6257
+ { regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
6258
+ { regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
6259
+ { regex: /\bkt\b(?!\w)/g, replacement: "knots" },
6260
+ { regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
6261
+ { regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
6262
+ { regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
6263
+ { regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
6264
+ { regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
6265
+ { regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
6266
+ { regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
6267
+ { regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
6268
+ { regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
6269
+ { regex: /\bin.\b(?!\w)/g, replacement: "inches" },
6270
+ { regex: /\bft\b(?!\w)/g, replacement: "feet" },
6271
+ { regex: /\bmi\b(?!\w)/g, replacement: "miles" },
6272
+ { regex: /\bhr\b(?!\w)/g, replacement: "hour" },
6273
+ { regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
6274
+ { regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
6275
+ { regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
6276
+ { regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
6277
+ { regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
6278
+ { regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
6279
+ { regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
6280
+ { regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
6281
+ { regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
6282
+ { regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
6283
+ { regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
6284
+ { regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
6285
+ { regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
6286
+ ];
6287
+ const hours = {
6288
+ 0: "twelve",
6289
+ 1: "one",
6290
+ 2: "two",
6291
+ 3: "three",
6292
+ 4: "four",
6293
+ 5: "five",
6294
+ 6: "six",
6295
+ 7: "seven",
6296
+ 8: "eight",
6297
+ 9: "nine",
6298
+ 10: "ten",
6299
+ 11: "eleven",
6300
+ 12: "twelve"
6301
+ };
6302
+ const minWord = (m) => m === 0 ? "o'clock" : m < 10 ? `oh ${m}` : `${m}`;
6303
+ const fmt = (h, m, ap) => `${hours[h % 12]} ${minWord(m)} ${ap}`;
6304
+ for (const { regex, replacement } of patches) {
6305
+ message = message.replace(regex, replacement);
6306
+ }
6307
+ return message.replace(/'/g, "''").replace(/\b(\d{1,2}):(\d{2})\s*(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(\d{2})\s+(AM|PM)\b/gi, (_, h, m, ap) => fmt(+h, +m, ap.toUpperCase())).replace(/\b(\d{2})(\d{2})\s+(AM|PM)\b/gi, (_, hh, mm, ap) => fmt(+hh, +mm, ap.toUpperCase())).replace(/\b(\d{1,2})\s+(AM|PM)\b/gi, (_, h, ap) => fmt(+h, 0, ap.toUpperCase())).replace(/\*+/g, " ").replace(/-/g, " ").replace(/\n/g, " ").trim();
6366
6308
  };
6367
6309
 
6368
- // src/@building/building.attachments.ts
6369
- var getEventAttachments = (event) => {
6370
- var _a, _b, _c, _d, _e, _f, _g;
6371
- let attachments = [];
6372
- const issuanceTime = getLatestIssuance();
6373
- const spcNumber = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.discussion_parameters) == null ? void 0 : _b.discussion_number;
6374
- const watchNumber = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.watch_parameters) == null ? void 0 : _d.watch_number;
6375
- const locations = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.locations_array;
6376
- const events = [
6377
- { target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${issuanceTime}.png` },
6378
- { target: "Day 2", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
6379
- { target: "Day 3", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
6380
- { target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
6381
- { target: "Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6382
- { target: "PDS Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6383
- { target: "Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6384
- { target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
6385
- ];
6386
- if (events.find((e) => e.target === event.properties.event)) {
6387
- attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target === event.properties.event).attachment });
6310
+ // src/@modules/@eas/eas.setEasTone.ts
6311
+ var import_path2 = require("path");
6312
+ var import_fs2 = require("fs");
6313
+ var import_child_process2 = require("child_process");
6314
+ var import_os2 = require("os");
6315
+ var setEasTone = (options) => __async(null, null, function* () {
6316
+ var _a;
6317
+ const tick = performance.now();
6318
+ const settings = bootstrap.settings;
6319
+ const directory = settings.GlobalSettings.ArchiveSettings.EasDirectory;
6320
+ const prefix = settings.GlobalSettings.ArchiveSettings.EasToneout;
6321
+ let message = options.message;
6322
+ let header = options.header;
6323
+ let title = ((_a = options.title) != null ? _a : `${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}`).replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
6324
+ if (!message || !header) {
6325
+ setWarning({
6326
+ title: `EAS`,
6327
+ message: `Message and header are required to generate an EAS tone.`
6328
+ });
6329
+ return null;
6388
6330
  }
6389
- for (const location of locations) {
6390
- if (dict_expressions.location.test(location)) {
6391
- const lines = [`Northern`, `Southern`, `Eastern`, `Western`, `Inland`, `Costal`, `County`];
6392
- const county = (_f = location == null ? void 0 : location.split(",")[0]) == null ? void 0 : _f.trim().replace(new RegExp(`^(${lines.join("|")}) `), "");
6393
- const state = dict_states[(_g = location == null ? void 0 : location.split(",")[1]) == null ? void 0 : _g.trim()];
6394
- const feeds = bootstrap.database.prepare(`SELECT * FROM broadcastify WHERE state = ? AND county = ?`).all(state, county).sort((a, b) => {
6395
- const typeOrder = ["Other", "Public Safety"];
6396
- const indexA = typeOrder.indexOf(a.type);
6397
- const indexB = typeOrder.indexOf(b.type);
6398
- return indexA - indexB;
6399
- });
6400
- const tags = bootstrap.settings.BroadcastifySettings.BroadcastifyTags;
6401
- const filtered = feeds.filter((feed) => tags.includes(feed.type));
6402
- if (filtered.length > 0) {
6403
- filtered.map((filtered2) => {
6404
- if (!attachments.some((a) => a.link === filtered2.link)) {
6405
- attachments.push({ name: `${filtered2.type}: ${filtered2.feed}`, link: filtered2.link });
6331
+ let buffTTS;
6332
+ let buffRadio;
6333
+ let buffFull = [];
6334
+ if (!(0, import_fs2.existsSync)(directory)) {
6335
+ (0, import_fs2.mkdirSync)(directory, { recursive: true });
6336
+ }
6337
+ if (!(0, import_fs2.existsSync)((0, import_path2.join)(directory, `/tts`))) {
6338
+ (0, import_fs2.mkdirSync)((0, import_path2.join)(directory, `/tts`), { recursive: true });
6339
+ }
6340
+ if (!(0, import_fs2.existsSync)((0, import_path2.join)(directory, `/encoded`))) {
6341
+ (0, import_fs2.mkdirSync)((0, import_path2.join)(directory, `/encoded`), { recursive: true });
6342
+ }
6343
+ const tmpTTS = (0, import_path2.join)(directory, `/tts/${title}.wav`);
6344
+ const outTTS = (0, import_path2.join)(directory, `/encoded/${title}.wav`);
6345
+ const vPlatform = (0, import_os2.platform)();
6346
+ if (vPlatform === "darwin") {
6347
+ setWarning({
6348
+ title: `EAS`,
6349
+ message: `EAS tone generation is not supported on macOS.`
6350
+ });
6351
+ return null;
6352
+ }
6353
+ yield new Promise((resolve6, reject) => {
6354
+ const tMsg = getCleanDescription(message);
6355
+ getTTS(tMsg, tmpTTS).then(() => {
6356
+ resolve6();
6357
+ });
6358
+ });
6359
+ if (!(0, import_fs2.existsSync)(tmpTTS)) {
6360
+ return null;
6361
+ }
6362
+ buffTTS = (0, import_fs2.readFileSync)(tmpTTS);
6363
+ const vWav = getWavPCM16(buffTTS);
6364
+ const vSamples = getSampledPCM16(vWav.samples, vWav.sampleRate, 8e3);
6365
+ const vRadio = setRadioEffect(vSamples, 8e3);
6366
+ if ((0, import_fs2.existsSync)(prefix)) {
6367
+ let tBuffer = (0, import_fs2.readFileSync)(prefix);
6368
+ let tWav = getWavPCM16(tBuffer);
6369
+ if (tWav == null) {
6370
+ try {
6371
+ const converted = (0, import_path2.join)(directory, `/tts/${title}.converted.wav`);
6372
+ (0, import_child_process2.execSync)(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
6373
+ if ((0, import_fs2.existsSync)(converted)) {
6374
+ tBuffer = (0, import_fs2.readFileSync)(converted);
6375
+ tWav = getWavPCM16(tBuffer);
6376
+ try {
6377
+ (0, import_fs2.unlinkSync)(converted);
6378
+ } catch (e) {
6406
6379
  }
6407
- });
6380
+ }
6381
+ } catch (e) {
6408
6382
  }
6409
6383
  }
6384
+ if (tWav == null) {
6385
+ setWarning({ title: `EAS`, 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.` });
6386
+ return null;
6387
+ }
6388
+ const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
6389
+ buffRadio = setRadioEffect(tSamples, 8e3);
6410
6390
  }
6411
- return attachments;
6391
+ buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
6392
+ buffFull.push(
6393
+ setSameHeader(header, 3, 8e3, {
6394
+ preMarkSec: 1.1,
6395
+ gapSec: 0.5
6396
+ }),
6397
+ new Int16Array(Math.floor(0.5 * 8e3)),
6398
+ setAttentionTone(8, 8e3),
6399
+ new Int16Array(Math.floor(0.5 * 8e3)),
6400
+ vRadio
6401
+ );
6402
+ for (let i = 0; i < 3; i++) {
6403
+ buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
6404
+ buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
6405
+ }
6406
+ const aSamples = getMergedPCM16(buffFull);
6407
+ const aFinal = setNoise(aSamples, 2e-3);
6408
+ const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
6409
+ (0, import_fs2.writeFileSync)(outTTS, aBuffer);
6410
+ try {
6411
+ (0, import_fs2.unlinkSync)(tmpTTS);
6412
+ } catch (e) {
6413
+ }
6414
+ setDebug({ title: `@eas.setEasTone`, message: `EAS tone generation took ${performance.now() - tick} ms` });
6415
+ return outTTS;
6416
+ });
6417
+
6418
+ // src/@parsers/@text/text.getEmbed.ts
6419
+ var getEmebed = (event) => {
6420
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na;
6421
+ const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
6422
+ const isStatement = event.properties.status_metadata.is_statement;
6423
+ const isExpired = event.properties.status_metadata.is_expired;
6424
+ return [
6425
+ line(`**Locations:**`, (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.locations) == null ? void 0 : _b.slice(0, 100)),
6426
+ line(`**Issued:**`, `<t:${Math.floor(new Date(event.properties.issued).getTime() / 1e3)}:R>`, !isExpired),
6427
+ line(`**Expires:**`, `<t:${Math.floor(new Date(event.properties.expires).getTime() / 1e3)}:R>`, !isStatement),
6428
+ line(`**Damage Threat:**`, (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat, !isExpired),
6429
+ line(`**Flood Threat:**`, (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.flood_threat, !isExpired),
6430
+ line(`**Tornado Threat:**`, (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.parameters) == null ? void 0 : _h.tornado_threat, !isExpired),
6431
+ line(`**Estimated Wind Gusts:**`, `${(_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.parameters) == null ? void 0 : _j.estimated_wind_gusts} ${((_l = (_k = event == null ? void 0 : event.properties) == null ? void 0 : _k.parameters) == null ? void 0 : _l.wind_threat) ? ` (${(_n = (_m = event == null ? void 0 : event.properties) == null ? void 0 : _m.parameters) == null ? void 0 : _n.wind_threat})` : ""}`, !isExpired && ((_p = (_o = event == null ? void 0 : event.properties) == null ? void 0 : _o.parameters) == null ? void 0 : _p.estimated_wind_gusts) != null),
6432
+ line(`**Estimated Hail Size:**`, `${(_r = (_q = event == null ? void 0 : event.properties) == null ? void 0 : _q.parameters) == null ? void 0 : _r.estimated_hail_size} ${((_t = (_s = event == null ? void 0 : event.properties) == null ? void 0 : _s.parameters) == null ? void 0 : _t.hail_threat) ? ` (${(_v = (_u = event == null ? void 0 : event.properties) == null ? void 0 : _u.parameters) == null ? void 0 : _v.hail_threat})` : ""}`, !isExpired && ((_x = (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.parameters) == null ? void 0 : _x.estimated_hail_size) != null),
6433
+ line(`**Discussion:**`, (_z = (_y = event == null ? void 0 : event.properties) == null ? void 0 : _y.discussion_parameters) == null ? void 0 : _z.discussion_number, !isExpired),
6434
+ line(`**Concern:**`, (_B = (_A = event == null ? void 0 : event.properties) == null ? void 0 : _A.discussion_parameters) == null ? void 0 : _B.discussion_concerning, !isExpired),
6435
+ line(`**SPC Max Tornado Threat:**`, (_D = (_C = event == null ? void 0 : event.properties) == null ? void 0 : _C.discussion_parameters) == null ? void 0 : _D.discussion_max_tornado, !isExpired),
6436
+ line(`**SPC Max Hail Threat:**`, (_F = (_E = event == null ? void 0 : event.properties) == null ? void 0 : _E.discussion_parameters) == null ? void 0 : _F.discussion_max_hail, !isExpired),
6437
+ line(`**SPC Max Wind Threat:**`, (_H = (_G = event == null ? void 0 : event.properties) == null ? void 0 : _G.discussion_parameters) == null ? void 0 : _H.discussion_max_wind, !isExpired),
6438
+ line(`**SPC Watch Issuance Probability:**`, ((_J = (_I = event == null ? void 0 : event.properties) == null ? void 0 : _I.discussion_parameters) == null ? void 0 : _J.discussion_watch_issuance) ? `${(_L = (_K = event == null ? void 0 : event.properties) == null ? void 0 : _K.discussion_parameters) == null ? void 0 : _L.discussion_watch_issuance}%` : null, !isExpired),
6439
+ line(`**Watch Number:**`, (_N = (_M = event == null ? void 0 : event.properties) == null ? void 0 : _M.watch_parameters) == null ? void 0 : _N.watch_number, !isExpired),
6440
+ line(`**Strong Tornadoes Probability:**`, ((_P = (_O = event == null ? void 0 : event.properties) == null ? void 0 : _O.watch_parameters) == null ? void 0 : _P.strong_tornadoes_probability) ? `${(_R = (_Q = event == null ? void 0 : event.properties) == null ? void 0 : _Q.watch_parameters) == null ? void 0 : _R.strong_tornadoes_probability}%` : null, !isExpired),
6441
+ line(`**Additional Tornadoes Probability:**`, ((_T = (_S = event == null ? void 0 : event.properties) == null ? void 0 : _S.watch_parameters) == null ? void 0 : _T.additional_tornadoes_probability) ? `${(_V = (_U = event == null ? void 0 : event.properties) == null ? void 0 : _U.watch_parameters) == null ? void 0 : _V.additional_tornadoes_probability}%` : null, !isExpired),
6442
+ line(`**Combined Hail/Wind Probability:**`, ((_X = (_W = event == null ? void 0 : event.properties) == null ? void 0 : _W.watch_parameters) == null ? void 0 : _X.combined_hail_wind_probability) ? `${(_Z = (_Y = event == null ? void 0 : event.properties) == null ? void 0 : _Y.watch_parameters) == null ? void 0 : _Z.combined_hail_wind_probability}%` : null, !isExpired),
6443
+ line(`**Severe Hail Probability:**`, ((_$ = (__ = event == null ? void 0 : event.properties) == null ? void 0 : __.watch_parameters) == null ? void 0 : _$.severe_hail_probability) ? `${(_ba = (_aa = event == null ? void 0 : event.properties) == null ? void 0 : _aa.watch_parameters) == null ? void 0 : _ba.severe_hail_probability}%` : null, !isExpired),
6444
+ line(`**Hail >2in Probability:**`, ((_da = (_ca = event == null ? void 0 : event.properties) == null ? void 0 : _ca.watch_parameters) == null ? void 0 : _da.hail_2in_probability) ? `${(_fa = (_ea = event == null ? void 0 : event.properties) == null ? void 0 : _ea.watch_parameters) == null ? void 0 : _fa.hail_2in_probability}%` : null, !isExpired),
6445
+ line(`**Max Hail Inches:**`, (_ha = (_ga = event == null ? void 0 : event.properties) == null ? void 0 : _ga.watch_parameters) == null ? void 0 : _ha.max_hail_in, !isExpired),
6446
+ line(`**Severe Wind Probability:**`, ((_ja = (_ia = event == null ? void 0 : event.properties) == null ? void 0 : _ia.watch_parameters) == null ? void 0 : _ja.severe_wind_probability) ? `${(_la = (_ka = event == null ? void 0 : event.properties) == null ? void 0 : _ka.watch_parameters) == null ? void 0 : _la.severe_wind_probability}%` : null, !isExpired),
6447
+ line(`**Max Surface Wind:**`, (_na = (_ma = event == null ? void 0 : event.properties) == null ? void 0 : _ma.watch_parameters) == null ? void 0 : _na.max_wind_surface, !isExpired),
6448
+ line(`**Max Tops (x100 feet):**`, (_pa = (_oa = event == null ? void 0 : event.properties) == null ? void 0 : _oa.watch_parameters) == null ? void 0 : _pa.max_tops_x100feet, !isExpired),
6449
+ line(`**Tags:**`, ((_sa = (_ra = (_qa = event == null ? void 0 : event.properties) == null ? void 0 : _qa.parameters) == null ? void 0 : _ra.tags) == null ? void 0 : _sa.length) > 0 ? (_ua = (_ta = event == null ? void 0 : event.properties) == null ? void 0 : _ta.parameters) == null ? void 0 : _ua.tags.join(", ") : null, !isExpired),
6450
+ line(`**Sender:**`, ((_xa = (_wa = (_va = event == null ? void 0 : event.properties) == null ? void 0 : _va.geocode) == null ? void 0 : _wa.office) == null ? void 0 : _xa.name) ? `${(_Aa = (_za = (_ya = event == null ? void 0 : event.properties) == null ? void 0 : _ya.geocode) == null ? void 0 : _za.office) == null ? void 0 : _Aa.name} (${(_Da = (_Ca = (_Ba = event == null ? void 0 : event.properties) == null ? void 0 : _Ba.geocode) == null ? void 0 : _Ca.office) == null ? void 0 : _Da.office})` : (_Ga = (_Fa = (_Ea = event == null ? void 0 : event.properties) == null ? void 0 : _Ea.geocode) == null ? void 0 : _Fa.office) == null ? void 0 : _Ga.office),
6451
+ line(`**Tracking:**`, (_Ia = (_Ha = event == null ? void 0 : event.properties) == null ? void 0 : _Ha.metadata) == null ? void 0 : _Ia.tracking),
6452
+ line(`**Logs:**`, ((_La = (_Ka = (_Ja = event == null ? void 0 : event.properties) == null ? void 0 : _Ja.metadata) == null ? void 0 : _Ka.history) == null ? void 0 : _La.length) > 0 ? (_Na = (_Ma = event == null ? void 0 : event.properties) == null ? void 0 : _Ma.metadata) == null ? void 0 : _Na.history.length : null)
6453
+ ].filter(Boolean).join("\n");
6412
6454
  };
6413
6455
 
6414
- // src/@building/building.validate.ts
6415
- var validateEvents = (events) => __async(null, null, function* () {
6416
- var _a;
6417
- if (events.length === 0) return;
6418
- const configurations = bootstrap.settings;
6419
- const sets = {};
6420
- const bools = {};
6421
- const megered = __spreadValues(__spreadValues({}, configurations.GlobalSettings), configurations.GlobalSettings.EventFiltering);
6422
- for (const key in megered) {
6423
- const setting = megered[key];
6424
- if (Array.isArray(setting)) {
6425
- sets[key] = new Set(setting.map((item) => item.toLowerCase()));
6426
- }
6427
- if (typeof setting === "boolean") {
6428
- bools[key] = setting;
6429
- }
6456
+ // src/@modules/@utilities/utilities.createHttp.ts
6457
+ var createHttp = (options) => __async(null, null, function* () {
6458
+ var _a, _b, _c, _d;
6459
+ const requestOptions = {
6460
+ method: (_a = options.method) != null ? _a : "GET",
6461
+ headers: (_b = options.headers) != null ? _b : {
6462
+ "User-Agent": "AtmosphericX",
6463
+ "Accept": "application/geo+json, text/plain, */*; q=0.9",
6464
+ "Accept-Language": "en-US,en;q=0.9"
6465
+ },
6466
+ signal: AbortSignal.timeout((_c = options.timeout) != null ? _c : 1e4),
6467
+ redirect: "follow"
6468
+ };
6469
+ const returnHttp = function(error, status, message) {
6470
+ return { error, options: requestOptions, status, message };
6471
+ };
6472
+ if (options == null ? void 0 : options.formData) {
6473
+ requestOptions.body = options.formData;
6474
+ } else if ((options == null ? void 0 : options.body) != void 0) {
6475
+ requestOptions.body = options.body instanceof FormData ? options.body : typeof options.body === "string" ? options.body : JSON.stringify(options.body);
6430
6476
  }
6431
- const filterd = events.filter((event) => {
6432
- var _a2, _b, _c, _d, _e;
6433
- const define2 = getEventSignature(event);
6434
- const properties2 = define2.properties;
6435
- const zones = properties2.geocode.ugc;
6436
- const icao = properties2.geocode.office.office;
6437
- const enhancedEventName = properties2.event = getEventEnhancedName(event);
6438
- const filteredProperties = JSON.parse(JSON.stringify(properties2));
6439
- if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
6440
- delete filteredProperties.metadata.ms;
6441
- }
6442
- filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
6443
- properties2.metadata.hash = (0, import_crypto.createHash)("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
6444
- properties2.metadata.attachments = getEventAttachments(event);
6445
- setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
6446
- if (properties2.status_metadata.is_test) {
6447
- setEventEmit({ event: `onTestProduct`, metadata: define2 });
6448
- if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
6449
- }
6450
- if (properties2.status_metadata.is_expired) {
6451
- setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
6452
- rmEvent(define2);
6453
- return false;
6477
+ try {
6478
+ const response2 = yield fetch(
6479
+ (_d = options == null ? void 0 : options.url) != null ? _d : `https://api.weather.gov/alerts/active`,
6480
+ requestOptions
6481
+ );
6482
+ const body = yield response2.text();
6483
+ if (!response2.ok) {
6484
+ return returnHttp(true, response2.status, `HTTP Status Code ${response2.status} (${response2.statusText})`);
6454
6485
  }
6455
- if (((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) && properties2.metadata.source != `events.api`) {
6456
- const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
6457
- setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
6458
- if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
6459
- return false;
6460
- }
6461
- if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
6462
- return false;
6463
- }
6486
+ return returnHttp(false, response2.status, body);
6487
+ } catch (error) {
6488
+ return returnHttp(true, 500, `Internal Server Error: ${error}`);
6489
+ }
6490
+ });
6491
+
6492
+ // src/@modules/@utilities/utilities.getMatched.ts
6493
+ var getMatched = (strings, string) => {
6494
+ const isMatched = strings.some((pattern) => {
6495
+ if (!pattern) return false;
6496
+ const lowerP = pattern.toLowerCase();
6497
+ const lowerS = string.toLowerCase();
6498
+ if (lowerP === "*" || lowerP === lowerS) return true;
6499
+ if (lowerP.includes("*")) {
6500
+ const regex = "^" + lowerP.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
6501
+ return new RegExp(regex).test(lowerS);
6464
6502
  }
6465
- for (const key in sets) {
6466
- const setting = sets[key];
6467
- if (key === "ListeningEvents" && setting.size > 0 && !setting.has(define2.properties.event.toLowerCase())) {
6468
- setEventEmit({
6469
- event: `onFilteredEvent`,
6470
- metadata: define2
6471
- });
6472
- return false;
6473
- }
6474
- if (key === "IgnoredEvents" && setting.size > 0 && setting.has(define2.properties.event.toLowerCase())) {
6475
- setEventEmit({
6476
- event: `onIgnoredEvent`,
6477
- metadata: define2
6478
- });
6479
- return false;
6480
- }
6481
- if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
6482
- setEventEmit({
6483
- event: `onFilteredICAO`,
6484
- metadata: define2
6503
+ return false;
6504
+ });
6505
+ return isMatched;
6506
+ };
6507
+
6508
+ // src/@manager/manager.updateListener.ts
6509
+ var import_fs3 = require("fs");
6510
+ var updateListener = (event) => __async(null, null, function* () {
6511
+ var _a, _b, _c, _d, _e, _f;
6512
+ const tick = performance.now();
6513
+ const settings = bootstrap.settings;
6514
+ const listeners2 = settings.ListenerSettings;
6515
+ const properties2 = event.properties;
6516
+ const metadata = {
6517
+ file: null,
6518
+ eas: null,
6519
+ json: null,
6520
+ name: properties2.event,
6521
+ status: properties2.status,
6522
+ description: properties2.description,
6523
+ tracking: properties2.metadata.tracking,
6524
+ header: properties2.metadata.header,
6525
+ raw: properties2.metadata.raw,
6526
+ expired: properties2.status_metadata.is_expired,
6527
+ attachments: properties2.metadata.attachments
6528
+ };
6529
+ for (const listener2 of listeners2) {
6530
+ const events = listener2 == null ? void 0 : listener2.events;
6531
+ const webhook = listener2 == null ? void 0 : listener2.webhook;
6532
+ const uploads = listener2 == null ? void 0 : listener2.uploads;
6533
+ const isMatched = getMatched(events != null ? events : [], metadata.name);
6534
+ if ((events == null ? void 0 : events.length) == 0 || isMatched) {
6535
+ if (uploads == null ? void 0 : uploads.eas) {
6536
+ metadata.eas = yield setEasTone({
6537
+ title: `${metadata.name}_${metadata.status}_${metadata.tracking}`,
6538
+ message: metadata.description,
6539
+ header: metadata.header
6485
6540
  });
6486
- return false;
6487
6541
  }
6488
- if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
6489
- setEventEmit({
6490
- event: `onIgnoredICAO`,
6491
- metadata: define2
6492
- });
6493
- return false;
6542
+ if (uploads == null ? void 0 : uploads.file) {
6543
+ const fDestination = settings.GlobalSettings.ArchiveSettings.TextDirectory;
6544
+ if (fDestination) {
6545
+ const file = `${fDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.txt`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
6546
+ if (!(0, import_fs3.existsSync)(fDestination)) {
6547
+ (0, import_fs3.mkdirSync)(fDestination, { recursive: true });
6548
+ }
6549
+ if ((0, import_fs3.existsSync)(file)) {
6550
+ (0, import_fs3.appendFileSync)(file, metadata.raw);
6551
+ } else {
6552
+ (0, import_fs3.writeFileSync)(file, metadata.raw);
6553
+ }
6554
+ }
6555
+ metadata.file = metadata.raw;
6494
6556
  }
6495
- if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
6496
- setEventEmit({
6497
- event: `onFilteredUGC`,
6498
- metadata: define2
6499
- });
6500
- return false;
6557
+ if (uploads == null ? void 0 : uploads.event) {
6558
+ const eDestination = settings.GlobalSettings.ArchiveSettings.EventDirectory;
6559
+ if (eDestination) {
6560
+ const file = `${eDestination}/${metadata.name}_${metadata.status}_${metadata.tracking}.json`.replace(/[\\:*?"<>|]/g, "_").replace(/\s+/g, " ").trim();
6561
+ if (!(0, import_fs3.existsSync)(eDestination)) {
6562
+ (0, import_fs3.mkdirSync)(eDestination, { recursive: true });
6563
+ }
6564
+ (0, import_fs3.writeFileSync)(file, JSON.stringify(getCleanedEvent(event), null, 2));
6565
+ }
6566
+ metadata.json = JSON.stringify(getCleanedEvent(event), null, 2);
6501
6567
  }
6502
- if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
6503
- setEventEmit({
6504
- event: `onFilteredState`,
6505
- metadata: define2
6568
+ if ((webhook == null ? void 0 : webhook.enabled) && (webhook == null ? void 0 : webhook.destination)) {
6569
+ const isRatelimited = setTimeoutAction({ identifier: webhook.destination, interval: ((_a = webhook.ratelimit) != null ? _a : 2) * 2, max: (_b = webhook.ratelimit) != null ? _b : 2, addTime: true });
6570
+ const form = new FormData();
6571
+ const embed = {
6572
+ title: `${metadata.name} (${metadata.status})`,
6573
+ description: getEmebed(event),
6574
+ fields: [],
6575
+ color: 16711680,
6576
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
6577
+ footer: { text: (_c = webhook.title) != null ? _c : `AtmosphericX` }
6578
+ };
6579
+ if (isRatelimited.limited) {
6580
+ return;
6581
+ }
6582
+ if (metadata.description && !metadata.expired) {
6583
+ if (metadata.description.length > 900) {
6584
+ metadata.description = metadata.description.substring(0, 900) + "\n\n[Message truncated due to length]";
6585
+ }
6586
+ embed.fields.push({
6587
+ name: "Description",
6588
+ value: metadata.description ? "```\n" + metadata.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n") + "\n```" : ""
6589
+ });
6590
+ }
6591
+ if (((_d = metadata.attachments) == null ? void 0 : _d.length) > 0) {
6592
+ metadata.attachments = metadata.attachments.slice(0, 5);
6593
+ embed.fields.push({
6594
+ name: "Attachments",
6595
+ value: metadata.attachments.map((attachment) => `- [${attachment.name.length > 45 ? attachment.name.substring(0, 45) + "..." : attachment.name}](${attachment.link})`).join("\n")
6596
+ });
6597
+ }
6598
+ if (uploads == null ? void 0 : uploads.file) {
6599
+ form.append("fUpload", new Blob([Buffer.from(metadata.file)], { type: "application/text" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`);
6600
+ }
6601
+ if (uploads == null ? void 0 : uploads.event) {
6602
+ form.append("fUpload2", new Blob([Buffer.from(metadata.json)], { type: "application/json" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.json`);
6603
+ }
6604
+ if (uploads == null ? void 0 : uploads.eas) {
6605
+ if (metadata.eas) {
6606
+ const file = (0, import_fs3.readFileSync)(metadata.eas);
6607
+ form.append("fEas", new Blob([Buffer.from(file)], { type: "audio/mpeg" }), `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`);
6608
+ }
6609
+ }
6610
+ form.append("payload_json", JSON.stringify({
6611
+ username: (_e = webhook.title) != null ? _e : "AtmosphericX",
6612
+ content: (_f = webhook.message) != null ? _f : "",
6613
+ embeds: [embed]
6614
+ }));
6615
+ yield createHttp({
6616
+ url: webhook.destination,
6617
+ timeout: 15e3,
6618
+ method: `POST`,
6619
+ body: form
6506
6620
  });
6507
- return false;
6508
6621
  }
6509
6622
  }
6510
- return true;
6511
- });
6512
- if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
6513
- for (const event of filterd) {
6514
- event.geometry = yield getEventGeometry(event);
6515
- }
6516
- }
6517
- if (filterd.length > 0) {
6518
- for (const event of filterd) {
6519
- yield mkEvent(event);
6520
- }
6521
6623
  }
6522
- yield updateNode();
6523
- setEventEmit({
6524
- event: `onEventCache`,
6525
- metadata: bootstrap.cache.events,
6526
- limited: true
6527
- });
6624
+ setDebug({ title: `@manager.updateListener`, message: `Listener took ${performance.now() - tick} ms` });
6528
6625
  });
6529
6626
 
6530
- // src/@events/events.text.ts
6531
- var text = (stanza) => __async(null, null, function* () {
6532
- var _a, _b, _c;
6533
- let processed = [];
6534
- const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
6535
- if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
6536
- for (const message of getMessages) {
6537
- const tick = performance.now();
6538
- const attributes = stanza == null ? void 0 : stanza.attributes;
6539
- const props = properties({ message, attributes });
6540
- const header = getEventHeader({ properties: props, getType: stanza.getType });
6541
- const issued = new Date(attributes.issue);
6542
- const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
6543
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
6544
- let isStatement = false;
6545
- if (!event) {
6546
- event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
6547
- isStatement = true;
6548
- }
6549
- processed.push({
6550
- type: `Feature`,
6551
- geometry: {
6552
- type: `Point`,
6553
- coordinates: []
6554
- },
6555
- properties: __spreadProps(__spreadValues({
6556
- event,
6557
- parent: event,
6558
- status: isStatement ? `Statement` : `Issued`,
6559
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6560
- expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
6561
- }, props), {
6562
- metadata: {
6563
- ms: performance.now() - tick,
6564
- source: `events.text`,
6565
- tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
6566
- header,
6567
- vtec: null,
6568
- hvtec: null,
6569
- raw: message,
6570
- history: [
6571
- {
6572
- description: props.description,
6573
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6574
- status: `Issued`
6575
- }
6576
- ]
6577
- }
6578
- })
6579
- });
6627
+ // src/@modules/@utilities/utilities.getShapeNearestPoint.ts
6628
+ var getShapeNearestPoint = (coordinates, point) => {
6629
+ if (!coordinates || !point) {
6630
+ return { proximity: false, point: [0, 0], distance: null };
6580
6631
  }
6581
- validateEvents(processed);
6582
- });
6583
-
6584
- // src/@parsers/@ugc/ugc.header.ts
6585
- var getUGCHeader = (message) => {
6586
- const start = message.search(dict_expressions.ugc1);
6587
- const sub = message.substring(start);
6588
- const end = sub.search(dict_expressions.ugc2);
6589
- const fin = sub.substring(0, end).replace(/\s+/g, "").slice(0, -1);
6590
- return fin != null ? fin : null;
6591
- };
6592
-
6593
- // src/@parsers/@ugc/ugc.zones.ts
6594
- var getZones = (header) => {
6595
- const splits = header.split("-");
6596
- const zones = [];
6597
- let state = splits[0].substring(0, 2);
6598
- const format = splits[0].substring(2, 3);
6599
- for (const part of splits) {
6600
- if (/^[A-Z]/.test(part)) {
6601
- state = part.substring(0, 2);
6602
- if (part.includes(">")) {
6603
- const [start, end] = part.split(">");
6604
- const startNum = parseInt(start.substring(3), 10);
6605
- const endNum = parseInt(end, 10);
6606
- for (let j2 = startNum; j2 <= endNum; j2++) {
6607
- zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
6632
+ const normalize = (coords) => {
6633
+ if (!Array.isArray(coords)) return [];
6634
+ if (typeof coords[0] === "number" && typeof coords[1] === "number") return [];
6635
+ if (Array.isArray(coords[0]) && typeof coords[0][0] === "number") {
6636
+ return [[coords]];
6637
+ }
6638
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === "number") {
6639
+ return [coords];
6640
+ }
6641
+ if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === "number") {
6642
+ return coords;
6643
+ }
6644
+ return [];
6645
+ };
6646
+ const polys = normalize(coordinates);
6647
+ if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
6648
+ const lon = point[0];
6649
+ const lat = point[1];
6650
+ const pointInRing = (pt, ring) => {
6651
+ let x = pt[0], y = pt[1];
6652
+ let inside = false;
6653
+ for (let i = 0, j2 = ring.length - 1; i < ring.length; j2 = i++) {
6654
+ const xi = ring[i][0], yi = ring[i][1];
6655
+ const xj = ring[j2][0], yj = ring[j2][1];
6656
+ const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi;
6657
+ if (intersect) inside = !inside;
6658
+ }
6659
+ return inside;
6660
+ };
6661
+ const toRadians = (deg) => deg * Math.PI / 180;
6662
+ const haversineMiles = (a, b) => {
6663
+ const R = 3958.8;
6664
+ const dLat = toRadians(b[1] - a[1]);
6665
+ const dLon = toRadians(b[0] - a[0]);
6666
+ const lat1 = toRadians(a[1]);
6667
+ const lat2 = toRadians(b[1]);
6668
+ const sinDLat = Math.sin(dLat / 2);
6669
+ const sinDLon = Math.sin(dLon / 2);
6670
+ const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
6671
+ return R * c;
6672
+ };
6673
+ let minDistance = Infinity;
6674
+ let closestPoint = null;
6675
+ for (const poly of polys) {
6676
+ const outer = poly[0];
6677
+ const holes = poly.slice(1);
6678
+ if (pointInRing(point, outer)) {
6679
+ let inHole = false;
6680
+ for (const hole of holes) {
6681
+ if (pointInRing(point, hole)) {
6682
+ inHole = true;
6683
+ break;
6608
6684
  }
6609
- } else {
6610
- zones.push(part);
6611
6685
  }
6612
- continue;
6686
+ if (!inHole) {
6687
+ return { proximity: true, point, distance: 0 };
6688
+ }
6613
6689
  }
6614
- if (part.includes(">")) {
6615
- const [start, end] = part.split(">");
6616
- const startNum = parseInt(start, 10);
6617
- const endNum = parseInt(end, 10);
6618
- for (let j2 = startNum; j2 <= endNum; j2++) {
6619
- zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
6690
+ for (const ring of poly) {
6691
+ for (let i = 0; i < ring.length - 1; i++) {
6692
+ const start = [ring[i][0], ring[i][1]];
6693
+ const end = [ring[i + 1][0], ring[i + 1][1]];
6694
+ const A = lon - start[0];
6695
+ const B = lat - start[1];
6696
+ const C = end[0] - start[0];
6697
+ const D = end[1] - start[1];
6698
+ const lenSq = C * C + D * D;
6699
+ const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
6700
+ const candidate = [start[0] + t * C, start[1] + t * D];
6701
+ const dist = haversineMiles([lon, lat], candidate);
6702
+ if (!isNaN(dist) && dist < minDistance) {
6703
+ minDistance = Number(dist.toFixed(3));
6704
+ closestPoint = candidate;
6705
+ }
6620
6706
  }
6621
- } else {
6622
- zones.push(`${state}${format}${part}`);
6623
6707
  }
6624
6708
  }
6625
- return zones.filter((item) => item !== "");
6626
- };
6627
-
6628
- // src/@parsers/@ugc/ugc.expiry.ts
6629
- var getExpiry = (message) => {
6630
- const match = message.match(/\b(\d{6})-/);
6631
- if (!match) {
6632
- return null;
6709
+ if (!isFinite(minDistance) || closestPoint == null) {
6710
+ return { proximity: false, point: [0, 0], distance: null };
6633
6711
  }
6634
- const date = match == null ? void 0 : match[1];
6635
- const day = parseInt(date == null ? void 0 : date.slice(0, 2), 10);
6636
- const hour = parseInt(date == null ? void 0 : date.slice(2, 4), 10);
6637
- const minute = parseInt(date == null ? void 0 : date.slice(4, 6), 10);
6638
- const now = /* @__PURE__ */ new Date();
6639
- const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
6640
- return expires.toISOString();
6712
+ const distanceMiles = minDistance;
6713
+ const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
6714
+ const distanceMeters = Math.round(distanceKm * 1e3);
6715
+ return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
6641
6716
  };
6642
6717
 
6643
- // src/@parsers/@ugc/ugc.locations.ts
6644
- var getLocations = (zones) => __async(null, null, function* () {
6645
- const sites = Array.from(new Set(zones));
6646
- const placeholders = sites.map(() => "?").join(",");
6647
- const rows = yield bootstrap.database.prepare(`SELECT id, location FROM shapefiles WHERE id IN (${placeholders})`).all(...sites);
6648
- return rows.map((row) => row.location).sort();
6649
- });
6650
-
6651
- // src/@parsers/@ugc/ugc.extract.ts
6652
- var ugcExtract = (message) => __async(null, null, function* () {
6653
- const head = getUGCHeader(message);
6654
- const ugcs = getZones(head);
6655
- const expires = getExpiry(message);
6656
- const areas = yield getLocations(ugcs);
6657
- if (!head || (ugcs == null ? void 0 : ugcs.length) == 0) return;
6718
+ // src/@building/building.polygon.ts
6719
+ var getEventNodes = (event) => __async(null, null, function* () {
6720
+ var _a, _b;
6721
+ const metadata = { nodes: [], proximity: false, filtered: false };
6722
+ const geometry = yield getEventGeometry(event);
6723
+ if (!geometry || !geometry.coordinates) {
6724
+ return { nodes: [], filtered: false, updated: Date.now() };
6725
+ }
6726
+ const nodes = bootstrap.cache.nodes.features;
6727
+ for (const node of nodes) {
6728
+ const [longitude, latitude] = node.geometry.coordinates;
6729
+ const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude]);
6730
+ const miles = (_a = getPoint.distance) != null ? _a : null;
6731
+ const kilometers = Number((miles * 1.609344).toFixed(3));
6732
+ const info = {
6733
+ id: (_b = node.properties) == null ? void 0 : _b.identifier,
6734
+ coordinates: [longitude, latitude],
6735
+ nearest: getPoint.point,
6736
+ miles,
6737
+ kilometers,
6738
+ proximity: getPoint.proximity
6739
+ };
6740
+ metadata.nodes.push(info);
6741
+ if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
6742
+ metadata.proximity = true;
6743
+ info.proximity = true;
6744
+ }
6745
+ }
6658
6746
  return {
6659
- zones: ugcs,
6660
- locations: areas,
6661
- expires
6747
+ nodes: metadata.nodes,
6748
+ filtered: metadata.proximity,
6749
+ updated: Date.now()
6662
6750
  };
6663
6751
  });
6664
6752
 
6665
- // src/@events/events.ugc.ts
6666
- var ugc = (stanza) => __async(null, null, function* () {
6667
- var _a, _b, _c;
6668
- let processed = [];
6669
- const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
6670
- if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
6671
- for (const message of getMessages) {
6672
- const tick = performance.now();
6673
- const attributes = stanza == null ? void 0 : stanza.attributes;
6674
- const ugc2 = yield ugcExtract(message);
6675
- if (ugc2 != null) {
6676
- const props = properties({ message, attributes, ugc: ugc2 });
6677
- const issued = new Date(attributes.issue);
6678
- const expires = new Date(ugc2.expires);
6679
- const header = getEventHeader({ properties: props, getType: stanza.getType });
6680
- let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
6681
- let isStatement = false;
6682
- if (!event) {
6683
- event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
6684
- isStatement = true;
6753
+ // src/@manager/manager.updateNodes.ts
6754
+ var updateNode = (selectedEvent) => __async(null, null, function* () {
6755
+ const events = bootstrap.cache.events.features;
6756
+ const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
6757
+ let total = 0;
6758
+ function update(evt) {
6759
+ return __async(this, null, function* () {
6760
+ var _a, _b, _c;
6761
+ const lastUpdate = (_c = (_b = (_a = evt == null ? void 0 : evt.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.updated) != null ? _c : null;
6762
+ if (lastUpdate != null && Date.now() - lastUpdate < ttl) {
6763
+ return evt;
6685
6764
  }
6686
- processed.push({
6687
- type: `Feature`,
6688
- geometry: {
6689
- type: `Point`,
6690
- coordinates: []
6691
- },
6692
- properties: __spreadProps(__spreadValues({
6693
- event,
6694
- parent: event,
6695
- status: isStatement ? `Statement` : `Issued`,
6696
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6697
- expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
6698
- }, props), {
6699
- metadata: {
6700
- ms: performance.now() - tick,
6701
- source: `events.ugc`,
6702
- tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
6703
- header,
6704
- vtec: null,
6705
- hvtec: null,
6706
- raw: message,
6707
- history: [
6708
- {
6709
- description: props.description,
6710
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6711
- status: `Issued`
6712
- }
6713
- ]
6714
- }
6715
- })
6716
- });
6717
- }
6765
+ const node = yield getEventNodes(evt);
6766
+ if (node.nodes.length > 0) {
6767
+ total++;
6768
+ }
6769
+ evt.properties.metadata.nodes = node.nodes;
6770
+ evt.properties.metadata.filtered_proximity = node.filtered;
6771
+ evt.properties.metadata.updated = node.updated;
6772
+ });
6718
6773
  }
6719
- validateEvents(processed);
6720
- });
6721
-
6722
- // src/@dictionaries/dictionaries.events.ts
6723
- var dict_events = {
6724
- "AF": "Ashfall",
6725
- "AS": "Air Stagnation",
6726
- "BH": "Beach Hazard",
6727
- "BW": "Brisk Wind",
6728
- "BZ": "Blizzard",
6729
- "CF": "Coastal Flood",
6730
- "DF": "Debris Flow",
6731
- "DS": "Dust Storm",
6732
- "EC": "Extreme Cold",
6733
- "EH": "Excessive Heat",
6734
- "XH": "Extreme Heat",
6735
- "EW": "Extreme Wind",
6736
- "FA": "Areal Flood",
6737
- "FF": "Flash Flood",
6738
- "FG": "Dense Fog",
6739
- "FL": "Flood",
6740
- "FR": "Frost",
6741
- "FW": "Fire Weather",
6742
- "FZ": "Freeze",
6743
- "GL": "Gale",
6744
- "HF": "Hurricane Force Wind",
6745
- "HT": "Heat",
6746
- "HU": "Hurricane",
6747
- "HW": "High Wind",
6748
- "HY": "Hydrologic",
6749
- "HZ": "Hard Freeze",
6750
- "IS": "Ice Storm",
6751
- "LE": "Lake Effect Snow",
6752
- "LO": "Low Water",
6753
- "LS": "Lakeshore Flood",
6754
- "LW": "Lake Wind",
6755
- "MA": "Special Marine",
6756
- "EQ": "Earthquake",
6757
- "MF": "Dense Fog",
6758
- "MH": "Ashfall",
6759
- "MS": "Dense Smoke",
6760
- "RB": "Small Craft for Rough Bar",
6761
- "RP": "Rip Current Risk",
6762
- "SC": "Small Craft",
6763
- "SE": "Hazardous Seas",
6764
- "SI": "Small Craft for Winds",
6765
- "SM": "Dense Smoke",
6766
- "SQ": "Snow Squall",
6767
- "SR": "Storm",
6768
- "SS": "Storm Surge",
6769
- "SU": "High Surf",
6770
- "SV": "Severe Thunderstorm",
6771
- "SW": "Small Craft for Hazardous Seas",
6772
- "TO": "Tornado",
6773
- "TR": "Tropical Storm",
6774
- "TS": "Tsunami",
6775
- "TY": "Typhoon",
6776
- "SP": "Special Weather",
6777
- "UP": "Heavy Freezing Spray",
6778
- "WC": "Wind Chill",
6779
- "WI": "Wind",
6780
- "WS": "Winter Storm",
6781
- "WW": "Winter Weather",
6782
- "ZF": "Freezing Fog",
6783
- "ZR": "Freezing Rain",
6784
- "ZY": "Freezing Spray"
6785
- };
6786
-
6787
- // src/@dictionaries/dictionaries.actions.ts
6788
- var dict_actions = {
6789
- "W": "Warning",
6790
- "F": "Forecast",
6791
- "A": "Watch",
6792
- "O": "Outlook",
6793
- "Y": "Advisory",
6794
- "N": "Synopsis",
6795
- "S": "Statement"
6796
- };
6797
-
6798
- // src/@dictionaries/dictionaries.status.ts
6799
- var dict_status = {
6800
- "NEW": "Issued",
6801
- "CON": "Updated",
6802
- "EXT": "Extended",
6803
- "EXA": "Extended",
6804
- "EXB": "Extended",
6805
- "UPG": "Upgraded",
6806
- "COR": "Correction",
6807
- "ROU": "Routine",
6808
- "CAN": "Cancelled",
6809
- "EXP": "Expired"
6810
- };
6811
-
6812
- // src/@parsers/@pvtec/pvtec.expires.ts
6813
- var getExpiry2 = (dates) => {
6814
- if ((dates == null ? void 0 : dates[1]) == `000000T0000Z`) return "Invalid Date Format";
6815
- const expires = `${(/* @__PURE__ */ new Date()).getFullYear().toString().substring(0, 2)}${dates[1].substring(0, 2)}-${dates[1].substring(2, 4)}-${dates[1].substring(4, 6)}T${dates[1].substring(7, 9)}:${dates[1].substring(9, 11)}:00`;
6816
- const local = new Date(new Date(expires).getTime() - 4 * 60 * 6e4);
6817
- const pad = (n) => n.toString().padStart(2, "0");
6818
- return `${local.getFullYear()}-${pad(local.getMonth() + 1)}-${pad(local.getDate())}T${pad(local.getHours())}:${pad(local.getMinutes())}:00.000-04:00`;
6819
- };
6820
-
6821
- // src/@parsers/@pvtec/pvtec.extract.ts
6822
- var pvExtract = (message) => {
6823
- var _a, _b, _c, _d;
6824
- if (!message) return null;
6825
- const getVTECs = (_a = message.match(dict_expressions.pvtec)) != null ? _a : [];
6826
- const vtecs = [];
6827
- for (const vtec2 of getVTECs) {
6828
- const sub = vtec2.split(`.`);
6829
- if ((sub == null ? void 0 : sub.length) < 7) continue;
6830
- const dates = (_b = sub[6]) == null ? void 0 : _b.split(`-`);
6831
- vtecs.push({
6832
- vtec: vtec2,
6833
- product: dict_products[sub[0]],
6834
- tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
6835
- event: `${dict_events[sub[3]]} ${dict_actions[sub[4]]}`,
6836
- status: dict_status[sub[1]],
6837
- organization: (_d = (_c = message.match(dict_expressions.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
6838
- expires: getExpiry2(dates),
6839
- is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
6840
- prediction_center: sub[2] == `KWNS` ? true : false
6774
+ if (!selectedEvent) {
6775
+ yield Promise.all(events.map((evt) => __async(null, null, function* () {
6776
+ yield update(evt);
6777
+ })));
6778
+ }
6779
+ if (selectedEvent) {
6780
+ yield update(selectedEvent);
6781
+ }
6782
+ if (total > 0) {
6783
+ setEventEmit({
6784
+ event: `onNodeUpdate`,
6785
+ metadata: {
6786
+ type: `global-update`,
6787
+ updated: total
6788
+ }
6841
6789
  });
6842
6790
  }
6843
- return vtecs.length > 0 ? vtecs : null;
6844
- };
6791
+ });
6845
6792
 
6846
- // src/@dictionaries/dictionaries.causes.ts
6847
- var dict_causes = {
6848
- "SM": "Snow Melt",
6849
- "RS": "Rain/Snow Melt",
6850
- "ER": "Excessive Rain",
6851
- "DM": "Dam/Levee Failure",
6852
- "IJ": "Ice Jam",
6853
- "GO": "Glacier Lake Outburst",
6854
- "IC": "Ice",
6855
- "FS": "Flash Flood / Storm Surge",
6856
- "FT": "Tidal Effects",
6857
- "ET": "Elevated Upstream Flow",
6858
- "MC": "Other Multiple Causes",
6859
- "WT": "Wind and/or Tidal Effects",
6860
- "DR": "Reservoir Release",
6861
- "UU": "Unknown",
6862
- "OT": "Other Effects"
6863
- };
6793
+ // src/@manager/manager.mkEvent.ts
6794
+ var mkEvent = (event) => __async(null, null, function* () {
6795
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
6796
+ const settings = bootstrap.settings;
6797
+ const features = bootstrap.cache.events.features;
6798
+ const getHash = event.properties.metadata.hash;
6799
+ const getTracking = event.properties.metadata.tracking;
6800
+ const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
6801
+ const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
6802
+ const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
6803
+ if (isHashed || event.properties.status_metadata.is_expired) return;
6804
+ setHash(event, isEntry);
6805
+ const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
6806
+ if (!isFilteredLocation && !dict_global.includes(event.properties.event.toLowerCase()) && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
6807
+ return;
6808
+ }
6809
+ const isRatelimited = setTimeoutAction({ identifier: getTracking, interval: 1, max: 1, addTime: true });
6810
+ if (!isRatelimited.limited) {
6811
+ setEventEmit({
6812
+ event: `onEventStatus`,
6813
+ metadata: {
6814
+ type: getFeature ? `Updated` : `New`,
6815
+ event
6816
+ },
6817
+ message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6818
+ });
6819
+ }
6820
+ if (settings.GlobalSettings.EventManagement) {
6821
+ if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
6822
+ if (getFeature) {
6823
+ const getIndex = features.indexOf(getFeature);
6824
+ const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
6825
+ const cLocations = (_i = (_h = (_g = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _g.locations) == null ? void 0 : _h.split(";").map((l) => l.trim())) != null ? _i : [];
6826
+ const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
6827
+ const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
6828
+ const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
6829
+ const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
6830
+ const mHistory = [...cHistory, ...iHistory].filter((v, i, a) => a.indexOf(v) === i).filter((v, i, a) => a.findIndex((h) => h.description === v.description && h.issued === v.issued) === i);
6831
+ const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
6832
+ const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
6833
+ bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
6834
+ properties: __spreadProps(__spreadValues({}, event.properties), {
6835
+ metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
6836
+ history: mHistory
6837
+ }),
6838
+ locations: mLocations,
6839
+ geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
6840
+ ugc: mUgc
6841
+ })
6842
+ })
6843
+ });
6844
+ yield updateListener(bootstrap.cache.events.features[getIndex]);
6845
+ } else {
6846
+ features.push(event);
6847
+ yield updateListener(event);
6848
+ }
6849
+ }
6850
+ }
6851
+ });
6864
6852
 
6865
- // src/@dictionaries/dictionaries.records.ts
6866
- var dict_records = {
6867
- "NO": "No Record Expected",
6868
- "NR": "Near Record or possible record",
6869
- "UU": "Unknown history of records",
6870
- "OO": "Other"
6871
- };
6853
+ // src/@manager/manager.rmEvent.ts
6854
+ var rmEvent = (event) => __async(null, null, function* () {
6855
+ const getEvent = bootstrap.cache.events.features.find((f) => {
6856
+ var _a, _b, _c, _d;
6857
+ return ((_b = (_a = f == null ? void 0 : f.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.tracking) === ((_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.metadata) == null ? void 0 : _d.tracking);
6858
+ });
6859
+ const cachedStatus = event.properties.status;
6860
+ event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
6861
+ event.properties.status = `Expired`;
6862
+ event.properties.status_metadata.is_expired = true;
6863
+ if (getEvent) {
6864
+ if (!event.properties.status_metadata.is_statement) {
6865
+ setEventEmit({
6866
+ event: `onEventStatus`,
6867
+ metadata: {
6868
+ type: `Removed`,
6869
+ event
6870
+ },
6871
+ message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
6872
+ });
6873
+ setEventEmit({ event: `onExpiredProduct`, metadata: event });
6874
+ }
6875
+ if (cachedStatus != `Statement`) yield updateListener(event);
6876
+ bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
6877
+ bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
6878
+ setTimeoutAction({ identifier: event.properties.metadata.tracking, expire: true });
6879
+ }
6880
+ setEventEmit({
6881
+ event: `onEventCache`,
6882
+ metadata: bootstrap.cache.events,
6883
+ limited: true
6884
+ });
6885
+ });
6872
6886
 
6873
- // src/@dictionaries/dictionaries.severity.ts
6874
- var dict_severity = {
6875
- N: "Not Expected",
6876
- 0: "Areal Flood or FF Product",
6877
- 1: "Minor",
6878
- 2: "Moderate",
6879
- 3: "Major",
6880
- U: "Unknown"
6887
+ // src/@dictionaries/dictionaries.states.ts
6888
+ var dict_states = {
6889
+ "AL": "Alabama",
6890
+ "AK": "Alaska",
6891
+ "AZ": "Arizona",
6892
+ "AR": "Arkansas",
6893
+ "CA": "California",
6894
+ "CO": "Colorado",
6895
+ "CT": "Connecticut",
6896
+ "DE": "Delaware",
6897
+ "FL": "Florida",
6898
+ "GA": "Georgia",
6899
+ "HI": "Hawaii",
6900
+ "ID": "Idaho",
6901
+ "IL": "Illinois",
6902
+ "IN": "Indiana",
6903
+ "IA": "Iowa",
6904
+ "KS": "Kansas",
6905
+ "KY": "Kentucky",
6906
+ "LA": "Louisiana",
6907
+ "ME": "Maine",
6908
+ "MD": "Maryland",
6909
+ "MA": "Massachusetts",
6910
+ "MI": "Michigan",
6911
+ "MN": "Minnesota",
6912
+ "MS": "Mississippi",
6913
+ "MO": "Missouri",
6914
+ "MT": "Montana",
6915
+ "NE": "Nebraska",
6916
+ "NV": "Nevada",
6917
+ "NH": "New Hampshire",
6918
+ "NJ": "New Jersey",
6919
+ "NM": "New Mexico",
6920
+ "NY": "New York",
6921
+ "NC": "North Carolina",
6922
+ "ND": "North Dakota",
6923
+ "OH": "Ohio",
6924
+ "OK": "Oklahoma",
6925
+ "OR": "Oregon",
6926
+ "PA": "Pennsylvania",
6927
+ "RI": "Rhode Island",
6928
+ "SC": "South Carolina",
6929
+ "SD": "South Dakota",
6930
+ "TN": "Tennessee",
6931
+ "TX": "Texas",
6932
+ "UT": "Utah",
6933
+ "VT": "Vermont",
6934
+ "VA": "Virginia",
6935
+ "WA": "Washington",
6936
+ "WV": "West Virginia",
6937
+ "WI": "Wisconsin",
6938
+ "WY": "Wyoming",
6939
+ "DC": "District of Columbia"
6881
6940
  };
6882
6941
 
6883
- // src/@parsers/@hvtec/hvtec.extract.ts
6884
- var hvExtract = (message) => {
6885
- var _a;
6886
- const getHVTECs = (_a = message.match(dict_expressions.hvtec)) != null ? _a : [];
6887
- const vtecs = [];
6888
- for (const vtec2 of getHVTECs) {
6889
- const sub = vtec2.split(`.`);
6890
- if (sub.length < 7) continue;
6891
- vtecs.push({
6892
- hvtec: vtec2,
6893
- severity: dict_severity[sub[1]],
6894
- cause: dict_causes[sub[2]],
6895
- record: dict_records[sub[6]]
6896
- });
6942
+ // src/@modules/@utilities/utilities.getLatestIssuance.ts
6943
+ var getLatestIssuance = () => {
6944
+ const now = /* @__PURE__ */ new Date();
6945
+ const current = now.getUTCHours() * 100 + now.getUTCMinutes();
6946
+ const issuances = [100, 600, 1300, 1630, 2e3];
6947
+ let latest = issuances[0];
6948
+ for (const issuance of issuances) {
6949
+ if (current >= issuance) {
6950
+ latest = issuance;
6951
+ }
6897
6952
  }
6898
- return vtecs.length > 0 ? vtecs : null;
6953
+ return latest.toString().padStart(4, "0");
6899
6954
  };
6900
6955
 
6901
- // src/@events/events.vtec.ts
6902
- var vtec = (stanza) => __async(null, null, function* () {
6903
- var _a, _b, _c, _d, _e;
6904
- let processed = [];
6905
- const getMessages = (_c = (_b = (_a = stanza == null ? void 0 : stanza.message) == null ? void 0 : _a.split(/(?=\$\$)/g)) == null ? void 0 : _b.map((message) => message.trim())) == null ? void 0 : _c.filter((message) => message && message !== "$$");
6906
- if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
6907
- for (const message of getMessages) {
6908
- const tick = performance.now();
6909
- const attributes = stanza == null ? void 0 : stanza.attributes;
6910
- const pVtec = pvExtract(message);
6911
- const hVtec = hvExtract(message);
6912
- const ugc2 = yield ugcExtract(message);
6913
- if (pVtec != null && ugc2 != null) {
6914
- for (const pv of pVtec) {
6915
- const vtec2 = pv;
6916
- const props = properties({ message, attributes, ugc: ugc2, pVtec: vtec2 });
6917
- const header = getEventHeader({ properties: props, getType: stanza.getType, vtec: vtec2 });
6918
- const issued = (_d = new Date(attributes.issue)) != null ? _d : /* @__PURE__ */ new Date();
6919
- const expires = new Date(vtec2.expires);
6920
- processed.push({
6921
- type: `Feature`,
6922
- geometry: {
6923
- type: `Point`,
6924
- coordinates: []
6925
- },
6926
- properties: __spreadProps(__spreadValues({
6927
- event: pv.event,
6928
- parent: pv.event,
6929
- status: pv.status,
6930
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6931
- expires: !isNaN(expires.getTime()) ? expires.toISOString() : (_e = ugc2.expires) != null ? _e : new Date(issued.getTime() + 60 * 60 * 1e3).toISOString()
6932
- }, props), {
6933
- metadata: {
6934
- ms: performance.now() - tick,
6935
- source: `events.vtec`,
6936
- tracking: getEventTracking({ type: `VTEC`, stanza, attributes, properties: props, vtec: vtec2 }),
6937
- header,
6938
- vtec: pv,
6939
- hvtec: hVtec,
6940
- raw: message,
6941
- history: [
6942
- {
6943
- description: props.description,
6944
- issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
6945
- status: pv.status
6946
- }
6947
- ]
6948
- }
6949
- })
6956
+ // src/@building/building.attachments.ts
6957
+ var getEventAttachments = (event) => {
6958
+ var _a, _b, _c, _d, _e, _f, _g;
6959
+ let attachments = [];
6960
+ const issuanceTime = getLatestIssuance();
6961
+ const spcNumber = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.discussion_parameters) == null ? void 0 : _b.discussion_number;
6962
+ const watchNumber = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.watch_parameters) == null ? void 0 : _d.watch_number;
6963
+ const locations = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.locations_array;
6964
+ const events = [
6965
+ { target: "SPC Day 1 Outlook", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${issuanceTime}.png` },
6966
+ { target: "SPC Day 2 Outlook", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
6967
+ { target: "SPC Day 3 Outlook", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
6968
+ { target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
6969
+ { target: "Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6970
+ { target: "PDS Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6971
+ { target: "Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
6972
+ { target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
6973
+ ];
6974
+ if (events.find((e) => e.target === event.properties.event)) {
6975
+ attachments.push({ name: `Image: Graphic`, link: events.find((e) => e.target.toLowerCase() === event.properties.event.toLowerCase()).attachment });
6976
+ }
6977
+ for (const location of locations) {
6978
+ if (dict_expressions.location.test(location)) {
6979
+ const lines = [`Northern`, `Southern`, `Eastern`, `Western`, `Inland`, `Costal`, `County`];
6980
+ const county = (_f = location == null ? void 0 : location.split(",")[0]) == null ? void 0 : _f.trim().replace(new RegExp(`^(${lines.join("|")}) `), "");
6981
+ const state = dict_states[(_g = location == null ? void 0 : location.split(",")[1]) == null ? void 0 : _g.trim()];
6982
+ const feeds = bootstrap.database.prepare(`SELECT * FROM broadcastify WHERE state = ? AND county = ?`).all(state, county).sort((a, b) => {
6983
+ const typeOrder = ["Other", "Public Safety"];
6984
+ const indexA = typeOrder.indexOf(a.type);
6985
+ const indexB = typeOrder.indexOf(b.type);
6986
+ return indexA - indexB;
6987
+ });
6988
+ const tags = bootstrap.settings.BroadcastifySettings.BroadcastifyTags;
6989
+ const filtered = feeds.filter((feed) => tags.includes(feed.type));
6990
+ if (filtered.length > 0) {
6991
+ filtered.map((filtered2) => {
6992
+ if (!attachments.some((a) => a.link === filtered2.link)) {
6993
+ attachments.push({ name: `${filtered2.type}: ${filtered2.feed}`, link: filtered2.link });
6994
+ }
6950
6995
  });
6951
6996
  }
6952
6997
  }
6953
6998
  }
6954
- validateEvents(processed);
6955
- });
6999
+ return attachments;
7000
+ };
6956
7001
 
6957
- // src/@events/events.api.ts
6958
- var api = (stanza) => __async(null, null, function* () {
6959
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb, _lb, _mb, _nb, _ob, _pb, _qb, _rb, _sb, _tb, _ub;
6960
- let processed = [];
6961
- const messages = Object.values(JSON.parse(stanza.message).features);
6962
- for (const feature of messages) {
6963
- const tick = performance.now();
6964
- const pVtec = (_d = pvExtract((_c = (_b = (_a = feature == null ? void 0 : feature.properties) == null ? void 0 : _a.parameters) == null ? void 0 : _b.VTEC) == null ? void 0 : _c[0])) != null ? _d : null;
6965
- processed.push({
6966
- type: `Feature`,
6967
- geometry: {
6968
- type: `Point`,
6969
- coordinates: []
6970
- },
6971
- properties: {
6972
- event: (_f = (_e = feature == null ? void 0 : feature.properties) == null ? void 0 : _e.event) != null ? _f : null,
6973
- parent: (_h = (_g = feature == null ? void 0 : feature.properties) == null ? void 0 : _g.event) != null ? _h : null,
6974
- status: (_j = (_i = feature == null ? void 0 : feature.properties) == null ? void 0 : _i.messageType) != null ? _j : null,
6975
- issued: ((_k = feature == null ? void 0 : feature.properties) == null ? void 0 : _k.sent) ? new Date((_l = feature == null ? void 0 : feature.properties) == null ? void 0 : _l.sent).toISOString() : null,
6976
- expires: ((_m = feature == null ? void 0 : feature.properties) == null ? void 0 : _m.expires) ? new Date((_n = feature == null ? void 0 : feature.properties) == null ? void 0 : _n.expires).toISOString() : null,
6977
- locations: (_p = (_o = feature == null ? void 0 : feature.properties) == null ? void 0 : _o.areaDesc) != null ? _p : null,
6978
- locations_array: ((_q = feature == null ? void 0 : feature.properties) == null ? void 0 : _q.areaDesc) ? (_r = feature == null ? void 0 : feature.properties) == null ? void 0 : _r.areaDesc.split(";") : [],
6979
- description: (_t = (_s = feature == null ? void 0 : feature.properties) == null ? void 0 : _s.description) != null ? _t : null,
6980
- attributes: (_v = (_u = feature == null ? void 0 : feature.properties) == null ? void 0 : _u.attributes) != null ? _v : {},
6981
- geocode: {
6982
- office: {
6983
- office: pVtec ? (_w = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _w.tracking.split(`.`)[0] : null,
6984
- name: (_y = dict_icao[pVtec ? (_x = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _x.tracking.split(`.`)[0] : null]) != null ? _y : null
6985
- },
6986
- organization: (_B = (_A = (_z = feature == null ? void 0 : feature.properties) == null ? void 0 : _z.parameters) == null ? void 0 : _A.WMOidentifier) == null ? void 0 : _B[0],
6987
- ugc: (_E = (_D = (_C = feature == null ? void 0 : feature.properties) == null ? void 0 : _C.geocode) == null ? void 0 : _D.UGC) != null ? _E : [],
6988
- polygon: ((_F = feature == null ? void 0 : feature.geometry) == null ? void 0 : _F.coordinates.length) > 0 ? Buffer.from(JSON.stringify([(_G = feature == null ? void 0 : feature.geometry) == null ? void 0 : _G.coordinates[0]])).toString("base64") : null,
6989
- polygon_generated: ((_H = feature == null ? void 0 : feature.geometry) == null ? void 0 : _H.coordinates.length) > 0 ? true : false
6990
- },
6991
- parameters: {
6992
- tags: getEventTags((_I = feature == null ? void 0 : feature.properties) == null ? void 0 : _I.description),
6993
- instructions: (_K = (_J = feature == null ? void 0 : feature.properties) == null ? void 0 : _J.instruction) != null ? _K : null,
6994
- source: (_M = getTextFromProduct({ message: (_L = feature == null ? void 0 : feature.properties) == null ? void 0 : _L.description, find: [`SOURCE...`], removal: [`.`] })) != null ? _M : null,
6995
- hazards: (_O = getTextFromProduct({ message: (_N = feature == null ? void 0 : feature.properties) == null ? void 0 : _N.description, find: [`HAZARD...`], removal: [`.`] })) != null ? _O : null,
6996
- impacts: (_Q = getTextFromProduct({ message: (_P = feature == null ? void 0 : feature.properties) == null ? void 0 : _P.description, find: [`IMPACT...`], removal: [`.`] })) != null ? _Q : null,
6997
- estimated_hail_size: (_U = (_T = (_S = (_R = feature == null ? void 0 : feature.properties) == null ? void 0 : _R.parameters) == null ? void 0 : _S.maxHailSize) == null ? void 0 : _T[0]) != null ? _U : null,
6998
- estimated_wind_gusts: (_Y = (_X = (_W = (_V = feature == null ? void 0 : feature.properties) == null ? void 0 : _V.parameters) == null ? void 0 : _W.maxWindGust) == null ? void 0 : _X[0]) != null ? _Y : null,
6999
- damage_threat: (_aa = (_$ = (__ = (_Z = feature == null ? void 0 : feature.properties) == null ? void 0 : _Z.parameters) == null ? void 0 : __.thunderstormDamageThreat) == null ? void 0 : _$[0]) != null ? _aa : null,
7000
- tornado_threat: (_ea = (_da = (_ca = (_ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _ba.parameters) == null ? void 0 : _ca.tornadoDetection) == null ? void 0 : _da[0]) != null ? _ea : null,
7001
- flood_threat: (_ia = (_ha = (_ga = (_fa = feature == null ? void 0 : feature.properties) == null ? void 0 : _fa.parameters) == null ? void 0 : _ga.floodDetection) == null ? void 0 : _ha[0]) != null ? _ia : null,
7002
- wind_threat: (_ma = (_la = (_ka = (_ja = feature == null ? void 0 : feature.properties) == null ? void 0 : _ja.parameters) == null ? void 0 : _ka.windThreat) == null ? void 0 : _la[0]) != null ? _ma : null,
7003
- hail_threat: (_qa = (_pa = (_oa = (_na = feature == null ? void 0 : feature.properties) == null ? void 0 : _na.parameters) == null ? void 0 : _oa.hailThreat) == null ? void 0 : _pa[0]) != null ? _qa : null
7004
- },
7005
- discussion_parameters: {
7006
- discussion_number: (_ua = (_ta = (_sa = getTextFromProduct({ message: (_ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _ra.description, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _sa.toString()) == null ? void 0 : _ta.padStart(4, "0")) != null ? _ua : null,
7007
- discussion_concerning: (_wa = getTextFromProduct({ message: (_va = feature == null ? void 0 : feature.properties) == null ? void 0 : _va.description, find: [`Concerning...`] })) != null ? _wa : null,
7008
- discussion_max_tornado: (_ya = getTextFromProduct({ message: (_xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _xa.description, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _ya : null,
7009
- discussion_max_hail: (_Aa = getTextFromProduct({ message: (_za = feature == null ? void 0 : feature.properties) == null ? void 0 : _za.description, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _Aa : null,
7010
- discussion_max_wind: (_Ca = getTextFromProduct({ message: (_Ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ba.description, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _Ca : null,
7011
- discussion_watch_issuance: (_Ea = getTextFromProduct({ message: (_Da = feature == null ? void 0 : feature.properties) == null ? void 0 : _Da.description, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _Ea : null
7012
- },
7013
- watch_parameters: {
7014
- watch_number: ((_Fa = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Fa.is_watch) && ((_Qa = (_Pa = (_Ka = (_Ja = (_Ia = (_Ha = getTextFromProduct({ message: (_Ga = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ga.description, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _Ha.replace(/(WT|WS|)/g, "")) == null ? void 0 : _Ia.trim()) == null ? void 0 : _Ja.toString()) == null ? void 0 : _Ka.padStart(4, "0")) != null ? _Pa : (_Oa = (_Na = (_Ma = (_La = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _La.tracking) == null ? void 0 : _Ma.slice(-4)) == null ? void 0 : _Na.toString()) == null ? void 0 : _Oa.padStart(4, "0")) != null ? _Qa : null),
7015
- watch_type: ((_Ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ra.description.includes(`TORNADO WATCH`)) ? `Tornado` : ((_Sa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Sa.description.includes(`SEVERE`)) ? `Severe` : null,
7016
- additional_tornadoes_probability: (_Ua = getTextFromProduct({ message: (_Ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ta.description, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ua : null,
7017
- strong_tornadoes_probability: (_Wa = getTextFromProduct({ message: (_Va = feature == null ? void 0 : feature.properties) == null ? void 0 : _Va.description, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Wa : null,
7018
- severe_wind_probability: (_Ya = getTextFromProduct({ message: (_Xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Xa.description, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ya : null,
7019
- severe_hail_probability: (__a = getTextFromProduct({ message: (_Za = feature == null ? void 0 : feature.properties) == null ? void 0 : _Za.description, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? __a : null,
7020
- hail_2in_probability: (_ab = getTextFromProduct({ message: (_$a = feature == null ? void 0 : feature.properties) == null ? void 0 : _$a.description, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _ab : null,
7021
- combined_hail_wind_probability: (_cb = getTextFromProduct({ message: (_bb = feature == null ? void 0 : feature.properties) == null ? void 0 : _bb.description, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _cb : null,
7022
- max_hail_in: (_eb = getTextFromProduct({ message: (_db = feature == null ? void 0 : feature.properties) == null ? void 0 : _db.description, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _eb : null,
7023
- max_wind_surface: (_gb = getTextFromProduct({ message: (_fb = feature == null ? void 0 : feature.properties) == null ? void 0 : _fb.description, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _gb : null,
7024
- max_tops_x100feet: (_ib = getTextFromProduct({ message: (_hb = feature == null ? void 0 : feature.properties) == null ? void 0 : _hb.description, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _ib : null,
7025
- pds_watch: getTextFromProduct({ message: (_jb = feature == null ? void 0 : feature.properties) == null ? void 0 : _jb.description, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
7026
- },
7027
- metadata: {
7028
- ms: performance.now() - tick,
7029
- source: `events.api`,
7030
- tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (_mb = (_lb = (_kb = feature == null ? void 0 : feature.properties) == null ? void 0 : _kb.parameters) == null ? void 0 : _lb.WMOidentifier) == null ? void 0 : _mb[0], featureId: feature == null ? void 0 : feature.id }, vtec: pVtec == null ? void 0 : pVtec[0] }),
7031
- header: `ZCZC-ATMOSX-${(_ob = (_nb = feature == null ? void 0 : feature.properties) == null ? void 0 : _nb.parameters) == null ? void 0 : _ob.WMOidentifier}`,
7032
- vtec: pVtec == null ? void 0 : pVtec[0],
7033
- hvtec: null,
7034
- raw: (_pb = feature == null ? void 0 : feature.properties) == null ? void 0 : _pb.description,
7035
- history: [
7036
- {
7037
- description: (_qb = feature == null ? void 0 : feature.properties) == null ? void 0 : _qb.description,
7038
- issued: ((_rb = feature == null ? void 0 : feature.properties) == null ? void 0 : _rb.sent) ? new Date((_sb = feature == null ? void 0 : feature.properties) == null ? void 0 : _sb.sent).toISOString() : null,
7039
- status: (_ub = (_tb = feature == null ? void 0 : feature.properties) == null ? void 0 : _tb.messageType) != null ? _ub : null
7040
- }
7041
- ]
7042
- }
7002
+ // src/@building/building.validate.ts
7003
+ var import_crypto = require("crypto");
7004
+ var validateEvents = (events) => __async(null, null, function* () {
7005
+ const tick = performance.now();
7006
+ if (events.length === 0) return;
7007
+ const configurations = bootstrap.settings;
7008
+ const sets = {};
7009
+ const bools = {};
7010
+ const megered = __spreadValues(__spreadValues({}, configurations.GlobalSettings), configurations.GlobalSettings.EventFiltering);
7011
+ for (const key in megered) {
7012
+ const setting = megered[key];
7013
+ if (Array.isArray(setting)) {
7014
+ sets[key] = new Set(setting.map((item) => item.toLowerCase()));
7015
+ }
7016
+ if (typeof setting === "boolean") {
7017
+ bools[key] = setting;
7018
+ }
7019
+ }
7020
+ const isFiltered = (define2) => {
7021
+ var _a, _b, _c, _d;
7022
+ const properties2 = define2.properties;
7023
+ const zones = properties2.geocode.ugc;
7024
+ const icao = properties2.geocode.office.office;
7025
+ if (properties2.status_metadata.is_test) {
7026
+ setEventEmit({ event: `onTestProduct`, metadata: define2 });
7027
+ if (bools == null ? void 0 : bools.IgnoreTestProducts) return true;
7028
+ }
7029
+ if (properties2.status_metadata.is_expired) {
7030
+ setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
7031
+ rmEvent(define2);
7032
+ return true;
7033
+ }
7034
+ if (((_b = (_a = properties2.metadata) == null ? void 0 : _a.vtec) == null ? void 0 : _b.is_watch) && properties2.metadata.source != `events.api`) {
7035
+ const isSPC = (_d = (_c = properties2.metadata) == null ? void 0 : _c.vtec) == null ? void 0 : _d.prediction_center;
7036
+ setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
7037
+ if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
7038
+ return true;
7043
7039
  }
7044
- });
7040
+ if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
7041
+ return true;
7042
+ }
7043
+ }
7044
+ for (const key in sets) {
7045
+ const setting = sets[key];
7046
+ const values = [...setting];
7047
+ if (key === "ListeningEvents" && setting.size > 0 && !getMatched(values, define2.properties.event)) {
7048
+ setEventEmit({
7049
+ event: `onFilteredEvent`,
7050
+ metadata: define2
7051
+ });
7052
+ return true;
7053
+ }
7054
+ if (key === "IgnoredEvents" && setting.size > 0 && getMatched(values, define2.properties.event)) {
7055
+ setEventEmit({
7056
+ event: `onIgnoredEvent`,
7057
+ metadata: define2
7058
+ });
7059
+ return true;
7060
+ }
7061
+ if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
7062
+ setEventEmit({
7063
+ event: `onFilteredICAO`,
7064
+ metadata: define2
7065
+ });
7066
+ return true;
7067
+ }
7068
+ if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
7069
+ setEventEmit({
7070
+ event: `onIgnoredICAO`,
7071
+ metadata: define2
7072
+ });
7073
+ return true;
7074
+ }
7075
+ if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
7076
+ setEventEmit({
7077
+ event: `onFilteredUGC`,
7078
+ metadata: define2
7079
+ });
7080
+ return true;
7081
+ }
7082
+ if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
7083
+ setEventEmit({
7084
+ event: `onFilteredState`,
7085
+ metadata: define2
7086
+ });
7087
+ return true;
7088
+ }
7089
+ }
7090
+ return false;
7091
+ };
7092
+ const filtering = events.filter((event) => {
7093
+ var _a;
7094
+ bootstrap.cache.processed = bootstrap.cache.processed.filter((e) => e !== event);
7095
+ const define2 = getEventSignature(event);
7096
+ const properties2 = define2.properties;
7097
+ (_a = properties2 == null ? void 0 : properties2.metadata) == null ? true : delete _a.ms;
7098
+ const enhanced = properties2.event = getEventEnhancedName(event);
7099
+ const filtered = isFiltered(define2);
7100
+ if (!filtered) {
7101
+ event.geometry = !(bools == null ? void 0 : bools.DisableGeometryParsing) ? getEventGeometry(event) : null;
7102
+ properties2.metadata.attachments = getEventAttachments(event);
7103
+ }
7104
+ properties2.metadata.hash = (0, import_crypto.createHash)("sha256").update(JSON.stringify(properties2)).digest("hex");
7105
+ setEventEmit({ event: `onProductType${enhanced.replace(/\s+/g, "")}`, metadata: define2 });
7106
+ return !filtered;
7107
+ });
7108
+ if (filtering.length > 0) {
7109
+ for (const event of filtering) {
7110
+ yield mkEvent(event);
7111
+ }
7045
7112
  }
7046
- validateEvents(processed);
7113
+ yield updateNode();
7114
+ setEventEmit({
7115
+ event: `onEventCache`,
7116
+ metadata: bootstrap.cache.events,
7117
+ limited: true
7118
+ });
7119
+ setDebug({ title: `@building.validate`, message: `Filtered ${filtering.length} events which took ${performance.now() - tick} ms` });
7047
7120
  });
7048
7121
 
7049
7122
  // src/@building/building.create.ts
7050
- var createEvent = (stanza) => __async(null, null, function* () {
7123
+ var createEvent = (stanza, ignorePushing) => __async(null, null, function* () {
7051
7124
  const settings = bootstrap.settings;
7052
7125
  const StanzaSettings = settings.NOAAWeatherWireServiceSettings.StanzaSettings;
7053
7126
  const isVtecEvent = stanza.isVTEC && stanza.isUGC;
7054
7127
  const isUgcEvent = !stanza.isVTEC && stanza.isUGC;
7055
7128
  const isTextEvent = !stanza.isVTEC && !stanza.isUGC;
7056
7129
  const isNWWS = stanza.isNWWS;
7057
- if (!isNWWS) return yield api(stanza);
7058
- if (!StanzaSettings.DisableVTEC && isVtecEvent) return yield vtec(stanza);
7059
- if (!StanzaSettings.DisableUGC && isUgcEvent) return yield ugc(stanza);
7060
- if (!StanzaSettings.DisableText && isTextEvent) return yield text(stanza);
7130
+ switch (true) {
7131
+ case !isNWWS:
7132
+ yield api(stanza);
7133
+ break;
7134
+ case (isNWWS && !StanzaSettings.DisableVTEC && isVtecEvent):
7135
+ yield vtec(stanza);
7136
+ break;
7137
+ case (isNWWS && !StanzaSettings.DisableUGC && isUgcEvent):
7138
+ yield ugc(stanza);
7139
+ break;
7140
+ case (isNWWS && !StanzaSettings.DisableText && isTextEvent):
7141
+ yield text(stanza);
7142
+ break;
7143
+ }
7144
+ if (!ignorePushing) {
7145
+ validateEvents(bootstrap.cache.processed);
7146
+ }
7061
7147
  return "nothing picked";
7062
7148
  });
7063
7149
 
@@ -7153,25 +7239,6 @@ var xDeploy = () => __async(null, null, function* () {
7153
7239
  }
7154
7240
  });
7155
7241
 
7156
- // src/@modules/@database/database.init.ts
7157
- var import_fs5 = __toESM(require("fs"));
7158
- var import_better_sqlite3 = __toESM(require("better-sqlite3"));
7159
-
7160
- // src/@modules/@database/database.shapefiles.ts
7161
- var import_fs4 = __toESM(require("fs"));
7162
- var import_path3 = require("path");
7163
- var import_jszip = require("jszip");
7164
- var import_shapefile = require("shapefile");
7165
-
7166
- // src/@modules/@utilities/utilities.setSleep.ts
7167
- var setSleep = (options) => __async(null, null, function* () {
7168
- return new Promise((resolve6) => {
7169
- setTimeout(() => {
7170
- resolve6();
7171
- }, options.timeout);
7172
- });
7173
- });
7174
-
7175
7242
  // src/@dictionaries/dictionaries.shapefiles.ts
7176
7243
  var dict_shapefiles = [
7177
7244
  { name: "us_counties", id: "C", link: "https://www.weather.gov/source/gis/Shapefiles/County/c_16ap26.zip" },
@@ -7185,7 +7252,20 @@ var dict_shapefiles = [
7185
7252
  { name: "high_seas_marine_zones", id: "Z", link: "https://www.weather.gov/source/gis/Shapefiles/WSOM/hz17fe26.zip" }
7186
7253
  ];
7187
7254
 
7255
+ // src/@modules/@utilities/utilities.setSleep.ts
7256
+ var setSleep = (options) => __async(null, null, function* () {
7257
+ return new Promise((resolve6) => {
7258
+ setTimeout(() => {
7259
+ resolve6();
7260
+ }, options.timeout);
7261
+ });
7262
+ });
7263
+
7188
7264
  // src/@modules/@database/database.shapefiles.ts
7265
+ var import_fs4 = require("fs");
7266
+ var import_path3 = require("path");
7267
+ var import_jszip = require("jszip");
7268
+ var import_shapefile = require("shapefile");
7189
7269
  var importShapefiles = () => __async(null, null, function* () {
7190
7270
  var _a, _b;
7191
7271
  const settings = bootstrap.settings;
@@ -7198,14 +7278,14 @@ var importShapefiles = () => __async(null, null, function* () {
7198
7278
  const arrayBuff = yield response2.arrayBuffer();
7199
7279
  const content = yield (0, import_jszip.loadAsync)(arrayBuff);
7200
7280
  const directory = (0, import_path3.resolve)(__dirname, `../../shapefiles`);
7201
- if (!import_fs4.default.existsSync(directory)) {
7202
- import_fs4.default.mkdirSync(directory, { recursive: true });
7281
+ if (!(0, import_fs4.existsSync)(directory)) {
7282
+ (0, import_fs4.mkdirSync)(directory, { recursive: true });
7203
7283
  }
7204
7284
  for (const file of Object.keys(content.files)) {
7205
7285
  if (file.endsWith(".shp") || file.endsWith(".dbf")) {
7206
7286
  const data = yield content.files[file].async(`nodebuffer`);
7207
7287
  const output = (0, import_path3.resolve)(directory, `${(_a = shapefile == null ? void 0 : shapefile.name) != null ? _a : ``}_${(_b = shapefile == null ? void 0 : shapefile.id) != null ? _b : ``}${(0, import_path3.extname)(file)}`);
7208
- import_fs4.default.writeFileSync(output, data);
7288
+ (0, import_fs4.writeFileSync)(output, data);
7209
7289
  }
7210
7290
  }
7211
7291
  const filepath = (0, import_path3.resolve)(__dirname, "../../shapefiles", shapefile.name + "_" + shapefile.id);
@@ -7236,11 +7316,11 @@ var importShapefiles = () => __async(null, null, function* () {
7236
7316
  insert.run(final2, location, JSON.stringify(geometry));
7237
7317
  }
7238
7318
  });
7239
- import_fs4.default.unlinkSync(`${filepath}.shp`);
7240
- import_fs4.default.unlinkSync(`${filepath}.dbf`);
7319
+ (0, import_fs4.unlinkSync)(`${filepath}.shp`);
7320
+ (0, import_fs4.unlinkSync)(`${filepath}.dbf`);
7241
7321
  transaction(features);
7242
7322
  }
7243
- import_fs4.default.rm((0, import_path3.resolve)(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
7323
+ (0, import_fs4.rm)((0, import_path3.resolve)(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
7244
7324
  });
7245
7325
  }
7246
7326
  } catch (error) {
@@ -7292,11 +7372,13 @@ var importBroadcastify = () => __async(null, null, function* () {
7292
7372
  });
7293
7373
 
7294
7374
  // src/@modules/@database/database.init.ts
7375
+ var import_fs5 = require("fs");
7376
+ var import_better_sqlite3 = __toESM(require("better-sqlite3"));
7295
7377
  var initializeDatabase = () => __async(null, null, function* () {
7296
7378
  const settings = bootstrap.settings;
7297
7379
  try {
7298
- if (!import_fs5.default.existsSync(settings.Database)) {
7299
- import_fs5.default.writeFileSync(settings.Database, "");
7380
+ if (!(0, import_fs5.existsSync)(settings.Database)) {
7381
+ (0, import_fs5.writeFileSync)(settings.Database, "");
7300
7382
  setWarning({ message: `Creating new database at ${settings.Database}` });
7301
7383
  }
7302
7384
  bootstrap.database = new import_better_sqlite3.default(settings.Database);
@@ -7324,7 +7406,7 @@ var getCachedEvents = () => __async(null, null, function* () {
7324
7406
  if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
7325
7407
  const max = (_a = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory) != null ? _a : 500;
7326
7408
  const get = yield bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max);
7327
- setWarning({ message: `Fetched ${get.length} cached events from the database in ${Math.floor(performance.now() - tick)} ms` });
7409
+ setWarning({ message: `Fetched ${get.length} cached stanzas from the database in ${Math.floor(performance.now() - tick)} ms` });
7328
7410
  let events = get.map((row) => JSON.parse(row.stanza)).filter((stanza) => {
7329
7411
  if (!stanza) {
7330
7412
  return;
@@ -7333,11 +7415,12 @@ var getCachedEvents = () => __async(null, null, function* () {
7333
7415
  return !isSkippable;
7334
7416
  });
7335
7417
  events = events.sort((a, b) => b.issued - a.issued);
7336
- yield Promise.all(events.map((event) => createEvent(event)));
7337
- setWarning({ message: `Processed ${events.length} cached events in ${Math.floor(performance.now() - tick)} ms` });
7418
+ yield Promise.all(events.map((event) => createEvent(event, true)));
7419
+ setWarning({ message: `Processed ${events.length} cached stanzas in ${Math.floor(performance.now() - tick)} ms` });
7420
+ validateEvents(bootstrap.cache.processed);
7338
7421
  }
7339
7422
  } catch (error) {
7340
- setWarning({ message: `An error occurred while fetching cached events: ${error.message} -> ${error.stack}` });
7423
+ setWarning({ message: `An error occurred while fetching cached stanzas: ${error.message} -> ${error.stack}` });
7341
7424
  }
7342
7425
  });
7343
7426
 
@@ -7457,7 +7540,7 @@ var updateEvents = (selectedEvent) => __async(null, null, function* () {
7457
7540
  function update(evt) {
7458
7541
  return __async(this, null, function* () {
7459
7542
  if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
7460
- rmEvent(evt);
7543
+ yield rmEvent(evt);
7461
7544
  }
7462
7545
  });
7463
7546
  }
@@ -7583,59 +7666,16 @@ var getNodes = () => {
7583
7666
  return bootstrap.cache.nodes;
7584
7667
  };
7585
7668
 
7586
- // src/@core/core.createEvent.ts
7587
- var createEvent2 = (options) => {
7588
- var _a;
7589
- const tick = performance.now();
7590
- validateEvents([{
7591
- type: `Feature`,
7592
- geometry: {
7593
- type: `Point`,
7594
- coordinates: options.coordinates
7595
- },
7596
- properties: {
7597
- event: options.event,
7598
- parent: options.event,
7599
- status: options.status,
7600
- issued: options.issued.toISOString(),
7601
- expires: options.expires.toISOString(),
7602
- locations: options.locations,
7603
- locations_array: options.locations ? options.locations.split(";") : [],
7604
- description: options.description,
7605
- geocode: {
7606
- office: {
7607
- office: `ATMX`,
7608
- name: `AtmosphericX Manual Event`
7609
- },
7610
- organization: `AtmosphericX`,
7611
- ugc: [],
7612
- polygon: options.coordinates.length > 0 ? Buffer.from(JSON.stringify([options.coordinates[0]])).toString("base64") : null,
7613
- polygon_generated: options.coordinates.length > 0 ? true : false
7614
- },
7615
- status_metadata: {
7616
- is_issued: options.status == `Issued`,
7617
- is_updated: options.status == `Updated`,
7618
- is_expired: options.status == `Expired`,
7619
- is_test: options.status == `Test`,
7620
- is_statement: options.status == `Statement`
7621
- },
7622
- metadata: {
7623
- ms: performance.now() - tick,
7624
- source: `events.manual`,
7625
- tracking: `ATMX-M-W-01`,
7626
- header: `ZCZC-ATMOSX-ATMX-M-W-01`,
7627
- raw: options.description,
7628
- history: [
7629
- {
7630
- description: options.description,
7631
- issued: options.issued.toISOString(),
7632
- status: (_a = options.status) != null ? _a : null
7633
- }
7634
- ]
7635
- }
7636
- }
7637
- }]);
7638
- };
7669
+ // src/@core/core.manualEvent.ts
7670
+ var manualEvent = (options) => __async(null, null, function* () {
7671
+ const isCapEvent = options.message.includes(`<?xml`);
7672
+ const isCapAreaDescription = options.message.includes(`<areaDesc>`);
7673
+ const isVTEC = options.message.match(dict_expressions.pvtec) != null;
7674
+ const isUGC = options.message.match(dict_expressions.ugc1) != null;
7675
+ const getType = getAwipsType({ attributes: options.attributes });
7676
+ const result = { message: options.message, attributes: options.attributes, isCapEvent, isVTEC, isUGC, isCapAreaDescription, isIgnored: false, isNWWS: true, getType };
7677
+ yield createEvent(result);
7678
+ });
7639
7679
 
7640
7680
  // src/@core/core.getRandomEvent.ts
7641
7681
  var getRandomEvent = () => {
@@ -7697,12 +7737,12 @@ var index_default = Manager;
7697
7737
  0 && (module.exports = {
7698
7738
  Manager,
7699
7739
  clearEvents,
7700
- createEvent,
7701
7740
  getCleanedEvent,
7702
7741
  getEventGeometry,
7703
7742
  getEvents,
7704
7743
  getNodes,
7705
7744
  getRandomEvent,
7745
+ manualEvent,
7706
7746
  query,
7707
7747
  setEasTone,
7708
7748
  setNode,