@atmosx/event-product-parser 3.0.42 → 3.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -22
- package/SUPPORTED_EVENTS.md +369 -0
- package/dist/cjs/index.cjs +1990 -1758
- package/dist/esm/index.mjs +1560 -1329
- package/dist/index.d.mts +44 -20
- package/dist/index.d.ts +44 -20
- package/package.json +1 -1
- package/src/@building/building.attachments.ts +42 -0
- package/src/@building/building.create.ts +2 -2
- package/src/@building/building.enhance.ts +8 -4
- package/src/@building/building.geometry.ts +1 -1
- package/src/@building/building.headers.ts +1 -1
- package/src/@building/building.office.ts +4 -4
- package/src/@building/building.properties.ts +15 -13
- package/src/@building/building.signature.ts +11 -11
- package/src/@building/building.tags.ts +2 -2
- package/src/@building/building.tracking.ts +6 -6
- package/src/@building/building.validate.ts +5 -3
- package/src/@core/core.createEvent.ts +82 -0
- package/src/@core/core.query.ts +1 -1
- package/src/@core/core.start.ts +1 -1
- package/src/@dictionaries/{dictionaries.eventActions.ts → dictionaries.actions.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventAwipAbreviations.ts → dictionaries.awips.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventCancelMessages.ts → dictionaries.cancellation.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventCauses.ts → dictionaries.causes.ts} +1 -1
- package/src/@dictionaries/{dictionaries.statusCorrelationText.ts → dictionaries.correlations.ts} +1 -1
- package/src/@dictionaries/{dictionaries.betterEventNames.ts → dictionaries.enhanced.ts} +13 -2
- package/src/@dictionaries/{dictionaries.eventTypes.ts → dictionaries.events.ts} +1 -1
- package/src/@dictionaries/{dictionaries.regExp.ts → dictionaries.expressions.ts} +1 -1
- package/src/@dictionaries/{dictionaries.hailStrings.ts → dictionaries.hail.ts} +4 -1
- package/src/@dictionaries/{dictionaries.officeICAOs.ts → dictionaries.icao.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventsMatchText.ts → dictionaries.matches.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventProducts.ts → dictionaries.products.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventRecords.ts → dictionaries.records.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventSeverity.ts → dictionaries.severity.ts} +1 -1
- package/src/@dictionaries/{dictionaries.shapefileLinks.ts → dictionaries.shapefiles.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventStatus.ts → dictionaries.status.ts} +1 -1
- package/src/@dictionaries/{dictionaries.eventTags.ts → dictionaries.tags.ts} +1 -1
- package/src/@dictionaries/{dictionaries.testSignatures.ts → dictionaries.test.ts} +3 -2
- package/src/@events/events.api.ts +19 -14
- package/src/@events/events.text.ts +5 -4
- package/src/@events/events.ugc.ts +5 -4
- package/src/@events/events.vtec.ts +5 -4
- package/src/@manager/manager.mkEvent.ts +4 -4
- package/src/@manager/manager.rmEvent.ts +3 -2
- package/src/@manager/manager.setHash.ts +1 -1
- package/src/@manager/manager.updateListener.ts +124 -0
- package/src/@modules/@database/database.cache.ts +1 -1
- package/src/@modules/@database/database.init.ts +1 -1
- package/src/@modules/@database/database.shapefiles.ts +3 -3
- package/src/@modules/@database/database.stanza.ts +2 -2
- package/src/@modules/@eas/eas.getCleanDescription.ts +91 -0
- package/src/@modules/@eas/eas.getTTS.ts +54 -0
- package/src/@modules/@eas/eas.setEasTone.ts +40 -30
- package/src/@modules/@stanza/stanza.getAwipsType.ts +3 -3
- package/src/@modules/@stanza/stanza.validate.ts +5 -5
- package/src/@modules/@utilities/utilities.getLatestIssuance.ts +32 -0
- package/src/@modules/@utilities/utilities.getSettings.ts +1 -1
- package/src/@modules/@utilities/utilities.setCronSchedule.ts +30 -2
- package/src/@modules/@utilities/utilities.setSettings.ts +1 -1
- package/src/@modules/@utilities/utilities.setWarning.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xDeploy.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xReconnect.ts +1 -1
- package/src/@modules/@xmpp/xmpp.xStanza.ts +1 -1
- package/src/@parsers/@hvtec/hvtec.extract.ts +9 -9
- package/src/@parsers/@pvtec/pvtec.extract.ts +13 -13
- package/src/@parsers/@text/text.getDescriptionFromProduct.ts +2 -2
- package/src/@parsers/@text/text.getEmbed.ts +60 -0
- package/src/@parsers/@ugc/ugc.extract.ts +1 -1
- package/src/@parsers/@ugc/ugc.header.ts +3 -3
- package/src/@types/{types.compiled.ts → type.compiled.ts} +1 -1
- package/src/@types/type.event.ts +6 -4
- package/src/@types/{types.webhook.ts → type.listener.ts} +11 -6
- package/src/@types/type.properties.ts +10 -8
- package/src/@types/{types.settings.ts → type.settings.ts} +7 -5
- package/src/bootstrap.ts +7 -5
- package/src/index.ts +3 -2
- package/test.js +19 -19
- package/src/@dictionaries/dictionaries.transcribedMessageReplacements.ts +0 -68
- package/src/@manager/manager.createWebhook.ts +0 -117
- package/src/@manager/manager.updateWebhooks.ts +0 -49
- /package/src/@types/{types.attributes.ts → type.attributes.ts} +0 -0
- /package/src/@types/{types.hash.ts → type.hash.ts} +0 -0
- /package/src/@types/{types.hvtec.ts → type.hvtec.ts} +0 -0
- /package/src/@types/{types.pvtec.ts → type.pvtec.ts} +0 -0
- /package/src/@types/{types.stanza.ts → type.stanza.ts} +0 -0
- /package/src/@types/{types.ugc.ts → type.ugc.ts} +0 -0
package/dist/esm/index.mjs
CHANGED
|
@@ -10491,7 +10491,7 @@ var require_form_data = __commonJS({
|
|
|
10491
10491
|
import path from "path";
|
|
10492
10492
|
import { EventEmitter } from "events";
|
|
10493
10493
|
var bootstrap = {
|
|
10494
|
-
version: `3.0.
|
|
10494
|
+
version: `3.0.46`,
|
|
10495
10495
|
isReady: true,
|
|
10496
10496
|
ratelimits: {},
|
|
10497
10497
|
session_xmpp: null,
|
|
@@ -10547,7 +10547,7 @@ var bootstrap = {
|
|
|
10547
10547
|
CallbackInterval: 15,
|
|
10548
10548
|
EventsEndpoint: `https://api.weather.gov/alerts/active`
|
|
10549
10549
|
},
|
|
10550
|
-
|
|
10550
|
+
ListenerSettings: [],
|
|
10551
10551
|
GlobalSettings: {
|
|
10552
10552
|
EventManagement: true,
|
|
10553
10553
|
BetterEventNames: true,
|
|
@@ -10567,9 +10567,11 @@ var bootstrap = {
|
|
|
10567
10567
|
NodeLocationFiltering: false,
|
|
10568
10568
|
IgnoreTestProducts: true
|
|
10569
10569
|
},
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10570
|
+
ArchiveSettings: {
|
|
10571
|
+
TTL: 60,
|
|
10572
|
+
TextDirectory: null,
|
|
10573
|
+
EasDirectory: null,
|
|
10574
|
+
EasToneout: null
|
|
10573
10575
|
}
|
|
10574
10576
|
}
|
|
10575
10577
|
}
|
|
@@ -13583,8 +13585,8 @@ var xError = () => {
|
|
|
13583
13585
|
}));
|
|
13584
13586
|
};
|
|
13585
13587
|
|
|
13586
|
-
// src/@dictionaries/dictionaries.
|
|
13587
|
-
var
|
|
13588
|
+
// src/@dictionaries/dictionaries.expressions.ts
|
|
13589
|
+
var dict_expressions = {
|
|
13588
13590
|
pvtec: new RegExp(`[OTEX].(NEW|CON|EXT|EXA|EXB|UPG|CAN|EXP|COR|ROU).[A-Z]{4}.[A-Z]{2}.[WAYSFON].[0-9]{4}.[0-9]{6}T[0-9]{4}Z-[0-9]{6}T[0-9]{4}Z`, "g"),
|
|
13589
13591
|
hvtec: new RegExp(`[a-zA-Z0-9]{4}.[A-Z0-9].[A-Z]{2}.[0-9]{6}T[0-9]{4}Z.[0-9]{6}T[0-9]{4}Z.[0-9]{6}T[0-9]{4}Z.[A-Z]{2}`, "imu"),
|
|
13590
13592
|
wmo: new RegExp(`[A-Z0-9]{6}\\s[A-Z]{4}\\s\\d{6}`, "imu"),
|
|
@@ -13594,8 +13596,8 @@ var regExp = {
|
|
|
13594
13596
|
dateline: new RegExp(`\\d{3,4}\\s*(AM|PM)?\\s*[A-Z]{2,4}\\s+[A-Z]{3,}\\s+[A-Z]{3,}\\s+\\d{1,2}\\s+\\d{4}`, "gim")
|
|
13595
13597
|
};
|
|
13596
13598
|
|
|
13597
|
-
// src/@dictionaries/dictionaries.
|
|
13598
|
-
var
|
|
13599
|
+
// src/@dictionaries/dictionaries.awips.ts
|
|
13600
|
+
var dict_awips = {
|
|
13599
13601
|
ABV: `rawinsonde-data-above-100-millibars`,
|
|
13600
13602
|
ADA: `alarm-alert-administrative-message`,
|
|
13601
13603
|
ADM: `alert-administrative-message`,
|
|
@@ -13950,7 +13952,7 @@ var getAwipsType = (options) => {
|
|
|
13950
13952
|
prefix: null
|
|
13951
13953
|
};
|
|
13952
13954
|
}
|
|
13953
|
-
for (const [prefix, type] of Object.entries(
|
|
13955
|
+
for (const [prefix, type] of Object.entries(dict_awips)) {
|
|
13954
13956
|
if (attributes.awipsid.startsWith(prefix)) {
|
|
13955
13957
|
return { type, prefix };
|
|
13956
13958
|
}
|
|
@@ -13968,8 +13970,8 @@ var validate = (options) => {
|
|
|
13968
13970
|
if (attributes.awipsid && attributes.awipsid.length > 1) {
|
|
13969
13971
|
const isCapEvent = message.includes(`<?xml`);
|
|
13970
13972
|
const isCapAreaDescription = message.includes(`<areaDesc>`);
|
|
13971
|
-
const isVTEC = message.match(
|
|
13972
|
-
const isUGC = message.match(
|
|
13973
|
+
const isVTEC = message.match(dict_expressions.pvtec) != null;
|
|
13974
|
+
const isUGC = message.match(dict_expressions.ugc1) != null;
|
|
13973
13975
|
const getType = getAwipsType({ attributes });
|
|
13974
13976
|
if (getType.type != null) {
|
|
13975
13977
|
return {
|
|
@@ -13993,7 +13995,7 @@ var validate = (options) => {
|
|
|
13993
13995
|
// src/@parsers/@text/text.getDescriptionFromProduct.ts
|
|
13994
13996
|
var getDescriptionFromProduct = (options) => {
|
|
13995
13997
|
let message = options.message;
|
|
13996
|
-
const dates = Array.from(message.matchAll(
|
|
13998
|
+
const dates = Array.from(message.matchAll(dict_expressions.dateline));
|
|
13997
13999
|
if (dates.length) {
|
|
13998
14000
|
const lastMatch = dates[dates.length - 1][0];
|
|
13999
14001
|
const sIndx = message.lastIndexOf(lastMatch);
|
|
@@ -14059,8 +14061,8 @@ var getTextFromProduct = (options) => {
|
|
|
14059
14061
|
return null;
|
|
14060
14062
|
};
|
|
14061
14063
|
|
|
14062
|
-
// src/@dictionaries/dictionaries.
|
|
14063
|
-
var
|
|
14064
|
+
// src/@dictionaries/dictionaries.icao.ts
|
|
14065
|
+
var dict_icao = {
|
|
14064
14066
|
"KLUB": "Lubbock, TX",
|
|
14065
14067
|
"KLCH": "Lake Charles, LA",
|
|
14066
14068
|
"TSTL": "St. Louis, MO",
|
|
@@ -14305,12 +14307,12 @@ var officeICAOs = {
|
|
|
14305
14307
|
var getEventOffice = (options) => {
|
|
14306
14308
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
14307
14309
|
const office = options.pVtec != null ? (_b = (_a = options.pVtec) == null ? void 0 : _a.tracking) == null ? void 0 : _b.split(`.`)[0] : (_e = (_c = options.attributes) == null ? void 0 : _c.cccc) != null ? _e : options.organization != null ? Array.isArray(options.organization) ? (_d = options.organization) == null ? void 0 : _d[0] : options.organization : null;
|
|
14308
|
-
const name = (_g = (_f =
|
|
14310
|
+
const name = (_g = (_f = dict_icao) == null ? void 0 : _f[office]) != null ? _g : null;
|
|
14309
14311
|
return { office, name };
|
|
14310
14312
|
};
|
|
14311
14313
|
|
|
14312
|
-
// src/@dictionaries/dictionaries.
|
|
14313
|
-
var
|
|
14314
|
+
// src/@dictionaries/dictionaries.tags.ts
|
|
14315
|
+
var dict_tags = {
|
|
14314
14316
|
"FROSTBITE AND HYPOTHERMIA ARE LIKELY": "Frostbite and Hypothermia Likely",
|
|
14315
14317
|
"LICKELY BECOME SLICK AND HAZARDOUS": "Slick and Hazardous Roads",
|
|
14316
14318
|
"SLIPPERY ROAD CONDITIONS": "Slippery Roads",
|
|
@@ -14387,13 +14389,13 @@ var eventTags = {
|
|
|
14387
14389
|
|
|
14388
14390
|
// src/@building/building.tags.ts
|
|
14389
14391
|
var getEventTags = (message) => {
|
|
14390
|
-
return Object.entries(
|
|
14392
|
+
return Object.entries(dict_tags).filter(([key]) => message == null ? void 0 : message.toLowerCase().includes(key.toLowerCase())).map(([, value]) => value);
|
|
14391
14393
|
};
|
|
14392
14394
|
|
|
14393
14395
|
// src/@building/building.properties.ts
|
|
14394
14396
|
var properties = (options) => {
|
|
14395
|
-
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;
|
|
14396
|
-
const organization = (_b = (_a = options.message.match(
|
|
14397
|
+
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;
|
|
14398
|
+
const organization = (_b = (_a = options.message.match(dict_expressions.wmo)) == null ? void 0 : _a[0]) != null ? _b : null;
|
|
14397
14399
|
const polygons = getPolygonFromProduct(options.message);
|
|
14398
14400
|
const properties2 = {
|
|
14399
14401
|
locations: (_e = (_d = (_c = options == null ? void 0 : options.ugc) == null ? void 0 : _c.locations) == null ? void 0 : _d.join(`; `)) != null ? _e : null,
|
|
@@ -14420,25 +14422,27 @@ var properties = (options) => {
|
|
|
14420
14422
|
wind_threat: (_s = getTextFromProduct({ message: options.message, find: [`WIND THREAT...`] })) != null ? _s : null,
|
|
14421
14423
|
hail_threat: (_t = getTextFromProduct({ message: options.message, find: [`HAIL THREAT...`], removal: [] })) != null ? _t : null
|
|
14422
14424
|
},
|
|
14423
|
-
|
|
14424
|
-
|
|
14425
|
-
|
|
14426
|
-
|
|
14427
|
-
|
|
14425
|
+
discussion_parameters: {
|
|
14426
|
+
discussion_number: (_w = (_v = (_u = getTextFromProduct({ message: options.message, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _u.toString()) == null ? void 0 : _v.padStart(4, "0")) != null ? _w : null,
|
|
14427
|
+
discussion_concerning: (_x = getTextFromProduct({ message: options.message, find: [`Concerning...`] })) != null ? _x : null,
|
|
14428
|
+
discussion_max_tornado: (_y = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _y : null,
|
|
14429
|
+
discussion_max_hail: (_z = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _z : null,
|
|
14430
|
+
discussion_max_wind: (_A = getTextFromProduct({ message: options.message, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _A : null,
|
|
14431
|
+
discussion_watch_issuance: (_B = getTextFromProduct({ message: options.message, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _B : null
|
|
14428
14432
|
},
|
|
14429
14433
|
watch_parameters: {
|
|
14430
|
-
watch_number: (
|
|
14434
|
+
watch_number: ((_C = options == null ? void 0 : options.pVtec) == null ? void 0 : _C.is_watch) && ((_M = (_L = (_G = (_F = (_E = (_D = getTextFromProduct({ message: options.message, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _D.replace(/(WT|WS|)/g, "")) == null ? void 0 : _E.trim()) == null ? void 0 : _F.toString()) == null ? void 0 : _G.padStart(4, "0")) != null ? _L : (_K = (_J = (_I = (_H = options == null ? void 0 : options.pVtec) == null ? void 0 : _H.tracking) == null ? void 0 : _I.slice(-4)) == null ? void 0 : _J.toString()) == null ? void 0 : _K.padStart(4, "0")) != null ? _M : null),
|
|
14431
14435
|
watch_type: options.message.includes(`TORNADO WATCH`) ? `Tornado` : (options == null ? void 0 : options.message.includes(`SEVERE`)) ? `Severe` : null,
|
|
14432
|
-
additional_tornadoes_probability: (
|
|
14433
|
-
strong_tornadoes_probability: (
|
|
14434
|
-
severe_wind_probability: (
|
|
14435
|
-
severe_hail_probability: (
|
|
14436
|
-
hail_2in_probability: (
|
|
14437
|
-
combined_hail_wind_probability: (
|
|
14438
|
-
max_hail_in: (
|
|
14439
|
-
max_wind_surface: (
|
|
14440
|
-
max_tops_x100feet: (
|
|
14441
|
-
pds_watch: getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
|
|
14436
|
+
additional_tornadoes_probability: (_N = getTextFromProduct({ message: options.message, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _N : null,
|
|
14437
|
+
strong_tornadoes_probability: (_O = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _O : null,
|
|
14438
|
+
severe_wind_probability: (_P = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _P : null,
|
|
14439
|
+
severe_hail_probability: (_Q = getTextFromProduct({ message: options.message, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Q : null,
|
|
14440
|
+
hail_2in_probability: (_R = getTextFromProduct({ message: options.message, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? _R : null,
|
|
14441
|
+
combined_hail_wind_probability: (_S = getTextFromProduct({ message: options.message, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _S : null,
|
|
14442
|
+
max_hail_in: (_T = getTextFromProduct({ message: options.message, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _T : null,
|
|
14443
|
+
max_wind_surface: (_U = getTextFromProduct({ message: options.message, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _U : null,
|
|
14444
|
+
max_tops_x100feet: (_V = getTextFromProduct({ message: options.message, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _V : null,
|
|
14445
|
+
pds_watch: getTextFromProduct({ message: options.message, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES` ? true : null
|
|
14442
14446
|
}
|
|
14443
14447
|
};
|
|
14444
14448
|
if (isNaN(Number(properties2.watch_parameters.watch_number))) {
|
|
@@ -14456,8 +14460,8 @@ var getEventHeader = (options) => {
|
|
|
14456
14460
|
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`}`;
|
|
14457
14461
|
};
|
|
14458
14462
|
|
|
14459
|
-
// src/@dictionaries/dictionaries.
|
|
14460
|
-
var
|
|
14463
|
+
// src/@dictionaries/dictionaries.matches.ts
|
|
14464
|
+
var dict_matches = {
|
|
14461
14465
|
"Special Weather Statement": "Special Weather Statement",
|
|
14462
14466
|
"Hurricane Warning": "Hurricane Warning",
|
|
14463
14467
|
"Hurricane Force Wind Warning": "Hurricane Force Wind Warning",
|
|
@@ -14477,7 +14481,7 @@ var eventsMatchText = {
|
|
|
14477
14481
|
|
|
14478
14482
|
// src/@building/building.tracking.ts
|
|
14479
14483
|
var getEventTracking = (options) => {
|
|
14480
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
14484
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
14481
14485
|
const properties2 = options.properties;
|
|
14482
14486
|
const attributes = options.attributes;
|
|
14483
14487
|
const stanza = options.stanza;
|
|
@@ -14494,26 +14498,26 @@ var getEventTracking = (options) => {
|
|
|
14494
14498
|
}
|
|
14495
14499
|
if (options.type === `API`) {
|
|
14496
14500
|
if (options.vtec) {
|
|
14497
|
-
const vtecValue = Array.isArray(options.vtec) ? options.vtec[0] : options.vtec;
|
|
14501
|
+
const vtecValue = Array.isArray(options.vtec) ? options.vtec[0].vtec : (_c = options.vtec) == null ? void 0 : _c.vtec;
|
|
14498
14502
|
const splitPVTEC = vtecValue.split(".");
|
|
14499
14503
|
return `${splitPVTEC[2]}.${splitPVTEC[3]}.${splitPVTEC[4]}.${splitPVTEC[5]}`;
|
|
14500
14504
|
}
|
|
14501
|
-
const wmoMatch = (
|
|
14502
|
-
const station = (
|
|
14505
|
+
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})/);
|
|
14506
|
+
const station = (_f = wmoMatch == null ? void 0 : wmoMatch[2]) != null ? _f : "N/A";
|
|
14503
14507
|
if (options.organization.featureId) {
|
|
14504
14508
|
const idMatch = options.organization.featureId.match(/([a-f0-9]+)\.(\d+)\.(\d+)$/);
|
|
14505
|
-
return `${station}.${(
|
|
14509
|
+
return `${station}.${(_h = (_g = idMatch == null ? void 0 : idMatch[0]) == null ? void 0 : _g.replace(/\./g, "")) != null ? _h : "N/A"}`;
|
|
14506
14510
|
}
|
|
14507
|
-
const id2 = (
|
|
14508
|
-
return `${station}.${id2}`;
|
|
14511
|
+
const id2 = (_i = wmoMatch == null ? void 0 : wmoMatch[1]) != null ? _i : "N/A";
|
|
14512
|
+
return `${station}.${(_j = id2 == null ? void 0 : id2.replace(/\./g, "")) != null ? _j : "N/A"}`;
|
|
14509
14513
|
}
|
|
14510
14514
|
};
|
|
14511
14515
|
|
|
14512
14516
|
// src/@building/building.validate.ts
|
|
14513
14517
|
import { createHash } from "crypto";
|
|
14514
14518
|
|
|
14515
|
-
// src/@dictionaries/dictionaries.
|
|
14516
|
-
var
|
|
14519
|
+
// src/@dictionaries/dictionaries.enhanced.ts
|
|
14520
|
+
var dict_enhanced = {
|
|
14517
14521
|
"Tornado Warning": {
|
|
14518
14522
|
"Tornado Emergency": {
|
|
14519
14523
|
description: "tornado emergency"
|
|
@@ -14531,6 +14535,11 @@ var betterEventNames = {
|
|
|
14531
14535
|
},
|
|
14532
14536
|
"Radar Indicated Tornado Warning": {}
|
|
14533
14537
|
},
|
|
14538
|
+
"Fire Weather Warning": {
|
|
14539
|
+
"PDS Fire Weather Warning": {
|
|
14540
|
+
description: "particularly dangerous situation"
|
|
14541
|
+
}
|
|
14542
|
+
},
|
|
14534
14543
|
"Blizzard Warning": {
|
|
14535
14544
|
"PDS Blizzard Warning": {
|
|
14536
14545
|
description: "particularly dangerous situation"
|
|
@@ -14548,7 +14557,12 @@ var betterEventNames = {
|
|
|
14548
14557
|
},
|
|
14549
14558
|
"Tornado Watch": {
|
|
14550
14559
|
"PDS Tornado Watch": {
|
|
14551
|
-
|
|
14560
|
+
pdswatch: true
|
|
14561
|
+
}
|
|
14562
|
+
},
|
|
14563
|
+
"Severe Thunderstorm Watch": {
|
|
14564
|
+
"PDS Severe Thunderstorm Watch": {
|
|
14565
|
+
pdswatch: true
|
|
14552
14566
|
}
|
|
14553
14567
|
},
|
|
14554
14568
|
"Flash Flood Warning": {
|
|
@@ -14589,16 +14603,17 @@ var betterEventNames = {
|
|
|
14589
14603
|
|
|
14590
14604
|
// src/@building/building.enhance.ts
|
|
14591
14605
|
var getEventEnhancedName = (event) => {
|
|
14592
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
14606
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
14593
14607
|
const configurations = bootstrap.settings;
|
|
14594
14608
|
let name = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.event;
|
|
14595
14609
|
if (!((_b = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _b.BetterEventNames)) {
|
|
14596
14610
|
return name;
|
|
14597
14611
|
}
|
|
14598
14612
|
const damage = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat;
|
|
14599
|
-
const tornado = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters.tornado_threat;
|
|
14600
|
-
const
|
|
14601
|
-
|
|
14613
|
+
const tornado = (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.tornado_threat;
|
|
14614
|
+
const pdswatch = (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.watch_parameters) == null ? void 0 : _h.pds_watch;
|
|
14615
|
+
const description = (_j = (_i = event == null ? void 0 : event.properties) == null ? void 0 : _i.description) == null ? void 0 : _j.toLowerCase();
|
|
14616
|
+
for (const [eventKey, eventConfig] of Object.entries(dict_enhanced)) {
|
|
14602
14617
|
if (eventKey !== name) continue;
|
|
14603
14618
|
for (const [paramKey, paramValue] of Object.entries(eventConfig)) {
|
|
14604
14619
|
let matches = true;
|
|
@@ -14611,6 +14626,9 @@ var getEventEnhancedName = (event) => {
|
|
|
14611
14626
|
if (paramValue == null ? void 0 : paramValue.tornado) {
|
|
14612
14627
|
if (paramValue.tornado !== tornado) matches = false;
|
|
14613
14628
|
}
|
|
14629
|
+
if (paramValue == null ? void 0 : paramValue.pdswatch) {
|
|
14630
|
+
if (paramValue.pdswatch !== pdswatch) matches = false;
|
|
14631
|
+
}
|
|
14614
14632
|
if (matches) {
|
|
14615
14633
|
name = paramKey;
|
|
14616
14634
|
break;
|
|
@@ -14620,8 +14638,8 @@ var getEventEnhancedName = (event) => {
|
|
|
14620
14638
|
return name;
|
|
14621
14639
|
};
|
|
14622
14640
|
|
|
14623
|
-
// src/@dictionaries/dictionaries.
|
|
14624
|
-
var
|
|
14641
|
+
// src/@dictionaries/dictionaries.correlations.ts
|
|
14642
|
+
var dict_correlations = [
|
|
14625
14643
|
{ type: "Statement", name: "Statement", isCancel: false, isUpdate: false, isIssued: true, isStatement: true },
|
|
14626
14644
|
{ type: "Update", name: "Updated", isCancel: false, isUpdate: true, isIssued: false, isStatement: false },
|
|
14627
14645
|
{ type: "Cancel", name: "Cancelled", isCancel: true, isUpdate: false, isIssued: false, isStatement: false },
|
|
@@ -14636,8 +14654,8 @@ var statusCorrelationText = [
|
|
|
14636
14654
|
{ type: "Routine", name: "Routine", isCancel: false, isUpdate: true, isIssued: false, isStatement: false }
|
|
14637
14655
|
];
|
|
14638
14656
|
|
|
14639
|
-
// src/@dictionaries/dictionaries.
|
|
14640
|
-
var
|
|
14657
|
+
// src/@dictionaries/dictionaries.cancellation.ts
|
|
14658
|
+
var dict_cancellation = [
|
|
14641
14659
|
"has been cancelled",
|
|
14642
14660
|
"subsided sufficiently for the advisory to be cancelled",
|
|
14643
14661
|
"has been cancelled",
|
|
@@ -14649,24 +14667,28 @@ var eventCancelMessages = [
|
|
|
14649
14667
|
"has weakened below severe"
|
|
14650
14668
|
];
|
|
14651
14669
|
|
|
14652
|
-
// src/@dictionaries/dictionaries.
|
|
14653
|
-
var
|
|
14670
|
+
// src/@dictionaries/dictionaries.test.ts
|
|
14671
|
+
var dict_testing = [
|
|
14654
14672
|
`This is a test message`,
|
|
14655
14673
|
`Monitoring message only.`,
|
|
14656
|
-
`THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY
|
|
14674
|
+
`THIS_MESSAGE_IS_FOR_TEST_PURPOSES_ONLY`,
|
|
14675
|
+
"TEST MESSAGE"
|
|
14657
14676
|
];
|
|
14658
14677
|
|
|
14659
|
-
// src/@dictionaries/dictionaries.
|
|
14660
|
-
var
|
|
14678
|
+
// src/@dictionaries/dictionaries.products.ts
|
|
14679
|
+
var dict_products = {
|
|
14661
14680
|
"O": "Operational Product",
|
|
14662
14681
|
"T": "Test Product",
|
|
14663
14682
|
"E": "Experimental Product",
|
|
14664
14683
|
"X": "Experimental Product (Non-Operational)"
|
|
14665
14684
|
};
|
|
14666
14685
|
|
|
14667
|
-
// src/@dictionaries/dictionaries.
|
|
14668
|
-
var
|
|
14686
|
+
// src/@dictionaries/dictionaries.hail.ts
|
|
14687
|
+
var dict_hail = {
|
|
14688
|
+
".25": "Pea",
|
|
14689
|
+
".50": "Penny",
|
|
14669
14690
|
".75": "Penny",
|
|
14691
|
+
"Up to .75": "Penny",
|
|
14670
14692
|
".88": "Nickel",
|
|
14671
14693
|
"0.75": "Penny",
|
|
14672
14694
|
"0.88": "Nickel",
|
|
@@ -14682,25 +14704,25 @@ var hailStrings = {
|
|
|
14682
14704
|
|
|
14683
14705
|
// src/@building/building.signature.ts
|
|
14684
14706
|
var getEventSignature = (event) => {
|
|
14685
|
-
var _a, _b, _c, _d, _e, _f;
|
|
14707
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
14686
14708
|
const properties2 = event == null ? void 0 : event.properties;
|
|
14687
14709
|
const vtec2 = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.vtec;
|
|
14688
|
-
const status =
|
|
14689
|
-
const csig =
|
|
14710
|
+
const status = dict_correlations.find((c) => c.type === (properties2 == null ? void 0 : properties2.status));
|
|
14711
|
+
const csig = dict_cancellation.find((sig) => properties2.description.toLowerCase().includes(sig.toLowerCase()));
|
|
14690
14712
|
properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_issued: true, is_test: false });
|
|
14691
|
-
if (properties2.parameters.estimated_hail_size) {
|
|
14692
|
-
properties2.parameters.estimated_hail_size += ` (${(
|
|
14713
|
+
if ((_c = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _c.estimated_hail_size) {
|
|
14714
|
+
properties2.parameters.estimated_hail_size += ` (${(_e = dict_hail[(_d = properties2 == null ? void 0 : properties2.parameters) == null ? void 0 : _d.estimated_hail_size]) != null ? _e : "--"})`;
|
|
14693
14715
|
}
|
|
14694
14716
|
if (status) {
|
|
14695
|
-
properties2.status = (
|
|
14717
|
+
properties2.status = (_f = status.name) != null ? _f : properties2.status;
|
|
14696
14718
|
properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_updated: !!status.isUpdate, is_issued: !!status.isIssued, is_expired: !!status.isCancel, is_statement: !!status.isStatement });
|
|
14697
14719
|
}
|
|
14698
14720
|
if (csig) {
|
|
14699
14721
|
properties2.status_metadata = __spreadProps(__spreadValues({}, properties2.status_metadata), { is_expired: true });
|
|
14700
14722
|
}
|
|
14701
|
-
const getProduct = (
|
|
14702
|
-
const isTestProduct =
|
|
14703
|
-
if (isTestProduct ||
|
|
14723
|
+
const getProduct = (_h = (_g = vtec2 == null ? void 0 : vtec2.vtec) == null ? void 0 : _g.split(`.`)[0]) == null ? void 0 : _h.replace(`/`, ``);
|
|
14724
|
+
const isTestProduct = dict_products[getProduct] == `Test Product`;
|
|
14725
|
+
if (isTestProduct || dict_testing.some((sig) => {
|
|
14704
14726
|
var _a2, _b2, _c2, _d2;
|
|
14705
14727
|
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());
|
|
14706
14728
|
})) {
|
|
@@ -14727,674 +14749,1185 @@ var setHash = (event, entry) => {
|
|
|
14727
14749
|
}
|
|
14728
14750
|
};
|
|
14729
14751
|
|
|
14730
|
-
// src/@modules/@
|
|
14731
|
-
|
|
14732
|
-
|
|
14733
|
-
|
|
14734
|
-
|
|
14735
|
-
|
|
14736
|
-
|
|
14737
|
-
|
|
14738
|
-
|
|
14739
|
-
|
|
14740
|
-
|
|
14741
|
-
|
|
14742
|
-
|
|
14743
|
-
|
|
14744
|
-
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
status: -1,
|
|
14759
|
-
message: (_a2 = error.message) != null ? _a2 : `Unknown Error`
|
|
14760
|
-
});
|
|
14761
|
-
}
|
|
14762
|
-
if (response2.statusCode < 200 || response2.statusCode >= 300) {
|
|
14763
|
-
return resolve6({
|
|
14764
|
-
error: true,
|
|
14765
|
-
options: requestOptions,
|
|
14766
|
-
status: (_b2 = response2.statusCode) != null ? _b2 : -1,
|
|
14767
|
-
message: `HTTP Status Code ${(_c2 = response2.statusCode) != null ? _c2 : `Unknown Status Code`} (${body})`
|
|
14768
|
-
});
|
|
14769
|
-
}
|
|
14770
|
-
if (body == void 0 || body == null) {
|
|
14771
|
-
return resolve6({
|
|
14772
|
-
error: true,
|
|
14773
|
-
options: requestOptions,
|
|
14774
|
-
status: (_d2 = response2.statusCode) != null ? _d2 : -1,
|
|
14775
|
-
message: `Empty Response Body`
|
|
14776
|
-
});
|
|
14777
|
-
}
|
|
14778
|
-
resolve6({
|
|
14779
|
-
error: false,
|
|
14780
|
-
options: requestOptions,
|
|
14781
|
-
status: (_e2 = response2.statusCode) != null ? _e2 : -1,
|
|
14782
|
-
message: body
|
|
14783
|
-
});
|
|
14784
|
-
});
|
|
14785
|
-
});
|
|
14786
|
-
});
|
|
14752
|
+
// src/@modules/@eas/eas.getWavPCM16.ts
|
|
14753
|
+
var getWavPCM16 = (buffer) => {
|
|
14754
|
+
if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
|
|
14755
|
+
return null;
|
|
14756
|
+
}
|
|
14757
|
+
let fmt = null;
|
|
14758
|
+
let data = null;
|
|
14759
|
+
let i = 12;
|
|
14760
|
+
while (i + 8 <= buffer.length) {
|
|
14761
|
+
const id2 = buffer.toString("ascii", i, i + 4);
|
|
14762
|
+
const size = buffer.readUInt32LE(i + 4);
|
|
14763
|
+
const start = i + 8;
|
|
14764
|
+
const end = start + size;
|
|
14765
|
+
if (id2 === "fmt ") fmt = buffer.slice(start, end);
|
|
14766
|
+
if (id2 === "data") data = buffer.slice(start, end);
|
|
14767
|
+
i = end + size % 2;
|
|
14768
|
+
}
|
|
14769
|
+
if (!fmt || !data) return null;
|
|
14770
|
+
const audioFormat = fmt.readUInt16LE(0);
|
|
14771
|
+
const channels = fmt.readUInt16LE(2);
|
|
14772
|
+
const sampleRate = fmt.readUInt32LE(4);
|
|
14773
|
+
const bitsPerSample = fmt.readUInt16LE(14);
|
|
14774
|
+
if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
|
|
14775
|
+
return null;
|
|
14776
|
+
}
|
|
14777
|
+
const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
|
|
14778
|
+
return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
|
|
14779
|
+
};
|
|
14787
14780
|
|
|
14788
|
-
// src/@
|
|
14789
|
-
var
|
|
14790
|
-
|
|
14791
|
-
|
|
14792
|
-
const
|
|
14793
|
-
const
|
|
14794
|
-
let
|
|
14795
|
-
|
|
14796
|
-
|
|
14797
|
-
|
|
14798
|
-
|
|
14799
|
-
|
|
14800
|
-
|
|
14801
|
-
const th = (_b2 = event.parameters.wind_threat) != null ? _b2 : null;
|
|
14802
|
-
const combined = [val, th].filter(Boolean).join(" ");
|
|
14803
|
-
return combined ? `**Wind Gusts**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14804
|
-
})(),
|
|
14805
|
-
(() => {
|
|
14806
|
-
var _a2, _b2;
|
|
14807
|
-
const val = (_a2 = event.parameters.estimated_hail_size) != null ? _a2 : null;
|
|
14808
|
-
const th = (_b2 = event.parameters.hail_threat) != null ? _b2 : null;
|
|
14809
|
-
return (val != null ? val : th) ? `**Hail Threat**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14810
|
-
})(),
|
|
14811
|
-
event.parameters.damage_threat ? `**Damage Threat**: ${event.parameters.damage_threat}` : null,
|
|
14812
|
-
event.parameters.flood_threat ? `**Flood Threat**: ${event.parameters.flood_threat}` : null,
|
|
14813
|
-
event.parameters.tornado_threat ? `**Tornado Threat**: ${event.parameters.tornado_threat}` : null,
|
|
14814
|
-
event.spc_parameters.spc_max_tornado ? `**Max Tornado Threat**: ${event.spc_parameters.spc_max_tornado}` : null,
|
|
14815
|
-
event.spc_parameters.spc_max_hail ? `**Max Hail Threat**: ${event.spc_parameters.spc_max_hail}` : null,
|
|
14816
|
-
event.spc_parameters.spc_max_wind ? `**Max Wind Threat**: ${event.spc_parameters.spc_max_wind}` : null,
|
|
14817
|
-
event.spc_parameters.spc_watch_issuance ? `**Watch Issuance**: ${event.spc_parameters.spc_watch_issuance}%` : null,
|
|
14818
|
-
event.watch_parameters.watch_number ? `**Watch Number**: ${event.watch_parameters.watch_number}` : null,
|
|
14819
|
-
event.watch_parameters.strong_tornadoes_probability ? `**Strong Tornadoes Probability**: ${event.watch_parameters.strong_tornadoes_probability}%` : null,
|
|
14820
|
-
event.watch_parameters.additional_tornadoes_probability ? `**Additional Tornadoes Probability**: ${event.watch_parameters.additional_tornadoes_probability}%` : null,
|
|
14821
|
-
event.watch_parameters.combined_hail_wind_probability ? `**Combined Hail/Wind Probability**: ${event.watch_parameters.combined_hail_wind_probability}%` : null,
|
|
14822
|
-
event.watch_parameters.severe_hail_probability ? `**Severe Hail Probability**: ${event.watch_parameters.severe_hail_probability}%` : null,
|
|
14823
|
-
event.watch_parameters.hail_2in_probability ? `**Hail \u22652in Probability**: ${event.watch_parameters.hail_2in_probability}%` : null,
|
|
14824
|
-
event.watch_parameters.max_hail_in ? `**Max Hail Inches**: ${event.watch_parameters.max_hail_in}` : null,
|
|
14825
|
-
event.watch_parameters.severe_wind_probability ? `**Severe Wind Probability**: ${event.watch_parameters.severe_wind_probability}%` : null,
|
|
14826
|
-
event.watch_parameters.max_wind_surface ? `**Max Surface Wind**: ${event.watch_parameters.max_wind_surface}` : null,
|
|
14827
|
-
event.watch_parameters.max_tops_x100feet ? `**Max Tops (x100 feet)**: ${event.watch_parameters.max_tops_x100feet}` : null,
|
|
14828
|
-
((_a = event.parameters.tags) == null ? void 0 : _a.length) > 0 ? `**Tags**: ${event.parameters.tags.join(", ")}` : null,
|
|
14829
|
-
(() => {
|
|
14830
|
-
var _a2, _b2, _c2, _d2, _e2, _f2;
|
|
14831
|
-
const val = (_c2 = (_b2 = (_a2 = event.geocode) == null ? void 0 : _a2.office) == null ? void 0 : _b2.name) != null ? _c2 : `N/A`;
|
|
14832
|
-
const th = (_f2 = (_e2 = (_d2 = event.geocode) == null ? void 0 : _d2.office) == null ? void 0 : _e2.office) != null ? _f2 : null;
|
|
14833
|
-
return (val != null ? val : th) ? `**Sender**: ${val} ${th ? `(${th})` : ""}` : null;
|
|
14834
|
-
})(),
|
|
14835
|
-
((_b = event.metadata) == null ? void 0 : _b.tracking) ? `**Tracking**: ${event.metadata.tracking}` : null,
|
|
14836
|
-
((_c = event.metadata.history) == null ? void 0 : _c.length) > 0 ? `**Logs**: ${event.metadata.history.length}` : null,
|
|
14837
|
-
(() => {
|
|
14838
|
-
var _a2;
|
|
14839
|
-
if (event.status == `Expired`) {
|
|
14840
|
-
return null;
|
|
14841
|
-
}
|
|
14842
|
-
const desc = ((_a2 = event.description) != null ? _a2 : "").split("\n").map((l) => l.trim()).filter(Boolean).join("\n");
|
|
14843
|
-
return desc ? "```\n" + desc + "\n```" : null;
|
|
14844
|
-
})()
|
|
14845
|
-
].filter(Boolean).join("\n");
|
|
14846
|
-
const isLimited = setTimeoutAction({ identifier: options.webhook.webhook, interval: options.webhook.rate, max: options.webhook.rate, addTime: true });
|
|
14847
|
-
if (isLimited.limited) {
|
|
14848
|
-
return;
|
|
14781
|
+
// src/@modules/@eas/eas.getSampledPCM16.ts
|
|
14782
|
+
var getSampledPCM16 = (int16, originalRate, targetRate) => {
|
|
14783
|
+
if (originalRate === targetRate) return int16;
|
|
14784
|
+
const ratio = targetRate / originalRate;
|
|
14785
|
+
const outLen = Math.max(1, Math.round(int16.length * ratio));
|
|
14786
|
+
const out = new Int16Array(outLen);
|
|
14787
|
+
for (let i = 0; i < outLen; i++) {
|
|
14788
|
+
const pos = i / ratio;
|
|
14789
|
+
const i0 = Math.floor(pos);
|
|
14790
|
+
const i1 = Math.min(i0 + 1, int16.length - 1);
|
|
14791
|
+
const frac = pos - i0;
|
|
14792
|
+
const v = int16[i0] * (1 - frac) + int16[i1] * frac;
|
|
14793
|
+
out[i] = Math.round(v);
|
|
14849
14794
|
}
|
|
14850
|
-
|
|
14851
|
-
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
const
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14864
|
-
|
|
14865
|
-
|
|
14866
|
-
embeds: [embed]
|
|
14867
|
-
}));
|
|
14868
|
-
if (settings.upload) {
|
|
14869
|
-
form.append("file", Buffer.from(JSON.stringify(getCleanedEvent(event), null, 2)), {
|
|
14870
|
-
filename: `${event.event}_${event.status}_${event.metadata.tracking}.json`,
|
|
14871
|
-
contentType: "application/json"
|
|
14872
|
-
});
|
|
14795
|
+
return out;
|
|
14796
|
+
};
|
|
14797
|
+
|
|
14798
|
+
// src/@modules/@eas/eas.getPCMToFloat.ts
|
|
14799
|
+
var getPCMToFloat = (int16) => {
|
|
14800
|
+
const out = new Float32Array(int16.length);
|
|
14801
|
+
for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
|
|
14802
|
+
return out;
|
|
14803
|
+
};
|
|
14804
|
+
|
|
14805
|
+
// src/@modules/@eas/eas.getFloatPCM16.ts
|
|
14806
|
+
var getFloatPCM16 = (float32) => {
|
|
14807
|
+
const out = new Int16Array(float32.length);
|
|
14808
|
+
for (let i = 0; i < float32.length; i++) {
|
|
14809
|
+
let v = Math.max(-1, Math.min(1, float32[i]));
|
|
14810
|
+
out[i] = Math.round(v * 32767);
|
|
14873
14811
|
}
|
|
14874
|
-
|
|
14875
|
-
|
|
14876
|
-
timeout: 2e3,
|
|
14877
|
-
method: `POST`,
|
|
14878
|
-
headers: form.getHeaders(),
|
|
14879
|
-
body: form
|
|
14880
|
-
});
|
|
14881
|
-
});
|
|
14812
|
+
return out;
|
|
14813
|
+
};
|
|
14882
14814
|
|
|
14883
|
-
// src/@
|
|
14884
|
-
var
|
|
14885
|
-
const
|
|
14886
|
-
const
|
|
14887
|
-
const
|
|
14888
|
-
|
|
14889
|
-
|
|
14890
|
-
|
|
14891
|
-
|
|
14892
|
-
|
|
14893
|
-
|
|
14894
|
-
|
|
14895
|
-
|
|
14896
|
-
|
|
14897
|
-
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14815
|
+
// src/@modules/@eas/eas.setRadioEffect.ts
|
|
14816
|
+
var setRadioEffect = (int16, sampleRate) => {
|
|
14817
|
+
const hpCut = 3555;
|
|
14818
|
+
const lpCut = 1600;
|
|
14819
|
+
const x = getPCMToFloat(int16);
|
|
14820
|
+
const dt = 1 / sampleRate;
|
|
14821
|
+
const rcHP = 1 / (2 * Math.PI * hpCut);
|
|
14822
|
+
const aHP = rcHP / (rcHP + dt);
|
|
14823
|
+
let yHP = 0, xPrev = 0;
|
|
14824
|
+
for (let i = 0; i < x.length; i++) {
|
|
14825
|
+
const xi = x[i];
|
|
14826
|
+
yHP = aHP * (yHP + xi - xPrev);
|
|
14827
|
+
xPrev = xi;
|
|
14828
|
+
x[i] = yHP;
|
|
14829
|
+
}
|
|
14830
|
+
const rcLP = 1 / (2 * Math.PI * lpCut);
|
|
14831
|
+
const aLP = dt / (rcLP + dt);
|
|
14832
|
+
let yLP = 0;
|
|
14833
|
+
for (let i = 0; i < x.length; i++) {
|
|
14834
|
+
yLP = yLP + aLP * (x[i] - yLP);
|
|
14835
|
+
x[i] = yLP;
|
|
14836
|
+
}
|
|
14837
|
+
const compGain = 2;
|
|
14838
|
+
const norm = Math.tanh(compGain);
|
|
14839
|
+
for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
|
|
14840
|
+
return getFloatPCM16(x);
|
|
14841
|
+
};
|
|
14842
|
+
|
|
14843
|
+
// src/@modules/@eas/eas.setAFSK.ts
|
|
14844
|
+
var setAFSK = (bits, sampleRate) => {
|
|
14845
|
+
const baud = 520.83;
|
|
14846
|
+
const markFreq = 2083.3;
|
|
14847
|
+
const spaceFreq = 1562.5;
|
|
14848
|
+
const amplitude = 0.6;
|
|
14849
|
+
const twoPi = Math.PI * 2;
|
|
14850
|
+
const result = [];
|
|
14851
|
+
let phase = 0;
|
|
14852
|
+
let frac = 0;
|
|
14853
|
+
for (let b = 0; b < bits.length; b++) {
|
|
14854
|
+
const bit = bits[b];
|
|
14855
|
+
const freq = bit ? markFreq : spaceFreq;
|
|
14856
|
+
const samplesPerBit = sampleRate / baud + frac;
|
|
14857
|
+
const n = Math.round(samplesPerBit);
|
|
14858
|
+
frac = samplesPerBit - n;
|
|
14859
|
+
const inc = twoPi * freq / sampleRate;
|
|
14860
|
+
for (let i = 0; i < n; i++) {
|
|
14861
|
+
result.push(Math.round(Math.sin(phase) * amplitude * 32767));
|
|
14862
|
+
phase += inc;
|
|
14863
|
+
if (phase > twoPi) phase -= twoPi;
|
|
14905
14864
|
}
|
|
14906
14865
|
}
|
|
14907
|
-
|
|
14866
|
+
const fadeSamples = Math.floor(sampleRate * 2e-3);
|
|
14867
|
+
for (let i = 0; i < fadeSamples; i++) {
|
|
14868
|
+
const gain = i / fadeSamples;
|
|
14869
|
+
result[i] = Math.round(result[i] * gain);
|
|
14870
|
+
result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
|
|
14871
|
+
}
|
|
14872
|
+
return Int16Array.from(result);
|
|
14873
|
+
};
|
|
14908
14874
|
|
|
14909
|
-
// src/@modules/@
|
|
14910
|
-
var
|
|
14911
|
-
|
|
14912
|
-
|
|
14875
|
+
// src/@modules/@eas/eas.setAsciiToBits.ts
|
|
14876
|
+
var setAsciiToBits = (str) => {
|
|
14877
|
+
const bits = [];
|
|
14878
|
+
for (let i = 0; i < str.length; i++) {
|
|
14879
|
+
const c = str.charCodeAt(i) & 255;
|
|
14880
|
+
bits.push(0);
|
|
14881
|
+
for (let b = 0; b < 8; b++) bits.push(c >> b & 1);
|
|
14882
|
+
bits.push(1, 1);
|
|
14913
14883
|
}
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
|
|
14931
|
-
|
|
14932
|
-
|
|
14933
|
-
|
|
14934
|
-
|
|
14935
|
-
|
|
14936
|
-
|
|
14937
|
-
|
|
14938
|
-
|
|
14939
|
-
|
|
14940
|
-
|
|
14941
|
-
|
|
14942
|
-
|
|
14943
|
-
|
|
14944
|
-
const haversineMiles = (a, b) => {
|
|
14945
|
-
const R = 3958.8;
|
|
14946
|
-
const dLat = toRadians(b[1] - a[1]);
|
|
14947
|
-
const dLon = toRadians(b[0] - a[0]);
|
|
14948
|
-
const lat1 = toRadians(a[1]);
|
|
14949
|
-
const lat2 = toRadians(b[1]);
|
|
14950
|
-
const sinDLat = Math.sin(dLat / 2);
|
|
14951
|
-
const sinDLon = Math.sin(dLon / 2);
|
|
14952
|
-
const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
|
|
14953
|
-
return R * c;
|
|
14954
|
-
};
|
|
14955
|
-
let minDistance = Infinity;
|
|
14956
|
-
let closestPoint = null;
|
|
14957
|
-
for (const poly of polys) {
|
|
14958
|
-
const outer = poly[0];
|
|
14959
|
-
const holes = poly.slice(1);
|
|
14960
|
-
if (pointInRing(point, outer)) {
|
|
14961
|
-
let inHole = false;
|
|
14962
|
-
for (const hole of holes) {
|
|
14963
|
-
if (pointInRing(point, hole)) {
|
|
14964
|
-
inHole = true;
|
|
14965
|
-
break;
|
|
14966
|
-
}
|
|
14967
|
-
}
|
|
14968
|
-
if (!inHole) {
|
|
14969
|
-
return { proximity: true, point, distance: 0 };
|
|
14970
|
-
}
|
|
14971
|
-
}
|
|
14972
|
-
for (const ring of poly) {
|
|
14973
|
-
for (let i = 0; i < ring.length - 1; i++) {
|
|
14974
|
-
const start = [ring[i][0], ring[i][1]];
|
|
14975
|
-
const end = [ring[i + 1][0], ring[i + 1][1]];
|
|
14976
|
-
const A = lon - start[0];
|
|
14977
|
-
const B = lat - start[1];
|
|
14978
|
-
const C = end[0] - start[0];
|
|
14979
|
-
const D = end[1] - start[1];
|
|
14980
|
-
const lenSq = C * C + D * D;
|
|
14981
|
-
const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
|
|
14982
|
-
const candidate = [start[0] + t * C, start[1] + t * D];
|
|
14983
|
-
const dist = haversineMiles([lon, lat], candidate);
|
|
14984
|
-
if (!isNaN(dist) && dist < minDistance) {
|
|
14985
|
-
minDistance = Number(dist.toFixed(3));
|
|
14986
|
-
closestPoint = candidate;
|
|
14987
|
-
}
|
|
14988
|
-
}
|
|
14884
|
+
return bits;
|
|
14885
|
+
};
|
|
14886
|
+
|
|
14887
|
+
// src/@modules/@eas/eas.getMergedPCM16.ts
|
|
14888
|
+
var getMergedPCM16 = (arrays) => {
|
|
14889
|
+
let total = 0;
|
|
14890
|
+
for (const a of arrays) total += a.length;
|
|
14891
|
+
const out = new Int16Array(total);
|
|
14892
|
+
let o = 0;
|
|
14893
|
+
for (const a of arrays) {
|
|
14894
|
+
out.set(a, o);
|
|
14895
|
+
o += a.length;
|
|
14896
|
+
}
|
|
14897
|
+
return out;
|
|
14898
|
+
};
|
|
14899
|
+
|
|
14900
|
+
// src/@modules/@eas/eas.setSameHeader.ts
|
|
14901
|
+
var setSameHeader = (vtec2, repeats, sampleRate = 8e3, options = {}) => {
|
|
14902
|
+
var _a, _b;
|
|
14903
|
+
const preMarkSec = (_a = options.preMarkSec) != null ? _a : 0.3;
|
|
14904
|
+
const gapSec = (_b = options.gapSec) != null ? _b : 0.1;
|
|
14905
|
+
const bursts = [];
|
|
14906
|
+
const gap = new Int16Array(Math.floor(gapSec * sampleRate));
|
|
14907
|
+
for (let i = 0; i < repeats; i++) {
|
|
14908
|
+
const bodyBits = setAsciiToBits(vtec2);
|
|
14909
|
+
const body = setAFSK(bodyBits, sampleRate);
|
|
14910
|
+
const extendedBodyDuration = Math.round(preMarkSec * sampleRate);
|
|
14911
|
+
const extendedBody = new Int16Array(extendedBodyDuration + gap.length);
|
|
14912
|
+
for (let j2 = 0; j2 < extendedBodyDuration; j2++) {
|
|
14913
|
+
extendedBody[j2] = Math.round(body[j2 % body.length] * 0.2);
|
|
14989
14914
|
}
|
|
14915
|
+
extendedBody.set(gap, extendedBodyDuration);
|
|
14916
|
+
bursts.push(extendedBody);
|
|
14917
|
+
if (i !== repeats - 1) bursts.push(gap);
|
|
14990
14918
|
}
|
|
14991
|
-
|
|
14992
|
-
|
|
14919
|
+
return getMergedPCM16(bursts);
|
|
14920
|
+
};
|
|
14921
|
+
|
|
14922
|
+
// src/@modules/@eas/eas.setAttentionTone.ts
|
|
14923
|
+
var setAttentionTone = (ms, sampleRate) => {
|
|
14924
|
+
const len = Math.floor(ms * sampleRate);
|
|
14925
|
+
const out = new Int16Array(len);
|
|
14926
|
+
const f1 = 853;
|
|
14927
|
+
const f2 = 960;
|
|
14928
|
+
const twoPi = Math.PI * 2;
|
|
14929
|
+
const amp = 0.1;
|
|
14930
|
+
const fadeLen = Math.floor(sampleRate * 0);
|
|
14931
|
+
for (let i = 0; i < len; i++) {
|
|
14932
|
+
const t = i / sampleRate;
|
|
14933
|
+
const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
|
|
14934
|
+
let gain = 1;
|
|
14935
|
+
if (i < fadeLen) gain = i / fadeLen;
|
|
14936
|
+
else if (i > len - fadeLen) gain = (len - i) / fadeLen;
|
|
14937
|
+
const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
|
|
14938
|
+
out[i] = Math.round(v * 32767);
|
|
14993
14939
|
}
|
|
14994
|
-
|
|
14995
|
-
const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
|
|
14996
|
-
const distanceMeters = Math.round(distanceKm * 1e3);
|
|
14997
|
-
return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
|
|
14940
|
+
return out;
|
|
14998
14941
|
};
|
|
14999
14942
|
|
|
15000
|
-
// src/@
|
|
15001
|
-
var
|
|
15002
|
-
|
|
15003
|
-
|
|
15004
|
-
|
|
15005
|
-
|
|
15006
|
-
|
|
14943
|
+
// src/@modules/@eas/eas.setNoise.ts
|
|
14944
|
+
var setNoise = (int16, noiseLevel = 0.02) => {
|
|
14945
|
+
const x = getPCMToFloat(int16);
|
|
14946
|
+
for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
|
|
14947
|
+
let peak = 0;
|
|
14948
|
+
for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
|
|
14949
|
+
if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
|
|
14950
|
+
return getFloatPCM16(x);
|
|
14951
|
+
};
|
|
14952
|
+
|
|
14953
|
+
// src/@modules/@eas/eas.getPCM16.ts
|
|
14954
|
+
var getPCM16 = (samples, sampleRate) => {
|
|
14955
|
+
let o = 0;
|
|
14956
|
+
const bytesPerSample = 2;
|
|
14957
|
+
const blockAlign = 1 * bytesPerSample;
|
|
14958
|
+
const byteRate = sampleRate * blockAlign;
|
|
14959
|
+
const subchunk2Size = samples.length * bytesPerSample;
|
|
14960
|
+
const chunkSize = 36 + subchunk2Size;
|
|
14961
|
+
const buffer = Buffer.alloc(44 + subchunk2Size);
|
|
14962
|
+
buffer.write("RIFF", o);
|
|
14963
|
+
o += 4;
|
|
14964
|
+
buffer.writeUInt32LE(chunkSize, o);
|
|
14965
|
+
o += 4;
|
|
14966
|
+
buffer.write("WAVE", o);
|
|
14967
|
+
o += 4;
|
|
14968
|
+
buffer.write("fmt ", o);
|
|
14969
|
+
o += 4;
|
|
14970
|
+
buffer.writeUInt32LE(16, o);
|
|
14971
|
+
o += 4;
|
|
14972
|
+
buffer.writeUInt16LE(1, o);
|
|
14973
|
+
o += 2;
|
|
14974
|
+
buffer.writeUInt16LE(1, o);
|
|
14975
|
+
o += 2;
|
|
14976
|
+
buffer.writeUInt32LE(sampleRate, o);
|
|
14977
|
+
o += 4;
|
|
14978
|
+
buffer.writeUInt32LE(byteRate, o);
|
|
14979
|
+
o += 4;
|
|
14980
|
+
buffer.writeUInt16LE(blockAlign, o);
|
|
14981
|
+
o += 2;
|
|
14982
|
+
buffer.writeUInt16LE(16, o);
|
|
14983
|
+
o += 2;
|
|
14984
|
+
buffer.write("data", o);
|
|
14985
|
+
o += 4;
|
|
14986
|
+
buffer.writeUInt32LE(subchunk2Size, o);
|
|
14987
|
+
o += 4;
|
|
14988
|
+
for (let i = 0; i < samples.length; i++, o += 2) {
|
|
14989
|
+
buffer.writeInt16LE(samples[i].value, o);
|
|
15007
14990
|
}
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
14991
|
+
return buffer;
|
|
14992
|
+
};
|
|
14993
|
+
|
|
14994
|
+
// src/@modules/@eas/eas.getTTS.ts
|
|
14995
|
+
import { platform } from "os";
|
|
14996
|
+
import { writeFileSync } from "fs";
|
|
14997
|
+
import { execSync } from "child_process";
|
|
14998
|
+
var getTTS = (text2, outputPath) => __async(null, null, function* () {
|
|
14999
|
+
const vPlatform = platform();
|
|
15000
|
+
switch (vPlatform) {
|
|
15001
|
+
case "win32": {
|
|
15002
|
+
try {
|
|
15003
|
+
const txtPath = outputPath + ".txt";
|
|
15004
|
+
writeFileSync(txtPath, text2, "utf8");
|
|
15005
|
+
const command = [
|
|
15006
|
+
"Add-Type -AssemblyName System.Speech;",
|
|
15007
|
+
`$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer;`,
|
|
15008
|
+
`$text = Get-Content -Raw -LiteralPath '${txtPath}';`,
|
|
15009
|
+
`$speak.SetOutputToWaveFile('${outputPath}');`,
|
|
15010
|
+
`$speak.Speak($text);`,
|
|
15011
|
+
`$speak.Dispose();`
|
|
15012
|
+
].join(" ");
|
|
15013
|
+
execSync(`powershell -Command "${command}"`, { stdio: "inherit" });
|
|
15014
|
+
} catch (error) {
|
|
15015
|
+
console.error("Error occurred while generating TTS:", error);
|
|
15016
|
+
}
|
|
15017
|
+
break;
|
|
15026
15018
|
}
|
|
15019
|
+
case "linux":
|
|
15020
|
+
try {
|
|
15021
|
+
execSync(`espeak -w "${outputPath}" "${text2.replace(/"/g, '\\"')}"`);
|
|
15022
|
+
} catch (e) {
|
|
15023
|
+
}
|
|
15024
|
+
break;
|
|
15025
|
+
default:
|
|
15026
|
+
break;
|
|
15027
15027
|
}
|
|
15028
|
-
return {
|
|
15029
|
-
nodes: metadata.nodes,
|
|
15030
|
-
filtered: metadata.proximity,
|
|
15031
|
-
updated: Date.now()
|
|
15032
|
-
};
|
|
15033
15028
|
});
|
|
15034
15029
|
|
|
15035
|
-
// src/@
|
|
15036
|
-
var
|
|
15037
|
-
const
|
|
15038
|
-
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15043
|
-
|
|
15044
|
-
|
|
15045
|
-
|
|
15046
|
-
|
|
15047
|
-
|
|
15048
|
-
|
|
15049
|
-
|
|
15050
|
-
|
|
15051
|
-
|
|
15052
|
-
|
|
15053
|
-
|
|
15030
|
+
// src/@modules/@eas/eas.getCleanDescription.ts
|
|
15031
|
+
var getCleanDescription = (message) => {
|
|
15032
|
+
const patches = [
|
|
15033
|
+
{ regex: /\.{3,}/g, replacement: ". " },
|
|
15034
|
+
{ regex: /\bUTC\b/g, replacement: "Coordinated Universal Time" },
|
|
15035
|
+
{ regex: /\bGMT\b/g, replacement: "Greenwich Mean Time" },
|
|
15036
|
+
{ regex: /\bEST\b(?!\w)/g, replacement: "Eastern Standard Time" },
|
|
15037
|
+
{ regex: /\bEDT\b(?!\w)/g, replacement: "Eastern Daylight Time" },
|
|
15038
|
+
{ regex: /\bCST\b(?!\w)/g, replacement: "Central Standard Time" },
|
|
15039
|
+
{ regex: /\bCDT\b(?!\w)/g, replacement: "Central Daylight Time" },
|
|
15040
|
+
{ regex: /\bMST\b(?!\w)/g, replacement: "Mountain Standard Time" },
|
|
15041
|
+
{ regex: /\bMDT\b(?!\w)/g, replacement: "Mountain Daylight Time" },
|
|
15042
|
+
{ regex: /\bPST\b(?!\w)/g, replacement: "Pacific Standard Time" },
|
|
15043
|
+
{ regex: /\bPDT\b(?!\w)/g, replacement: "Pacific Daylight Time" },
|
|
15044
|
+
{ regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
|
|
15045
|
+
{ regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
|
|
15046
|
+
{ regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
|
|
15047
|
+
{ regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
|
|
15048
|
+
{ regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
|
|
15049
|
+
{ regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
|
|
15050
|
+
{ regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
|
|
15051
|
+
{ regex: /\bkt\b(?!\w)/g, replacement: "knots" },
|
|
15052
|
+
{ regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
|
|
15053
|
+
{ regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
|
|
15054
|
+
{ regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
|
|
15055
|
+
{ regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
|
|
15056
|
+
{ regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
|
|
15057
|
+
{ regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
|
|
15058
|
+
{ regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
|
|
15059
|
+
{ regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
|
|
15060
|
+
{ regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
|
|
15061
|
+
{ regex: /\bin.\b(?!\w)/g, replacement: "inches" },
|
|
15062
|
+
{ regex: /\bft\b(?!\w)/g, replacement: "feet" },
|
|
15063
|
+
{ regex: /\bmi\b(?!\w)/g, replacement: "miles" },
|
|
15064
|
+
{ regex: /\bhr\b(?!\w)/g, replacement: "hour" },
|
|
15065
|
+
{ regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
|
|
15066
|
+
{ regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
|
|
15067
|
+
{ regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
|
|
15068
|
+
{ regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
|
|
15069
|
+
{ regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
|
|
15070
|
+
{ regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
|
|
15071
|
+
{ regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
|
|
15072
|
+
{ regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
|
|
15073
|
+
{ regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
|
|
15074
|
+
{ regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
|
|
15075
|
+
{ regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
|
|
15076
|
+
{ regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
|
|
15077
|
+
{ regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
|
|
15078
|
+
];
|
|
15079
|
+
const hours = {
|
|
15080
|
+
0: "twelve",
|
|
15081
|
+
1: "one",
|
|
15082
|
+
2: "two",
|
|
15083
|
+
3: "three",
|
|
15084
|
+
4: "four",
|
|
15085
|
+
5: "five",
|
|
15086
|
+
6: "six",
|
|
15087
|
+
7: "seven",
|
|
15088
|
+
8: "eight",
|
|
15089
|
+
9: "nine",
|
|
15090
|
+
10: "ten",
|
|
15091
|
+
11: "eleven",
|
|
15092
|
+
12: "twelve"
|
|
15093
|
+
};
|
|
15094
|
+
const minWord = (m) => m === 0 ? "o'clock" : m < 10 ? `oh ${m}` : `${m}`;
|
|
15095
|
+
const fmt = (h, m, ap) => `${hours[h % 12]} ${minWord(m)} ${ap}`;
|
|
15096
|
+
for (const { regex, replacement } of patches) {
|
|
15097
|
+
message = message.replace(regex, replacement);
|
|
15098
|
+
}
|
|
15099
|
+
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();
|
|
15100
|
+
};
|
|
15101
|
+
|
|
15102
|
+
// src/@modules/@eas/eas.setEasTone.ts
|
|
15103
|
+
import { join } from "path";
|
|
15104
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync as writeFileSync2, unlinkSync } from "fs";
|
|
15105
|
+
import { execSync as execSync2 } from "child_process";
|
|
15106
|
+
import { platform as platform2 } from "os";
|
|
15107
|
+
var setEasTone = (options) => __async(null, null, function* () {
|
|
15108
|
+
var _a;
|
|
15109
|
+
const settings = bootstrap.settings;
|
|
15110
|
+
const directory = settings.GlobalSettings.ArchiveSettings.EasDirectory;
|
|
15111
|
+
const prefix = settings.GlobalSettings.ArchiveSettings.EasToneout;
|
|
15112
|
+
let message = options.message;
|
|
15113
|
+
let header = options.header;
|
|
15114
|
+
let title = (_a = options.title) != null ? _a : `${Math.random().toString(36).substring(2, 15)}-${header.replace(/[^a-zA-Z0-9]/g, "")}`;
|
|
15115
|
+
if (!message || !header) {
|
|
15116
|
+
setWarning({
|
|
15117
|
+
title: `EAS`,
|
|
15118
|
+
message: `Message and header are required to generate an EAS tone.`
|
|
15054
15119
|
});
|
|
15120
|
+
return null;
|
|
15055
15121
|
}
|
|
15056
|
-
|
|
15057
|
-
|
|
15058
|
-
|
|
15059
|
-
|
|
15122
|
+
let buffTTS;
|
|
15123
|
+
let buffRadio;
|
|
15124
|
+
let buffFull = [];
|
|
15125
|
+
if (!existsSync(directory)) {
|
|
15126
|
+
mkdirSync(directory, { recursive: true });
|
|
15060
15127
|
}
|
|
15061
|
-
if (
|
|
15062
|
-
|
|
15128
|
+
if (!existsSync(join(directory, `/tts`))) {
|
|
15129
|
+
mkdirSync(join(directory, `/tts`), { recursive: true });
|
|
15063
15130
|
}
|
|
15064
|
-
if (
|
|
15065
|
-
|
|
15066
|
-
|
|
15067
|
-
|
|
15068
|
-
|
|
15069
|
-
|
|
15070
|
-
|
|
15131
|
+
if (!existsSync(join(directory, `/encoded`))) {
|
|
15132
|
+
mkdirSync(join(directory, `/encoded`), { recursive: true });
|
|
15133
|
+
}
|
|
15134
|
+
const tmpTTS = join(directory, `/tts/${title}.wav`);
|
|
15135
|
+
const outTTS = join(directory, `/encoded/${title}.wav`);
|
|
15136
|
+
const vPlatform = platform2();
|
|
15137
|
+
if (vPlatform === "darwin") {
|
|
15138
|
+
setWarning({
|
|
15139
|
+
title: `EAS`,
|
|
15140
|
+
message: `EAS tone generation is not supported on macOS.`
|
|
15071
15141
|
});
|
|
15142
|
+
return null;
|
|
15072
15143
|
}
|
|
15073
|
-
|
|
15074
|
-
|
|
15075
|
-
|
|
15076
|
-
|
|
15077
|
-
|
|
15078
|
-
const settings = bootstrap.settings;
|
|
15079
|
-
const features = bootstrap.cache.events.features;
|
|
15080
|
-
const getHash = event.properties.metadata.hash;
|
|
15081
|
-
const getTracking = event.properties.metadata.tracking;
|
|
15082
|
-
const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
|
|
15083
|
-
const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
|
|
15084
|
-
const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
|
|
15085
|
-
if (isHashed || event.properties.status_metadata.is_expired) return;
|
|
15086
|
-
setHash(event, isEntry);
|
|
15087
|
-
const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
15088
|
-
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
|
|
15089
|
-
return;
|
|
15090
|
-
}
|
|
15091
|
-
setEventEmit({
|
|
15092
|
-
event: `onEventStatus`,
|
|
15093
|
-
metadata: {
|
|
15094
|
-
type: getFeature ? `Updated` : `New`,
|
|
15095
|
-
event
|
|
15096
|
-
},
|
|
15097
|
-
message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
|
|
15144
|
+
yield new Promise((resolve6, reject) => {
|
|
15145
|
+
const tMsg = getCleanDescription(message);
|
|
15146
|
+
getTTS(tMsg, tmpTTS).then(() => {
|
|
15147
|
+
resolve6();
|
|
15148
|
+
});
|
|
15098
15149
|
});
|
|
15099
|
-
if (
|
|
15100
|
-
|
|
15101
|
-
|
|
15102
|
-
|
|
15103
|
-
|
|
15104
|
-
|
|
15105
|
-
|
|
15106
|
-
|
|
15107
|
-
|
|
15108
|
-
|
|
15109
|
-
|
|
15110
|
-
|
|
15111
|
-
const
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
|
|
15115
|
-
|
|
15116
|
-
|
|
15117
|
-
|
|
15118
|
-
|
|
15119
|
-
|
|
15120
|
-
|
|
15121
|
-
|
|
15122
|
-
});
|
|
15123
|
-
updateWebhooks(bootstrap.cache.events.features[getIndex]);
|
|
15124
|
-
} else {
|
|
15125
|
-
features.push(event);
|
|
15126
|
-
updateWebhooks(event);
|
|
15150
|
+
if (!existsSync(tmpTTS)) {
|
|
15151
|
+
return null;
|
|
15152
|
+
}
|
|
15153
|
+
buffTTS = readFileSync(tmpTTS);
|
|
15154
|
+
const vWav = getWavPCM16(buffTTS);
|
|
15155
|
+
const vSamples = getSampledPCM16(vWav.samples, vWav.sampleRate, 8e3);
|
|
15156
|
+
const vRadio = setRadioEffect(vSamples, 8e3);
|
|
15157
|
+
if (existsSync(prefix)) {
|
|
15158
|
+
let tBuffer = readFileSync(prefix);
|
|
15159
|
+
let tWav = getWavPCM16(tBuffer);
|
|
15160
|
+
if (tWav == null) {
|
|
15161
|
+
try {
|
|
15162
|
+
const converted = join(directory, `/tts/${title}.converted.wav`);
|
|
15163
|
+
execSync2(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
|
|
15164
|
+
if (existsSync(converted)) {
|
|
15165
|
+
tBuffer = readFileSync(converted);
|
|
15166
|
+
tWav = getWavPCM16(tBuffer);
|
|
15167
|
+
try {
|
|
15168
|
+
unlinkSync(converted);
|
|
15169
|
+
} catch (e) {
|
|
15170
|
+
}
|
|
15171
|
+
}
|
|
15172
|
+
} catch (e) {
|
|
15127
15173
|
}
|
|
15128
15174
|
}
|
|
15175
|
+
if (tWav == null) {
|
|
15176
|
+
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.` });
|
|
15177
|
+
return null;
|
|
15178
|
+
}
|
|
15179
|
+
const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
|
|
15180
|
+
buffRadio = setRadioEffect(tSamples, 8e3);
|
|
15181
|
+
}
|
|
15182
|
+
buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
|
|
15183
|
+
buffFull.push(
|
|
15184
|
+
setSameHeader(header, 3, 8e3, {
|
|
15185
|
+
preMarkSec: 1.1,
|
|
15186
|
+
gapSec: 0.5
|
|
15187
|
+
}),
|
|
15188
|
+
new Int16Array(Math.floor(0.5 * 8e3)),
|
|
15189
|
+
setAttentionTone(8, 8e3),
|
|
15190
|
+
new Int16Array(Math.floor(0.5 * 8e3)),
|
|
15191
|
+
vRadio
|
|
15192
|
+
);
|
|
15193
|
+
for (let i = 0; i < 3; i++) {
|
|
15194
|
+
buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
|
|
15195
|
+
buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
|
|
15196
|
+
}
|
|
15197
|
+
const aSamples = getMergedPCM16(buffFull);
|
|
15198
|
+
const aFinal = setNoise(aSamples, 2e-3);
|
|
15199
|
+
const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
|
|
15200
|
+
writeFileSync2(outTTS, aBuffer);
|
|
15201
|
+
try {
|
|
15202
|
+
unlinkSync(tmpTTS);
|
|
15203
|
+
} catch (e) {
|
|
15129
15204
|
}
|
|
15205
|
+
return outTTS;
|
|
15130
15206
|
});
|
|
15131
15207
|
|
|
15132
|
-
// src/@
|
|
15133
|
-
var
|
|
15134
|
-
|
|
15135
|
-
|
|
15136
|
-
|
|
15137
|
-
|
|
15138
|
-
|
|
15139
|
-
|
|
15140
|
-
|
|
15141
|
-
|
|
15142
|
-
|
|
15143
|
-
|
|
15144
|
-
|
|
15145
|
-
|
|
15146
|
-
|
|
15147
|
-
|
|
15148
|
-
|
|
15149
|
-
|
|
15150
|
-
|
|
15151
|
-
|
|
15152
|
-
|
|
15153
|
-
|
|
15154
|
-
|
|
15155
|
-
|
|
15156
|
-
event:
|
|
15157
|
-
|
|
15158
|
-
|
|
15159
|
-
|
|
15208
|
+
// src/@parsers/@text/text.getEmbed.ts
|
|
15209
|
+
var getEmebed = (event) => {
|
|
15210
|
+
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;
|
|
15211
|
+
const line = (label, value, condition = true) => condition && value ? `${label} ${value}` : null;
|
|
15212
|
+
const isStatement = event.properties.status_metadata.is_statement;
|
|
15213
|
+
const isExpired = event.properties.status_metadata.is_expired;
|
|
15214
|
+
return [
|
|
15215
|
+
line(`**Locations:**`, (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.locations) == null ? void 0 : _b.slice(0, 100)),
|
|
15216
|
+
line(`**Issued:**`, `<t:${Math.floor(new Date(event.properties.issued).getTime() / 1e3)}:R>`, !isExpired),
|
|
15217
|
+
line(`**Expires:**`, `<t:${Math.floor(new Date(event.properties.expires).getTime() / 1e3)}:R>`, !isStatement),
|
|
15218
|
+
line(`**Damage Threat:**`, (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.parameters) == null ? void 0 : _d.damage_threat, !isExpired),
|
|
15219
|
+
line(`**Flood Threat:**`, (_f = (_e = event == null ? void 0 : event.properties) == null ? void 0 : _e.parameters) == null ? void 0 : _f.flood_threat, !isExpired),
|
|
15220
|
+
line(`**Tornado Threat:**`, (_h = (_g = event == null ? void 0 : event.properties) == null ? void 0 : _g.parameters) == null ? void 0 : _h.tornado_threat, !isExpired),
|
|
15221
|
+
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),
|
|
15222
|
+
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),
|
|
15223
|
+
line(`**Discussion:**`, (_z = (_y = event == null ? void 0 : event.properties) == null ? void 0 : _y.discussion_parameters) == null ? void 0 : _z.discussion_number, !isExpired),
|
|
15224
|
+
line(`**Concern:**`, (_B = (_A = event == null ? void 0 : event.properties) == null ? void 0 : _A.discussion_parameters) == null ? void 0 : _B.discussion_concerning, !isExpired),
|
|
15225
|
+
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),
|
|
15226
|
+
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),
|
|
15227
|
+
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),
|
|
15228
|
+
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),
|
|
15229
|
+
line(`**Watch Number:**`, (_N = (_M = event == null ? void 0 : event.properties) == null ? void 0 : _M.watch_parameters) == null ? void 0 : _N.watch_number, !isExpired),
|
|
15230
|
+
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),
|
|
15231
|
+
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),
|
|
15232
|
+
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),
|
|
15233
|
+
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),
|
|
15234
|
+
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),
|
|
15235
|
+
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),
|
|
15236
|
+
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),
|
|
15237
|
+
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),
|
|
15238
|
+
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),
|
|
15239
|
+
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),
|
|
15240
|
+
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),
|
|
15241
|
+
line(`**Tracking:**`, (_Ia = (_Ha = event == null ? void 0 : event.properties) == null ? void 0 : _Ha.metadata) == null ? void 0 : _Ia.tracking),
|
|
15242
|
+
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),
|
|
15243
|
+
line(``, ((_Qa = (_Pa = (_Oa = event == null ? void 0 : event.properties) == null ? void 0 : _Oa.metadata) == null ? void 0 : _Pa.attachments) == null ? void 0 : _Qa.length) > 0 ? `**Attachments:** ${(_Sa = (_Ra = event == null ? void 0 : event.properties) == null ? void 0 : _Ra.metadata) == null ? void 0 : _Sa.attachments.map((attachment) => {
|
|
15244
|
+
var _a2, _b2;
|
|
15245
|
+
return `[Attachment #${((_b2 = (_a2 = event == null ? void 0 : event.properties) == null ? void 0 : _a2.metadata) == null ? void 0 : _b2.attachments.indexOf(attachment)) + 1}](${attachment})`;
|
|
15246
|
+
}).join(" | ")}` : null),
|
|
15247
|
+
line(``, ((_Ta = event == null ? void 0 : event.properties) == null ? void 0 : _Ta.description) ? "```\n" + ((_Ua = event == null ? void 0 : event.properties) == null ? void 0 : _Ua.description.split("\n").map((l) => l.trim()).filter(Boolean).join("\n")) + "\n```" : null, !isExpired)
|
|
15248
|
+
].filter(Boolean).join("\n");
|
|
15160
15249
|
};
|
|
15161
15250
|
|
|
15162
|
-
// src/@
|
|
15163
|
-
|
|
15164
|
-
|
|
15165
|
-
|
|
15166
|
-
|
|
15167
|
-
|
|
15168
|
-
|
|
15169
|
-
|
|
15170
|
-
|
|
15171
|
-
|
|
15172
|
-
|
|
15173
|
-
|
|
15174
|
-
|
|
15175
|
-
|
|
15176
|
-
|
|
15177
|
-
|
|
15178
|
-
|
|
15179
|
-
|
|
15180
|
-
|
|
15181
|
-
|
|
15182
|
-
|
|
15183
|
-
const zones = properties2.geocode.ugc;
|
|
15184
|
-
const icao = properties2.geocode.office.office;
|
|
15185
|
-
const enhancedEventName = properties2.event = getEventEnhancedName(event);
|
|
15186
|
-
const filteredProperties = JSON.parse(JSON.stringify(properties2));
|
|
15187
|
-
if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
|
|
15188
|
-
delete filteredProperties.metadata.ms;
|
|
15189
|
-
}
|
|
15190
|
-
filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
|
|
15191
|
-
properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
|
|
15192
|
-
setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
|
|
15193
|
-
if (properties2.status_metadata.is_test) {
|
|
15194
|
-
setEventEmit({ event: `onTestProduct`, metadata: define2 });
|
|
15195
|
-
if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
|
|
15196
|
-
}
|
|
15197
|
-
if (properties2.status_metadata.is_expired) {
|
|
15198
|
-
setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
|
|
15199
|
-
rmEvent(define2);
|
|
15200
|
-
return false;
|
|
15201
|
-
}
|
|
15202
|
-
if ((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) {
|
|
15203
|
-
const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
|
|
15204
|
-
setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
|
|
15205
|
-
if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
|
|
15206
|
-
return false;
|
|
15207
|
-
}
|
|
15208
|
-
if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
|
|
15209
|
-
return false;
|
|
15210
|
-
}
|
|
15251
|
+
// src/@modules/@utilities/utilities.createHttp.ts
|
|
15252
|
+
import request from "request";
|
|
15253
|
+
var createHttp = (options) => __async(null, null, function* () {
|
|
15254
|
+
return new Promise((resolve6, reject) => {
|
|
15255
|
+
var _a, _b, _c, _d, _e;
|
|
15256
|
+
const requestOptions = {
|
|
15257
|
+
url: (_a = options.url) != null ? _a : `https://api.weather.gov/alerts/active`,
|
|
15258
|
+
headers: (_b = options.headers) != null ? _b : {
|
|
15259
|
+
"User-Agent": "AtmosphericX",
|
|
15260
|
+
"Accept": "application/geo+json, text/plain, */*; q=0.9",
|
|
15261
|
+
"Accept-Language": "en-US,en;q=0.9"
|
|
15262
|
+
},
|
|
15263
|
+
method: (_c = options.method) != null ? _c : `GET`,
|
|
15264
|
+
timeout: (_d = options.timeout) != null ? _d : 1e4,
|
|
15265
|
+
proxy: (_e = options.proxy) != null ? _e : null,
|
|
15266
|
+
maxRedirects: 1
|
|
15267
|
+
};
|
|
15268
|
+
if (options.formData) {
|
|
15269
|
+
requestOptions["formData"] = options.formData;
|
|
15270
|
+
} else if (options.body) {
|
|
15271
|
+
requestOptions["body"] = options.body;
|
|
15211
15272
|
}
|
|
15212
|
-
|
|
15213
|
-
|
|
15214
|
-
if (
|
|
15215
|
-
|
|
15216
|
-
|
|
15217
|
-
|
|
15273
|
+
request(requestOptions, (error, response2, body) => {
|
|
15274
|
+
var _a2, _b2, _c2, _d2, _e2;
|
|
15275
|
+
if (error) {
|
|
15276
|
+
return resolve6({
|
|
15277
|
+
error: true,
|
|
15278
|
+
options: requestOptions,
|
|
15279
|
+
status: -1,
|
|
15280
|
+
message: (_a2 = error.message) != null ? _a2 : `Unknown Error`
|
|
15218
15281
|
});
|
|
15219
|
-
return false;
|
|
15220
15282
|
}
|
|
15221
|
-
if (
|
|
15222
|
-
|
|
15223
|
-
|
|
15224
|
-
|
|
15283
|
+
if (response2.statusCode < 200 || response2.statusCode >= 300) {
|
|
15284
|
+
return resolve6({
|
|
15285
|
+
error: true,
|
|
15286
|
+
options: requestOptions,
|
|
15287
|
+
status: (_b2 = response2.statusCode) != null ? _b2 : -1,
|
|
15288
|
+
message: `HTTP Status Code ${(_c2 = response2.statusCode) != null ? _c2 : `Unknown Status Code`} (${body})`
|
|
15225
15289
|
});
|
|
15226
|
-
return false;
|
|
15227
15290
|
}
|
|
15228
|
-
if (
|
|
15229
|
-
|
|
15230
|
-
|
|
15231
|
-
|
|
15291
|
+
if (body == void 0 || body == null) {
|
|
15292
|
+
return resolve6({
|
|
15293
|
+
error: true,
|
|
15294
|
+
options: requestOptions,
|
|
15295
|
+
status: (_d2 = response2.statusCode) != null ? _d2 : -1,
|
|
15296
|
+
message: `Empty Response Body`
|
|
15232
15297
|
});
|
|
15233
|
-
return false;
|
|
15234
15298
|
}
|
|
15235
|
-
|
|
15236
|
-
|
|
15237
|
-
|
|
15238
|
-
|
|
15239
|
-
|
|
15240
|
-
|
|
15299
|
+
resolve6({
|
|
15300
|
+
error: false,
|
|
15301
|
+
options: requestOptions,
|
|
15302
|
+
status: (_e2 = response2.statusCode) != null ? _e2 : -1,
|
|
15303
|
+
message: body
|
|
15304
|
+
});
|
|
15305
|
+
});
|
|
15306
|
+
});
|
|
15307
|
+
});
|
|
15308
|
+
|
|
15309
|
+
// src/@manager/manager.updateListener.ts
|
|
15310
|
+
var import_form_data = __toESM(require_form_data());
|
|
15311
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, readFileSync as readFileSync2, appendFileSync } from "fs";
|
|
15312
|
+
var updateListener = (event) => __async(null, null, function* () {
|
|
15313
|
+
var _a, _b, _c, _d;
|
|
15314
|
+
const settings = bootstrap.settings;
|
|
15315
|
+
const listeners2 = settings.ListenerSettings;
|
|
15316
|
+
const properties2 = event.properties;
|
|
15317
|
+
for (const socket of listeners2) {
|
|
15318
|
+
const events = socket.events;
|
|
15319
|
+
const sWebhook = socket == null ? void 0 : socket.webhook;
|
|
15320
|
+
const sUploads = socket == null ? void 0 : socket.uploads;
|
|
15321
|
+
const matched = events.some((pattern) => {
|
|
15322
|
+
if (!pattern) return false;
|
|
15323
|
+
if (pattern === "*" || pattern === properties2.event) return true;
|
|
15324
|
+
if (pattern.includes("*")) {
|
|
15325
|
+
const regex = "^" + pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$";
|
|
15326
|
+
return new RegExp(regex).test(properties2.event);
|
|
15241
15327
|
}
|
|
15242
|
-
|
|
15243
|
-
|
|
15244
|
-
|
|
15245
|
-
|
|
15328
|
+
return false;
|
|
15329
|
+
});
|
|
15330
|
+
if ((events == null ? void 0 : events.length) == 0 || matched) {
|
|
15331
|
+
let eas;
|
|
15332
|
+
let file;
|
|
15333
|
+
if (sUploads == null ? void 0 : sUploads.eas) {
|
|
15334
|
+
eas = yield setEasTone({
|
|
15335
|
+
title: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}`,
|
|
15336
|
+
message: properties2.description,
|
|
15337
|
+
header: properties2.metadata.header
|
|
15246
15338
|
});
|
|
15247
|
-
return false;
|
|
15248
15339
|
}
|
|
15249
|
-
if (
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
|
|
15340
|
+
if (sUploads == null ? void 0 : sUploads.file) {
|
|
15341
|
+
const destination = bootstrap.settings.GlobalSettings.ArchiveSettings.TextDirectory;
|
|
15342
|
+
if (destination) {
|
|
15343
|
+
if (!existsSync2(destination)) {
|
|
15344
|
+
mkdirSync2(destination, { recursive: true });
|
|
15345
|
+
}
|
|
15346
|
+
if (existsSync2(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`)) {
|
|
15347
|
+
appendFileSync(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, properties2.metadata.raw);
|
|
15348
|
+
} else {
|
|
15349
|
+
writeFileSync3(`${destination}/${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, properties2.metadata.raw);
|
|
15350
|
+
}
|
|
15351
|
+
}
|
|
15352
|
+
file = properties2.metadata.raw;
|
|
15255
15353
|
}
|
|
15256
|
-
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
|
|
15261
|
-
|
|
15262
|
-
|
|
15263
|
-
|
|
15264
|
-
|
|
15265
|
-
|
|
15266
|
-
|
|
15267
|
-
|
|
15268
|
-
|
|
15269
|
-
|
|
15270
|
-
|
|
15271
|
-
|
|
15272
|
-
|
|
15273
|
-
|
|
15274
|
-
|
|
15275
|
-
}
|
|
15276
|
-
|
|
15277
|
-
|
|
15278
|
-
|
|
15279
|
-
|
|
15280
|
-
|
|
15281
|
-
|
|
15282
|
-
|
|
15283
|
-
|
|
15284
|
-
|
|
15285
|
-
|
|
15286
|
-
|
|
15287
|
-
|
|
15288
|
-
|
|
15289
|
-
const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
|
|
15290
|
-
let event = Object.keys(eventsMatchText).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
|
|
15291
|
-
let isStatement = false;
|
|
15292
|
-
if (!event) {
|
|
15293
|
-
event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
|
|
15294
|
-
isStatement = true;
|
|
15295
|
-
}
|
|
15296
|
-
processed.push({
|
|
15297
|
-
type: `Feature`,
|
|
15298
|
-
geometry: {
|
|
15299
|
-
type: `Point`,
|
|
15300
|
-
coordinates: []
|
|
15301
|
-
},
|
|
15302
|
-
properties: __spreadProps(__spreadValues({
|
|
15303
|
-
event,
|
|
15304
|
-
parent: event,
|
|
15305
|
-
status: isStatement ? `Statement` : `Issued`,
|
|
15306
|
-
issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
15307
|
-
expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
|
|
15308
|
-
}, props), {
|
|
15309
|
-
metadata: {
|
|
15310
|
-
ms: performance.now() - tick,
|
|
15311
|
-
source: `events.text`,
|
|
15312
|
-
tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
|
|
15313
|
-
header,
|
|
15314
|
-
vtec: null,
|
|
15315
|
-
hvtec: null,
|
|
15316
|
-
history: [
|
|
15317
|
-
{
|
|
15318
|
-
description: props.description,
|
|
15319
|
-
issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
15320
|
-
status: `Issued`
|
|
15354
|
+
if (sWebhook == null ? void 0 : sWebhook.enabled) {
|
|
15355
|
+
const isLimited = setTimeoutAction({ identifier: sWebhook.destination, interval: sWebhook.ratelimit, max: sWebhook.ratelimit, addTime: true });
|
|
15356
|
+
if (!isLimited.limited) {
|
|
15357
|
+
let body = getEmebed(event);
|
|
15358
|
+
if (body.length > 1900) {
|
|
15359
|
+
body = body.substring(0, 1900) + "\n\n[Message truncated due to length]";
|
|
15360
|
+
const blocks = ((_a = body.match(/```/g)) != null ? _a : []).length;
|
|
15361
|
+
if (blocks % 2 !== 0) body += "```";
|
|
15362
|
+
}
|
|
15363
|
+
if (properties2.description.length < 25) {
|
|
15364
|
+
continue;
|
|
15365
|
+
}
|
|
15366
|
+
const form = new import_form_data.default();
|
|
15367
|
+
const embed = {
|
|
15368
|
+
title: `${properties2.event} (${properties2.status})`,
|
|
15369
|
+
description: body,
|
|
15370
|
+
color: 16711680,
|
|
15371
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
15372
|
+
image: {},
|
|
15373
|
+
footer: { text: (_b = sWebhook.title) != null ? _b : `AtmosphericX` }
|
|
15374
|
+
};
|
|
15375
|
+
form.append("payload_json", JSON.stringify({
|
|
15376
|
+
username: (_c = sWebhook.title) != null ? _c : "AtmosphericX",
|
|
15377
|
+
content: (_d = sWebhook.message) != null ? _d : "",
|
|
15378
|
+
embeds: [embed]
|
|
15379
|
+
}));
|
|
15380
|
+
if (sUploads == null ? void 0 : sUploads.file) {
|
|
15381
|
+
form.append("fUpload", Buffer.from(file), { filename: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}.txt`, contentType: "application/text" });
|
|
15382
|
+
}
|
|
15383
|
+
if (sUploads == null ? void 0 : sUploads.eas) {
|
|
15384
|
+
if (eas) {
|
|
15385
|
+
const file2 = readFileSync2(eas);
|
|
15386
|
+
form.append("fEas", Buffer.from(file2), { filename: `${properties2.event}_${properties2.status}_${properties2.metadata.tracking}_eas.mp3`, contentType: "audio/mpeg" });
|
|
15321
15387
|
}
|
|
15322
|
-
|
|
15388
|
+
}
|
|
15389
|
+
const a = yield createHttp({
|
|
15390
|
+
url: sWebhook.destination,
|
|
15391
|
+
timeout: 5e3,
|
|
15392
|
+
method: `POST`,
|
|
15393
|
+
headers: form.getHeaders(),
|
|
15394
|
+
body: form
|
|
15395
|
+
});
|
|
15323
15396
|
}
|
|
15324
|
-
}
|
|
15325
|
-
}
|
|
15397
|
+
}
|
|
15398
|
+
}
|
|
15326
15399
|
}
|
|
15327
|
-
validateEvents(processed);
|
|
15328
15400
|
});
|
|
15329
15401
|
|
|
15330
|
-
// src/@
|
|
15331
|
-
var
|
|
15332
|
-
|
|
15333
|
-
|
|
15334
|
-
|
|
15335
|
-
const
|
|
15336
|
-
|
|
15337
|
-
|
|
15338
|
-
|
|
15339
|
-
|
|
15340
|
-
|
|
15341
|
-
|
|
15342
|
-
|
|
15343
|
-
|
|
15344
|
-
|
|
15345
|
-
|
|
15346
|
-
|
|
15347
|
-
|
|
15348
|
-
|
|
15349
|
-
|
|
15350
|
-
|
|
15351
|
-
|
|
15352
|
-
|
|
15353
|
-
|
|
15402
|
+
// src/@modules/@utilities/utilities.getShapeNearestPoint.ts
|
|
15403
|
+
var getShapeNearestPoint = (coordinates, point) => {
|
|
15404
|
+
if (!coordinates || !point) {
|
|
15405
|
+
return { proximity: false, point: [0, 0], distance: null };
|
|
15406
|
+
}
|
|
15407
|
+
const normalize = (coords) => {
|
|
15408
|
+
if (!Array.isArray(coords)) return [];
|
|
15409
|
+
if (typeof coords[0] === "number" && typeof coords[1] === "number") return [];
|
|
15410
|
+
if (Array.isArray(coords[0]) && typeof coords[0][0] === "number") {
|
|
15411
|
+
return [[coords]];
|
|
15412
|
+
}
|
|
15413
|
+
if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && typeof coords[0][0][0] === "number") {
|
|
15414
|
+
return [coords];
|
|
15415
|
+
}
|
|
15416
|
+
if (Array.isArray(coords[0]) && Array.isArray(coords[0][0]) && Array.isArray(coords[0][0][0]) && typeof coords[0][0][0][0] === "number") {
|
|
15417
|
+
return coords;
|
|
15418
|
+
}
|
|
15419
|
+
return [];
|
|
15420
|
+
};
|
|
15421
|
+
const polys = normalize(coordinates);
|
|
15422
|
+
if (polys.length === 0) return { proximity: false, point: [0, 0], distance: null };
|
|
15423
|
+
const lon = point[0];
|
|
15424
|
+
const lat = point[1];
|
|
15425
|
+
const pointInRing = (pt, ring) => {
|
|
15426
|
+
let x = pt[0], y = pt[1];
|
|
15427
|
+
let inside = false;
|
|
15428
|
+
for (let i = 0, j2 = ring.length - 1; i < ring.length; j2 = i++) {
|
|
15429
|
+
const xi = ring[i][0], yi = ring[i][1];
|
|
15430
|
+
const xj = ring[j2][0], yj = ring[j2][1];
|
|
15431
|
+
const intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi + 0) + xi;
|
|
15432
|
+
if (intersect) inside = !inside;
|
|
15433
|
+
}
|
|
15434
|
+
return inside;
|
|
15435
|
+
};
|
|
15436
|
+
const toRadians = (deg) => deg * Math.PI / 180;
|
|
15437
|
+
const haversineMiles = (a, b) => {
|
|
15438
|
+
const R = 3958.8;
|
|
15439
|
+
const dLat = toRadians(b[1] - a[1]);
|
|
15440
|
+
const dLon = toRadians(b[0] - a[0]);
|
|
15441
|
+
const lat1 = toRadians(a[1]);
|
|
15442
|
+
const lat2 = toRadians(b[1]);
|
|
15443
|
+
const sinDLat = Math.sin(dLat / 2);
|
|
15444
|
+
const sinDLon = Math.sin(dLon / 2);
|
|
15445
|
+
const c = 2 * Math.asin(Math.sqrt(sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon));
|
|
15446
|
+
return R * c;
|
|
15447
|
+
};
|
|
15448
|
+
let minDistance = Infinity;
|
|
15449
|
+
let closestPoint = null;
|
|
15450
|
+
for (const poly of polys) {
|
|
15451
|
+
const outer = poly[0];
|
|
15452
|
+
const holes = poly.slice(1);
|
|
15453
|
+
if (pointInRing(point, outer)) {
|
|
15454
|
+
let inHole = false;
|
|
15455
|
+
for (const hole of holes) {
|
|
15456
|
+
if (pointInRing(point, hole)) {
|
|
15457
|
+
inHole = true;
|
|
15458
|
+
break;
|
|
15354
15459
|
}
|
|
15355
|
-
} else {
|
|
15356
|
-
zones.push(part);
|
|
15357
15460
|
}
|
|
15358
|
-
|
|
15461
|
+
if (!inHole) {
|
|
15462
|
+
return { proximity: true, point, distance: 0 };
|
|
15463
|
+
}
|
|
15359
15464
|
}
|
|
15360
|
-
|
|
15361
|
-
|
|
15362
|
-
|
|
15363
|
-
|
|
15364
|
-
|
|
15365
|
-
|
|
15465
|
+
for (const ring of poly) {
|
|
15466
|
+
for (let i = 0; i < ring.length - 1; i++) {
|
|
15467
|
+
const start = [ring[i][0], ring[i][1]];
|
|
15468
|
+
const end = [ring[i + 1][0], ring[i + 1][1]];
|
|
15469
|
+
const A = lon - start[0];
|
|
15470
|
+
const B = lat - start[1];
|
|
15471
|
+
const C = end[0] - start[0];
|
|
15472
|
+
const D = end[1] - start[1];
|
|
15473
|
+
const lenSq = C * C + D * D;
|
|
15474
|
+
const t = lenSq === 0 ? 0 : Math.max(0, Math.min(1, (A * C + B * D) / lenSq));
|
|
15475
|
+
const candidate = [start[0] + t * C, start[1] + t * D];
|
|
15476
|
+
const dist = haversineMiles([lon, lat], candidate);
|
|
15477
|
+
if (!isNaN(dist) && dist < minDistance) {
|
|
15478
|
+
minDistance = Number(dist.toFixed(3));
|
|
15479
|
+
closestPoint = candidate;
|
|
15480
|
+
}
|
|
15366
15481
|
}
|
|
15367
|
-
} else {
|
|
15368
|
-
zones.push(`${state}${format}${part}`);
|
|
15369
15482
|
}
|
|
15370
15483
|
}
|
|
15371
|
-
|
|
15372
|
-
};
|
|
15373
|
-
|
|
15374
|
-
// src/@parsers/@ugc/ugc.expiry.ts
|
|
15375
|
-
var getExpiry = (message) => {
|
|
15376
|
-
const match = message.match(/\b(\d{6})-/);
|
|
15377
|
-
if (!match) {
|
|
15378
|
-
return null;
|
|
15484
|
+
if (!isFinite(minDistance) || closestPoint == null) {
|
|
15485
|
+
return { proximity: false, point: [0, 0], distance: null };
|
|
15379
15486
|
}
|
|
15380
|
-
const
|
|
15381
|
-
const
|
|
15382
|
-
const
|
|
15383
|
-
|
|
15384
|
-
const now = /* @__PURE__ */ new Date();
|
|
15385
|
-
const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
|
|
15386
|
-
return expires.toISOString();
|
|
15487
|
+
const distanceMiles = minDistance;
|
|
15488
|
+
const distanceKm = Number((distanceMiles * 1.609344).toFixed(3));
|
|
15489
|
+
const distanceMeters = Math.round(distanceKm * 1e3);
|
|
15490
|
+
return { proximity: distanceMiles === 0, point: closestPoint, distance: distanceMiles, distanceKm, distanceMeters };
|
|
15387
15491
|
};
|
|
15388
15492
|
|
|
15389
|
-
// src/@
|
|
15390
|
-
var
|
|
15391
|
-
|
|
15392
|
-
const
|
|
15393
|
-
const
|
|
15394
|
-
|
|
15493
|
+
// src/@building/building.polygon.ts
|
|
15494
|
+
var getEventNodes = (event) => __async(null, null, function* () {
|
|
15495
|
+
var _a, _b;
|
|
15496
|
+
const metadata = { nodes: [], proximity: false, filtered: false };
|
|
15497
|
+
const geometry = yield getEventGeometry(event);
|
|
15498
|
+
if (!geometry || !geometry.coordinates) {
|
|
15499
|
+
return { nodes: [], filtered: false, updated: Date.now() };
|
|
15500
|
+
}
|
|
15501
|
+
const nodes = bootstrap.cache.nodes.features;
|
|
15502
|
+
for (const node of nodes) {
|
|
15503
|
+
const [longitude, latitude] = node.geometry.coordinates;
|
|
15504
|
+
const getPoint = getShapeNearestPoint(geometry.coordinates, [longitude, latitude]);
|
|
15505
|
+
const miles = (_a = getPoint.distance) != null ? _a : null;
|
|
15506
|
+
const kilometers = Number((miles * 1.609344).toFixed(3));
|
|
15507
|
+
const info = {
|
|
15508
|
+
id: (_b = node.properties) == null ? void 0 : _b.identifier,
|
|
15509
|
+
coordinates: [longitude, latitude],
|
|
15510
|
+
nearest: getPoint.point,
|
|
15511
|
+
miles,
|
|
15512
|
+
kilometers,
|
|
15513
|
+
proximity: getPoint.proximity
|
|
15514
|
+
};
|
|
15515
|
+
metadata.nodes.push(info);
|
|
15516
|
+
if (bootstrap.settings.GlobalSettings.EventFiltering.NodeLocationFiltering && miles < bootstrap.settings.GlobalSettings.NodeMinDistance) {
|
|
15517
|
+
metadata.proximity = true;
|
|
15518
|
+
info.proximity = true;
|
|
15519
|
+
}
|
|
15520
|
+
}
|
|
15521
|
+
return {
|
|
15522
|
+
nodes: metadata.nodes,
|
|
15523
|
+
filtered: metadata.proximity,
|
|
15524
|
+
updated: Date.now()
|
|
15525
|
+
};
|
|
15395
15526
|
});
|
|
15396
15527
|
|
|
15397
|
-
// src/@
|
|
15528
|
+
// src/@manager/manager.updateNodes.ts
|
|
15529
|
+
var updateNode = (selectedEvent) => __async(null, null, function* () {
|
|
15530
|
+
const events = bootstrap.cache.events.features;
|
|
15531
|
+
const ttl = bootstrap.settings.GlobalSettings.NodeTTL * 1e3;
|
|
15532
|
+
let total = 0;
|
|
15533
|
+
function update(evt) {
|
|
15534
|
+
return __async(this, null, function* () {
|
|
15535
|
+
var _a, _b, _c;
|
|
15536
|
+
const lastUpdate = (_c = (_b = (_a = evt == null ? void 0 : evt.properties) == null ? void 0 : _a.metadata) == null ? void 0 : _b.updated) != null ? _c : null;
|
|
15537
|
+
if (lastUpdate != null && Date.now() - lastUpdate < ttl) {
|
|
15538
|
+
return evt;
|
|
15539
|
+
}
|
|
15540
|
+
const node = yield getEventNodes(evt);
|
|
15541
|
+
if (node.nodes.length > 0) {
|
|
15542
|
+
total++;
|
|
15543
|
+
}
|
|
15544
|
+
evt.properties.metadata.nodes = node.nodes;
|
|
15545
|
+
evt.properties.metadata.filtered_proximity = node.filtered;
|
|
15546
|
+
evt.properties.metadata.updated = node.updated;
|
|
15547
|
+
});
|
|
15548
|
+
}
|
|
15549
|
+
if (!selectedEvent) {
|
|
15550
|
+
yield Promise.all(events.map((evt) => __async(null, null, function* () {
|
|
15551
|
+
yield update(evt);
|
|
15552
|
+
})));
|
|
15553
|
+
}
|
|
15554
|
+
if (selectedEvent) {
|
|
15555
|
+
yield update(selectedEvent);
|
|
15556
|
+
}
|
|
15557
|
+
if (total > 0) {
|
|
15558
|
+
setEventEmit({
|
|
15559
|
+
event: `onNodeUpdate`,
|
|
15560
|
+
metadata: {
|
|
15561
|
+
type: `global-update`,
|
|
15562
|
+
updated: total
|
|
15563
|
+
}
|
|
15564
|
+
});
|
|
15565
|
+
}
|
|
15566
|
+
});
|
|
15567
|
+
|
|
15568
|
+
// src/@manager/manager.mkEvent.ts
|
|
15569
|
+
var mkEvent = (event) => __async(null, null, function* () {
|
|
15570
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
15571
|
+
const settings = bootstrap.settings;
|
|
15572
|
+
const features = bootstrap.cache.events.features;
|
|
15573
|
+
const getHash = event.properties.metadata.hash;
|
|
15574
|
+
const getTracking = event.properties.metadata.tracking;
|
|
15575
|
+
const isEntry = (_a = bootstrap.cache.hashes) == null ? void 0 : _a.find((hash) => hash.tracking === getTracking);
|
|
15576
|
+
const isHashed = (_c = (_b = isEntry == null ? void 0 : isEntry.hashes) == null ? void 0 : _b.includes(getHash)) != null ? _c : false;
|
|
15577
|
+
const getFeature = features.find((feature) => feature.properties.metadata.tracking === getTracking);
|
|
15578
|
+
if (isHashed || event.properties.status_metadata.is_expired) return;
|
|
15579
|
+
setHash(event, isEntry);
|
|
15580
|
+
const isFilteredLocation = yield updateNode(event).then(() => event.properties.metadata.filtered_proximity);
|
|
15581
|
+
if (!isFilteredLocation && settings.GlobalSettings.EventFiltering.NodeLocationFiltering) {
|
|
15582
|
+
return;
|
|
15583
|
+
}
|
|
15584
|
+
setEventEmit({
|
|
15585
|
+
event: `onEventStatus`,
|
|
15586
|
+
metadata: {
|
|
15587
|
+
type: getFeature ? `Updated` : `New`,
|
|
15588
|
+
event
|
|
15589
|
+
},
|
|
15590
|
+
message: `[${getFeature ? "Updated" : "New"}] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
|
|
15591
|
+
});
|
|
15592
|
+
if (settings.GlobalSettings.EventManagement) {
|
|
15593
|
+
if (event.properties.status_metadata.is_issued || event.properties.status_metadata.is_updated) {
|
|
15594
|
+
if (getFeature) {
|
|
15595
|
+
const getIndex = features.indexOf(getFeature);
|
|
15596
|
+
const cHistory = (_f = (_e = (_d = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _d.metadata) == null ? void 0 : _e.history) != null ? _f : [];
|
|
15597
|
+
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 : [];
|
|
15598
|
+
const cUgc = (_l = (_k = (_j = getFeature == null ? void 0 : getFeature.properties) == null ? void 0 : _j.geocode) == null ? void 0 : _k.ugc) != null ? _l : [];
|
|
15599
|
+
const iHistory = (_o = (_n = (_m = event.properties) == null ? void 0 : _m.metadata) == null ? void 0 : _n.history) != null ? _o : [];
|
|
15600
|
+
const iLocations = (_r = (_q = (_p = event.properties) == null ? void 0 : _p.locations) == null ? void 0 : _q.split(";").map((l) => l.trim())) != null ? _r : [];
|
|
15601
|
+
const iUgc = (_u = (_t = (_s = event.properties) == null ? void 0 : _s.geocode) == null ? void 0 : _t.ugc) != null ? _u : [];
|
|
15602
|
+
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);
|
|
15603
|
+
const mLocations = [...cLocations, ...iLocations].filter((v, i, a) => a.indexOf(v) === i).join("; ");
|
|
15604
|
+
const mUgc = [...cUgc, ...iUgc].filter((v, i, a) => a.indexOf(v) === i);
|
|
15605
|
+
bootstrap.cache.events.features[getIndex] = __spreadProps(__spreadValues({}, event), {
|
|
15606
|
+
properties: __spreadProps(__spreadValues({}, event.properties), {
|
|
15607
|
+
metadata: __spreadProps(__spreadValues({}, (_v = event == null ? void 0 : event.properties) == null ? void 0 : _v.metadata), {
|
|
15608
|
+
history: mHistory
|
|
15609
|
+
}),
|
|
15610
|
+
locations: mLocations,
|
|
15611
|
+
geocode: __spreadProps(__spreadValues({}, (_w = event == null ? void 0 : event.properties) == null ? void 0 : _w.geocode), {
|
|
15612
|
+
ugc: mUgc
|
|
15613
|
+
})
|
|
15614
|
+
})
|
|
15615
|
+
});
|
|
15616
|
+
updateListener(bootstrap.cache.events.features[getIndex]);
|
|
15617
|
+
} else {
|
|
15618
|
+
features.push(event);
|
|
15619
|
+
updateListener(event);
|
|
15620
|
+
}
|
|
15621
|
+
}
|
|
15622
|
+
}
|
|
15623
|
+
});
|
|
15624
|
+
|
|
15625
|
+
// src/@manager/manager.rmEvent.ts
|
|
15626
|
+
var rmEvent = (event) => {
|
|
15627
|
+
const getEvent = bootstrap.cache.events.features.find((f) => {
|
|
15628
|
+
var _a, _b, _c, _d;
|
|
15629
|
+
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);
|
|
15630
|
+
});
|
|
15631
|
+
const cachedStatus = event.properties.status;
|
|
15632
|
+
event.properties.expires = (/* @__PURE__ */ new Date()).toISOString();
|
|
15633
|
+
event.properties.status = `Expired`;
|
|
15634
|
+
event.properties.status_metadata.is_expired = true;
|
|
15635
|
+
if (getEvent) {
|
|
15636
|
+
setEventEmit({
|
|
15637
|
+
event: `onEventStatus`,
|
|
15638
|
+
metadata: {
|
|
15639
|
+
type: `Removed`,
|
|
15640
|
+
event
|
|
15641
|
+
},
|
|
15642
|
+
message: `[Removed] ${event.properties.event} (${event.properties.status}) (${event.properties.metadata.tracking})`
|
|
15643
|
+
});
|
|
15644
|
+
setEventEmit({ event: `onExpiredProduct`, metadata: event });
|
|
15645
|
+
if (cachedStatus != `Statement`) updateListener(event);
|
|
15646
|
+
bootstrap.cache.events.features.splice(bootstrap.cache.events.features.indexOf(getEvent), 1);
|
|
15647
|
+
bootstrap.cache.hashes = bootstrap.cache.hashes.filter((hash) => hash.tracking !== event.properties.metadata.tracking);
|
|
15648
|
+
}
|
|
15649
|
+
setEventEmit({
|
|
15650
|
+
event: `onEventCache`,
|
|
15651
|
+
metadata: bootstrap.cache.events,
|
|
15652
|
+
limited: true
|
|
15653
|
+
});
|
|
15654
|
+
};
|
|
15655
|
+
|
|
15656
|
+
// src/@modules/@utilities/utilities.getLatestIssuance.ts
|
|
15657
|
+
var getLatestIssuance = () => {
|
|
15658
|
+
const now = /* @__PURE__ */ new Date();
|
|
15659
|
+
const current = now.getUTCHours() * 100 + now.getUTCMinutes();
|
|
15660
|
+
const issuances = [100, 600, 1300, 1630, 2e3];
|
|
15661
|
+
let latest = issuances[0];
|
|
15662
|
+
for (const issuance of issuances) {
|
|
15663
|
+
if (current >= issuance) {
|
|
15664
|
+
latest = issuance;
|
|
15665
|
+
}
|
|
15666
|
+
}
|
|
15667
|
+
return latest.toString().padStart(4, "0");
|
|
15668
|
+
};
|
|
15669
|
+
|
|
15670
|
+
// src/@building/building.attachments.ts
|
|
15671
|
+
var getEventAttachments = (event) => {
|
|
15672
|
+
var _a, _b, _c, _d;
|
|
15673
|
+
const latestTime = getLatestIssuance();
|
|
15674
|
+
const spcNumber = (_b = (_a = event == null ? void 0 : event.properties) == null ? void 0 : _a.discussion_parameters) == null ? void 0 : _b.discussion_number;
|
|
15675
|
+
const watchNumber = (_d = (_c = event == null ? void 0 : event.properties) == null ? void 0 : _c.watch_parameters) == null ? void 0 : _d.watch_number;
|
|
15676
|
+
const validEvents = [
|
|
15677
|
+
{ target: "Day 1", attachment: `https://www.spc.noaa.gov/products/outlook/day1otlk_${latestTime}.png` },
|
|
15678
|
+
{ target: "Day 2", attachment: `https://www.spc.noaa.gov/products/outlook/day2otlk.png` },
|
|
15679
|
+
{ target: "Day 3", attachment: `https://www.spc.noaa.gov/products/outlook/day3otlk.png` },
|
|
15680
|
+
{ target: "Mesoscale Discussion", attachment: `https://www.spc.noaa.gov/products/md/mcd${spcNumber}.png` },
|
|
15681
|
+
{ target: "Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
15682
|
+
{ target: "PDS Tornado Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
15683
|
+
{ target: "Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` },
|
|
15684
|
+
{ target: "PDS Severe Thunderstorm Watch", attachment: `https://www.spc.noaa.gov/products/watch/ww${watchNumber}_radar_big.gif` }
|
|
15685
|
+
];
|
|
15686
|
+
const isValid = validEvents.find((outlook) => outlook.target == event.properties.event);
|
|
15687
|
+
if (isValid) {
|
|
15688
|
+
return (isValid == null ? void 0 : isValid.attachment) ? [isValid.attachment] : [];
|
|
15689
|
+
}
|
|
15690
|
+
return null;
|
|
15691
|
+
};
|
|
15692
|
+
|
|
15693
|
+
// src/@building/building.validate.ts
|
|
15694
|
+
var validateEvents = (events) => __async(null, null, function* () {
|
|
15695
|
+
var _a;
|
|
15696
|
+
if (events.length === 0) return;
|
|
15697
|
+
const configurations = bootstrap.settings;
|
|
15698
|
+
const sets = {};
|
|
15699
|
+
const bools = {};
|
|
15700
|
+
const megered = __spreadValues(__spreadValues({}, configurations.GlobalSettings), configurations.GlobalSettings.EventFiltering);
|
|
15701
|
+
for (const key in megered) {
|
|
15702
|
+
const setting = megered[key];
|
|
15703
|
+
if (Array.isArray(setting)) {
|
|
15704
|
+
sets[key] = new Set(setting.map((item) => item.toLowerCase()));
|
|
15705
|
+
}
|
|
15706
|
+
if (typeof setting === "boolean") {
|
|
15707
|
+
bools[key] = setting;
|
|
15708
|
+
}
|
|
15709
|
+
}
|
|
15710
|
+
const filterd = events.filter((event) => {
|
|
15711
|
+
var _a2, _b, _c, _d, _e;
|
|
15712
|
+
const define2 = getEventSignature(event);
|
|
15713
|
+
const properties2 = define2.properties;
|
|
15714
|
+
const zones = properties2.geocode.ugc;
|
|
15715
|
+
const icao = properties2.geocode.office.office;
|
|
15716
|
+
const enhancedEventName = properties2.event = getEventEnhancedName(event);
|
|
15717
|
+
const filteredProperties = JSON.parse(JSON.stringify(properties2));
|
|
15718
|
+
if ((filteredProperties == null ? void 0 : filteredProperties.metadata) && "ms" in filteredProperties.metadata) {
|
|
15719
|
+
delete filteredProperties.metadata.ms;
|
|
15720
|
+
}
|
|
15721
|
+
filteredProperties.metadata = (_a2 = filteredProperties.metadata) != null ? _a2 : {};
|
|
15722
|
+
properties2.metadata.hash = createHash("sha256").update(JSON.stringify(filteredProperties)).digest("hex");
|
|
15723
|
+
properties2.metadata.attachments = getEventAttachments(event);
|
|
15724
|
+
setEventEmit({ event: `onProductType${enhancedEventName.replace(/\s+/g, "")}`, metadata: define2 });
|
|
15725
|
+
if (properties2.status_metadata.is_test) {
|
|
15726
|
+
setEventEmit({ event: `onTestProduct`, metadata: define2 });
|
|
15727
|
+
if (bools == null ? void 0 : bools.IgnoreTestProducts) return false;
|
|
15728
|
+
}
|
|
15729
|
+
if (properties2.status_metadata.is_expired) {
|
|
15730
|
+
setEventEmit({ event: `onExpiredProduct`, metadata: define2 });
|
|
15731
|
+
rmEvent(define2);
|
|
15732
|
+
return false;
|
|
15733
|
+
}
|
|
15734
|
+
if (((_c = (_b = properties2.metadata) == null ? void 0 : _b.vtec) == null ? void 0 : _c.is_watch) && properties2.metadata.source != `events.api`) {
|
|
15735
|
+
const isSPC = (_e = (_d = properties2.metadata) == null ? void 0 : _d.vtec) == null ? void 0 : _e.prediction_center;
|
|
15736
|
+
setEventEmit({ event: isSPC ? `onStormPredictionWatch` : `onNonStormPredictionWatch`, metadata: define2 });
|
|
15737
|
+
if ((bools == null ? void 0 : bools.SPCWatchesOnly) && !isSPC) {
|
|
15738
|
+
return false;
|
|
15739
|
+
}
|
|
15740
|
+
if (!(bools == null ? void 0 : bools.SPCWatchesOnly) && isSPC) {
|
|
15741
|
+
return false;
|
|
15742
|
+
}
|
|
15743
|
+
}
|
|
15744
|
+
for (const key in sets) {
|
|
15745
|
+
const setting = sets[key];
|
|
15746
|
+
if (key === "ListeningEvents" && setting.size > 0 && !setting.has(define2.properties.event.toLowerCase())) {
|
|
15747
|
+
setEventEmit({
|
|
15748
|
+
event: `onFilteredEvent`,
|
|
15749
|
+
metadata: define2
|
|
15750
|
+
});
|
|
15751
|
+
return false;
|
|
15752
|
+
}
|
|
15753
|
+
if (key === "IgnoredEvents" && setting.size > 0 && setting.has(define2.properties.event.toLowerCase())) {
|
|
15754
|
+
setEventEmit({
|
|
15755
|
+
event: `onIgnoredEvent`,
|
|
15756
|
+
metadata: define2
|
|
15757
|
+
});
|
|
15758
|
+
return false;
|
|
15759
|
+
}
|
|
15760
|
+
if (key === "ListeningICAO" && setting.size > 0 && icao != null && !setting.has(icao.toLowerCase())) {
|
|
15761
|
+
setEventEmit({
|
|
15762
|
+
event: `onFilteredICAO`,
|
|
15763
|
+
metadata: define2
|
|
15764
|
+
});
|
|
15765
|
+
return false;
|
|
15766
|
+
}
|
|
15767
|
+
if (key === "IgnoredICAO" && setting.size > 0 && icao != null && setting.has(icao.toLowerCase())) {
|
|
15768
|
+
setEventEmit({
|
|
15769
|
+
event: `onIgnoredICAO`,
|
|
15770
|
+
metadata: define2
|
|
15771
|
+
});
|
|
15772
|
+
return false;
|
|
15773
|
+
}
|
|
15774
|
+
if (key === "ListeningUGC" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.toLowerCase()))) {
|
|
15775
|
+
setEventEmit({
|
|
15776
|
+
event: `onFilteredUGC`,
|
|
15777
|
+
metadata: define2
|
|
15778
|
+
});
|
|
15779
|
+
return false;
|
|
15780
|
+
}
|
|
15781
|
+
if (key === "ListeningStates" && setting.size > 0 && zones.length > 0 && !zones.some((ugc2) => setting.has(ugc2.substring(0, 2).toLowerCase()))) {
|
|
15782
|
+
setEventEmit({
|
|
15783
|
+
event: `onFilteredState`,
|
|
15784
|
+
metadata: define2
|
|
15785
|
+
});
|
|
15786
|
+
return false;
|
|
15787
|
+
}
|
|
15788
|
+
}
|
|
15789
|
+
return true;
|
|
15790
|
+
});
|
|
15791
|
+
if (!((_a = configurations == null ? void 0 : configurations.GlobalSettings) == null ? void 0 : _a.DisableGeometryParsing)) {
|
|
15792
|
+
for (const event of filterd) {
|
|
15793
|
+
event.geometry = yield getEventGeometry(event);
|
|
15794
|
+
}
|
|
15795
|
+
}
|
|
15796
|
+
if (filterd.length > 0) {
|
|
15797
|
+
for (const event of filterd) {
|
|
15798
|
+
yield mkEvent(event);
|
|
15799
|
+
}
|
|
15800
|
+
}
|
|
15801
|
+
yield updateNode();
|
|
15802
|
+
setEventEmit({
|
|
15803
|
+
event: `onEventCache`,
|
|
15804
|
+
metadata: bootstrap.cache.events,
|
|
15805
|
+
limited: true
|
|
15806
|
+
});
|
|
15807
|
+
});
|
|
15808
|
+
|
|
15809
|
+
// src/@events/events.text.ts
|
|
15810
|
+
var text = (stanza) => __async(null, null, function* () {
|
|
15811
|
+
var _a, _b, _c;
|
|
15812
|
+
let processed = [];
|
|
15813
|
+
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 !== "$$");
|
|
15814
|
+
if (!getMessages || (getMessages == null ? void 0 : getMessages.length) == 0) return;
|
|
15815
|
+
for (const message of getMessages) {
|
|
15816
|
+
const tick = performance.now();
|
|
15817
|
+
const attributes = stanza == null ? void 0 : stanza.attributes;
|
|
15818
|
+
const props = properties({ message, attributes });
|
|
15819
|
+
const header = getEventHeader({ properties: props, getType: stanza.getType });
|
|
15820
|
+
const issued = new Date(attributes.issue);
|
|
15821
|
+
const expires = new Date(issued.getTime() + 12 * 60 * 60 * 1e3);
|
|
15822
|
+
let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
|
|
15823
|
+
let isStatement = false;
|
|
15824
|
+
if (!event) {
|
|
15825
|
+
event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
|
|
15826
|
+
isStatement = true;
|
|
15827
|
+
}
|
|
15828
|
+
processed.push({
|
|
15829
|
+
type: `Feature`,
|
|
15830
|
+
geometry: {
|
|
15831
|
+
type: `Point`,
|
|
15832
|
+
coordinates: []
|
|
15833
|
+
},
|
|
15834
|
+
properties: __spreadProps(__spreadValues({
|
|
15835
|
+
event,
|
|
15836
|
+
parent: event,
|
|
15837
|
+
status: isStatement ? `Statement` : `Issued`,
|
|
15838
|
+
issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
15839
|
+
expires: isStatement ? new Date(issued.getTime() + 120 * 1e3).toISOString() : !isNaN(expires.getTime()) ? expires.toISOString() : new Date(Date.now() + 60 * 60 * 1e3).toISOString()
|
|
15840
|
+
}, props), {
|
|
15841
|
+
metadata: {
|
|
15842
|
+
ms: performance.now() - tick,
|
|
15843
|
+
source: `events.text`,
|
|
15844
|
+
tracking: getEventTracking({ type: `RAW`, stanza, attributes, properties: props }),
|
|
15845
|
+
header,
|
|
15846
|
+
vtec: null,
|
|
15847
|
+
hvtec: null,
|
|
15848
|
+
raw: message,
|
|
15849
|
+
history: [
|
|
15850
|
+
{
|
|
15851
|
+
description: props.description,
|
|
15852
|
+
issued: !isNaN(issued.getTime()) ? issued.toISOString() : (/* @__PURE__ */ new Date()).toISOString(),
|
|
15853
|
+
status: `Issued`
|
|
15854
|
+
}
|
|
15855
|
+
]
|
|
15856
|
+
}
|
|
15857
|
+
})
|
|
15858
|
+
});
|
|
15859
|
+
}
|
|
15860
|
+
validateEvents(processed);
|
|
15861
|
+
});
|
|
15862
|
+
|
|
15863
|
+
// src/@parsers/@ugc/ugc.header.ts
|
|
15864
|
+
var getUGCHeader = (message) => {
|
|
15865
|
+
const start = message.search(dict_expressions.ugc1);
|
|
15866
|
+
const sub = message.substring(start);
|
|
15867
|
+
const end = sub.search(dict_expressions.ugc2);
|
|
15868
|
+
const fin = sub.substring(0, end).replace(/\s+/g, "").slice(0, -1);
|
|
15869
|
+
return fin != null ? fin : null;
|
|
15870
|
+
};
|
|
15871
|
+
|
|
15872
|
+
// src/@parsers/@ugc/ugc.zones.ts
|
|
15873
|
+
var getZones = (header) => {
|
|
15874
|
+
const splits = header.split("-");
|
|
15875
|
+
const zones = [];
|
|
15876
|
+
let state = splits[0].substring(0, 2);
|
|
15877
|
+
const format = splits[0].substring(2, 3);
|
|
15878
|
+
for (const part of splits) {
|
|
15879
|
+
if (/^[A-Z]/.test(part)) {
|
|
15880
|
+
state = part.substring(0, 2);
|
|
15881
|
+
if (part.includes(">")) {
|
|
15882
|
+
const [start, end] = part.split(">");
|
|
15883
|
+
const startNum = parseInt(start.substring(3), 10);
|
|
15884
|
+
const endNum = parseInt(end, 10);
|
|
15885
|
+
for (let j2 = startNum; j2 <= endNum; j2++) {
|
|
15886
|
+
zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
|
|
15887
|
+
}
|
|
15888
|
+
} else {
|
|
15889
|
+
zones.push(part);
|
|
15890
|
+
}
|
|
15891
|
+
continue;
|
|
15892
|
+
}
|
|
15893
|
+
if (part.includes(">")) {
|
|
15894
|
+
const [start, end] = part.split(">");
|
|
15895
|
+
const startNum = parseInt(start, 10);
|
|
15896
|
+
const endNum = parseInt(end, 10);
|
|
15897
|
+
for (let j2 = startNum; j2 <= endNum; j2++) {
|
|
15898
|
+
zones.push(`${state}${format}${j2.toString().padStart(3, "0")}`);
|
|
15899
|
+
}
|
|
15900
|
+
} else {
|
|
15901
|
+
zones.push(`${state}${format}${part}`);
|
|
15902
|
+
}
|
|
15903
|
+
}
|
|
15904
|
+
return zones.filter((item) => item !== "");
|
|
15905
|
+
};
|
|
15906
|
+
|
|
15907
|
+
// src/@parsers/@ugc/ugc.expiry.ts
|
|
15908
|
+
var getExpiry = (message) => {
|
|
15909
|
+
const match = message.match(/\b(\d{6})-/);
|
|
15910
|
+
if (!match) {
|
|
15911
|
+
return null;
|
|
15912
|
+
}
|
|
15913
|
+
const date = match == null ? void 0 : match[1];
|
|
15914
|
+
const day = parseInt(date == null ? void 0 : date.slice(0, 2), 10);
|
|
15915
|
+
const hour = parseInt(date == null ? void 0 : date.slice(2, 4), 10);
|
|
15916
|
+
const minute = parseInt(date == null ? void 0 : date.slice(4, 6), 10);
|
|
15917
|
+
const now = /* @__PURE__ */ new Date();
|
|
15918
|
+
const expires = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), day, hour, minute));
|
|
15919
|
+
return expires.toISOString();
|
|
15920
|
+
};
|
|
15921
|
+
|
|
15922
|
+
// src/@parsers/@ugc/ugc.locations.ts
|
|
15923
|
+
var getLocations = (zones) => __async(null, null, function* () {
|
|
15924
|
+
const sites = Array.from(new Set(zones));
|
|
15925
|
+
const placeholders = sites.map(() => "?").join(",");
|
|
15926
|
+
const rows = yield bootstrap.database.prepare(`SELECT id, location FROM shapefiles WHERE id IN (${placeholders})`).all(...sites);
|
|
15927
|
+
return rows.map((row) => row.location).sort();
|
|
15928
|
+
});
|
|
15929
|
+
|
|
15930
|
+
// src/@parsers/@ugc/ugc.extract.ts
|
|
15398
15931
|
var ugcExtract = (message) => __async(null, null, function* () {
|
|
15399
15932
|
const head = getUGCHeader(message);
|
|
15400
15933
|
const ugcs = getZones(head);
|
|
@@ -15423,7 +15956,7 @@ var ugc = (stanza) => __async(null, null, function* () {
|
|
|
15423
15956
|
const issued = new Date(attributes.issue);
|
|
15424
15957
|
const expires = new Date(ugc2.expires);
|
|
15425
15958
|
const header = getEventHeader({ properties: props, getType: stanza.getType });
|
|
15426
|
-
let event = Object.keys(
|
|
15959
|
+
let event = Object.keys(dict_matches).find((event2) => message.toLowerCase().includes(event2.toLowerCase()));
|
|
15427
15960
|
let isStatement = false;
|
|
15428
15961
|
if (!event) {
|
|
15429
15962
|
event = stanza.getType.type.split(`-`).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(` `);
|
|
@@ -15449,6 +15982,7 @@ var ugc = (stanza) => __async(null, null, function* () {
|
|
|
15449
15982
|
header,
|
|
15450
15983
|
vtec: null,
|
|
15451
15984
|
hvtec: null,
|
|
15985
|
+
raw: message,
|
|
15452
15986
|
history: [
|
|
15453
15987
|
{
|
|
15454
15988
|
description: props.description,
|
|
@@ -15464,8 +15998,8 @@ var ugc = (stanza) => __async(null, null, function* () {
|
|
|
15464
15998
|
validateEvents(processed);
|
|
15465
15999
|
});
|
|
15466
16000
|
|
|
15467
|
-
// src/@dictionaries/dictionaries.
|
|
15468
|
-
var
|
|
16001
|
+
// src/@dictionaries/dictionaries.events.ts
|
|
16002
|
+
var dict_events = {
|
|
15469
16003
|
"AF": "Ashfall",
|
|
15470
16004
|
"AS": "Air Stagnation",
|
|
15471
16005
|
"BH": "Beach Hazard",
|
|
@@ -15529,8 +16063,8 @@ var eventTypes = {
|
|
|
15529
16063
|
"ZY": "Freezing Spray"
|
|
15530
16064
|
};
|
|
15531
16065
|
|
|
15532
|
-
// src/@dictionaries/dictionaries.
|
|
15533
|
-
var
|
|
16066
|
+
// src/@dictionaries/dictionaries.actions.ts
|
|
16067
|
+
var dict_actions = {
|
|
15534
16068
|
"W": "Warning",
|
|
15535
16069
|
"F": "Forecast",
|
|
15536
16070
|
"A": "Watch",
|
|
@@ -15540,8 +16074,8 @@ var eventActions = {
|
|
|
15540
16074
|
"S": "Statement"
|
|
15541
16075
|
};
|
|
15542
16076
|
|
|
15543
|
-
// src/@dictionaries/dictionaries.
|
|
15544
|
-
var
|
|
16077
|
+
// src/@dictionaries/dictionaries.status.ts
|
|
16078
|
+
var dict_status = {
|
|
15545
16079
|
"NEW": "Issued",
|
|
15546
16080
|
"CON": "Updated",
|
|
15547
16081
|
"EXT": "Extended",
|
|
@@ -15566,7 +16100,8 @@ var getExpiry2 = (dates) => {
|
|
|
15566
16100
|
// src/@parsers/@pvtec/pvtec.extract.ts
|
|
15567
16101
|
var pvExtract = (message) => {
|
|
15568
16102
|
var _a, _b, _c, _d;
|
|
15569
|
-
|
|
16103
|
+
if (!message) return null;
|
|
16104
|
+
const getVTECs = (_a = message.match(dict_expressions.pvtec)) != null ? _a : [];
|
|
15570
16105
|
const vtecs = [];
|
|
15571
16106
|
for (const vtec2 of getVTECs) {
|
|
15572
16107
|
const sub = vtec2.split(`.`);
|
|
@@ -15574,11 +16109,11 @@ var pvExtract = (message) => {
|
|
|
15574
16109
|
const dates = (_b = sub[6]) == null ? void 0 : _b.split(`-`);
|
|
15575
16110
|
vtecs.push({
|
|
15576
16111
|
vtec: vtec2,
|
|
15577
|
-
product:
|
|
16112
|
+
product: dict_products[sub[0]],
|
|
15578
16113
|
tracking: `${sub[2]}.${sub[3]}.${sub[4]}.${sub[5]}`,
|
|
15579
|
-
event: `${
|
|
15580
|
-
status:
|
|
15581
|
-
organization: (_d = (_c = message.match(
|
|
16114
|
+
event: `${dict_events[sub[3]]} ${dict_actions[sub[4]]}`,
|
|
16115
|
+
status: dict_status[sub[1]],
|
|
16116
|
+
organization: (_d = (_c = message.match(dict_expressions.wmo)) == null ? void 0 : _c[0]) != null ? _d : null,
|
|
15582
16117
|
expires: getExpiry2(dates),
|
|
15583
16118
|
is_watch: (sub[4] == `A` || sub[4] == `Y`) && (sub[3] == `TO` || sub[3] == `SV`),
|
|
15584
16119
|
prediction_center: sub[2] == `KWNS` ? true : false
|
|
@@ -15587,8 +16122,8 @@ var pvExtract = (message) => {
|
|
|
15587
16122
|
return vtecs.length > 0 ? vtecs : null;
|
|
15588
16123
|
};
|
|
15589
16124
|
|
|
15590
|
-
// src/@dictionaries/dictionaries.
|
|
15591
|
-
var
|
|
16125
|
+
// src/@dictionaries/dictionaries.causes.ts
|
|
16126
|
+
var dict_causes = {
|
|
15592
16127
|
"SM": "Snow Melt",
|
|
15593
16128
|
"RS": "Rain/Snow Melt",
|
|
15594
16129
|
"ER": "Excessive Rain",
|
|
@@ -15606,16 +16141,16 @@ var eventCauses = {
|
|
|
15606
16141
|
"OT": "Other Effects"
|
|
15607
16142
|
};
|
|
15608
16143
|
|
|
15609
|
-
// src/@dictionaries/dictionaries.
|
|
15610
|
-
var
|
|
16144
|
+
// src/@dictionaries/dictionaries.records.ts
|
|
16145
|
+
var dict_records = {
|
|
15611
16146
|
"NO": "No Record Expected",
|
|
15612
16147
|
"NR": "Near Record or possible record",
|
|
15613
16148
|
"UU": "Unknown history of records",
|
|
15614
16149
|
"OO": "Other"
|
|
15615
16150
|
};
|
|
15616
16151
|
|
|
15617
|
-
// src/@dictionaries/dictionaries.
|
|
15618
|
-
var
|
|
16152
|
+
// src/@dictionaries/dictionaries.severity.ts
|
|
16153
|
+
var dict_severity = {
|
|
15619
16154
|
N: "Not Expected",
|
|
15620
16155
|
0: "Areal Flood or FF Product",
|
|
15621
16156
|
1: "Minor",
|
|
@@ -15627,16 +16162,16 @@ var eventSeverity = {
|
|
|
15627
16162
|
// src/@parsers/@hvtec/hvtec.extract.ts
|
|
15628
16163
|
var hvExtract = (message) => {
|
|
15629
16164
|
var _a;
|
|
15630
|
-
const getHVTECs = (_a = message.match(
|
|
16165
|
+
const getHVTECs = (_a = message.match(dict_expressions.hvtec)) != null ? _a : [];
|
|
15631
16166
|
const vtecs = [];
|
|
15632
16167
|
for (const vtec2 of getHVTECs) {
|
|
15633
16168
|
const sub = vtec2.split(`.`);
|
|
15634
16169
|
if (sub.length < 7) continue;
|
|
15635
16170
|
vtecs.push({
|
|
15636
16171
|
hvtec: vtec2,
|
|
15637
|
-
severity:
|
|
15638
|
-
cause:
|
|
15639
|
-
record:
|
|
16172
|
+
severity: dict_severity[sub[1]],
|
|
16173
|
+
cause: dict_causes[sub[2]],
|
|
16174
|
+
record: dict_records[sub[6]]
|
|
15640
16175
|
});
|
|
15641
16176
|
}
|
|
15642
16177
|
return vtecs.length > 0 ? vtecs : null;
|
|
@@ -15681,6 +16216,7 @@ var vtec = (stanza) => __async(null, null, function* () {
|
|
|
15681
16216
|
header,
|
|
15682
16217
|
vtec: pv,
|
|
15683
16218
|
hvtec: hVtec,
|
|
16219
|
+
raw: message,
|
|
15684
16220
|
history: [
|
|
15685
16221
|
{
|
|
15686
16222
|
description: props.description,
|
|
@@ -15699,12 +16235,12 @@ var vtec = (stanza) => __async(null, null, function* () {
|
|
|
15699
16235
|
|
|
15700
16236
|
// src/@events/events.api.ts
|
|
15701
16237
|
var api = (stanza) => __async(null, null, function* () {
|
|
15702
|
-
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;
|
|
16238
|
+
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;
|
|
15703
16239
|
let processed = [];
|
|
15704
16240
|
const messages = Object.values(JSON.parse(stanza.message).features);
|
|
15705
16241
|
for (const feature of messages) {
|
|
15706
16242
|
const tick = performance.now();
|
|
15707
|
-
const pVtec = (_d = (_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;
|
|
16243
|
+
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;
|
|
15708
16244
|
processed.push({
|
|
15709
16245
|
type: `Feature`,
|
|
15710
16246
|
geometry: {
|
|
@@ -15722,60 +16258,63 @@ var api = (stanza) => __async(null, null, function* () {
|
|
|
15722
16258
|
attributes: (_t = (_s = feature == null ? void 0 : feature.properties) == null ? void 0 : _s.attributes) != null ? _t : {},
|
|
15723
16259
|
geocode: {
|
|
15724
16260
|
office: {
|
|
15725
|
-
office: pVtec ? pVtec.split(`.`)[
|
|
15726
|
-
name: (
|
|
16261
|
+
office: pVtec ? (_u = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _u.tracking.split(`.`)[0] : null,
|
|
16262
|
+
name: (_w = dict_icao[pVtec ? (_v = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _v.tracking.split(`.`)[0] : null]) != null ? _w : null
|
|
15727
16263
|
},
|
|
15728
|
-
organization: (
|
|
15729
|
-
ugc: (
|
|
15730
|
-
polygon: ((
|
|
15731
|
-
polygon_generated: ((
|
|
16264
|
+
organization: (_z = (_y = (_x = feature == null ? void 0 : feature.properties) == null ? void 0 : _x.parameters) == null ? void 0 : _y.WMOidentifier) == null ? void 0 : _z[0],
|
|
16265
|
+
ugc: (_C = (_B = (_A = feature == null ? void 0 : feature.properties) == null ? void 0 : _A.geocode) == null ? void 0 : _B.UGC) != null ? _C : [],
|
|
16266
|
+
polygon: ((_D = feature == null ? void 0 : feature.geometry) == null ? void 0 : _D.coordinates.length) > 0 ? Buffer.from(JSON.stringify([(_E = feature == null ? void 0 : feature.geometry) == null ? void 0 : _E.coordinates[0]])).toString("base64") : null,
|
|
16267
|
+
polygon_generated: ((_F = feature == null ? void 0 : feature.geometry) == null ? void 0 : _F.coordinates.length) > 0 ? true : false
|
|
15732
16268
|
},
|
|
15733
16269
|
parameters: {
|
|
15734
|
-
tags: getEventTags((
|
|
15735
|
-
instructions: (
|
|
15736
|
-
source: (
|
|
15737
|
-
hazards: (
|
|
15738
|
-
impacts: (
|
|
15739
|
-
estimated_hail_size: (
|
|
15740
|
-
estimated_wind_gusts: (
|
|
15741
|
-
damage_threat: (
|
|
15742
|
-
tornado_threat: (
|
|
15743
|
-
flood_threat: (
|
|
15744
|
-
wind_threat: (
|
|
15745
|
-
hail_threat: (
|
|
16270
|
+
tags: getEventTags((_G = feature == null ? void 0 : feature.properties) == null ? void 0 : _G.description),
|
|
16271
|
+
instructions: (_I = (_H = feature == null ? void 0 : feature.properties) == null ? void 0 : _H.instruction) != null ? _I : null,
|
|
16272
|
+
source: (_K = getTextFromProduct({ message: (_J = feature == null ? void 0 : feature.properties) == null ? void 0 : _J.description, find: [`SOURCE...`], removal: [`.`] })) != null ? _K : null,
|
|
16273
|
+
hazards: (_M = getTextFromProduct({ message: (_L = feature == null ? void 0 : feature.properties) == null ? void 0 : _L.description, find: [`HAZARD...`], removal: [`.`] })) != null ? _M : null,
|
|
16274
|
+
impacts: (_O = getTextFromProduct({ message: (_N = feature == null ? void 0 : feature.properties) == null ? void 0 : _N.description, find: [`IMPACT...`], removal: [`.`] })) != null ? _O : null,
|
|
16275
|
+
estimated_hail_size: (_S = (_R = (_Q = (_P = feature == null ? void 0 : feature.properties) == null ? void 0 : _P.parameters) == null ? void 0 : _Q.maxHailSize) == null ? void 0 : _R[0]) != null ? _S : null,
|
|
16276
|
+
estimated_wind_gusts: (_W = (_V = (_U = (_T = feature == null ? void 0 : feature.properties) == null ? void 0 : _T.parameters) == null ? void 0 : _U.maxWindGust) == null ? void 0 : _V[0]) != null ? _W : null,
|
|
16277
|
+
damage_threat: (__ = (_Z = (_Y = (_X = feature == null ? void 0 : feature.properties) == null ? void 0 : _X.parameters) == null ? void 0 : _Y.thunderstormDamageThreat) == null ? void 0 : _Z[0]) != null ? __ : null,
|
|
16278
|
+
tornado_threat: (_ca = (_ba = (_aa = (_$ = feature == null ? void 0 : feature.properties) == null ? void 0 : _$.parameters) == null ? void 0 : _aa.tornadoDetection) == null ? void 0 : _ba[0]) != null ? _ca : null,
|
|
16279
|
+
flood_threat: (_ga = (_fa = (_ea = (_da = feature == null ? void 0 : feature.properties) == null ? void 0 : _da.parameters) == null ? void 0 : _ea.floodDetection) == null ? void 0 : _fa[0]) != null ? _ga : null,
|
|
16280
|
+
wind_threat: (_ka = (_ja = (_ia = (_ha = feature == null ? void 0 : feature.properties) == null ? void 0 : _ha.parameters) == null ? void 0 : _ia.windThreat) == null ? void 0 : _ja[0]) != null ? _ka : null,
|
|
16281
|
+
hail_threat: (_oa = (_na = (_ma = (_la = feature == null ? void 0 : feature.properties) == null ? void 0 : _la.parameters) == null ? void 0 : _ma.hailThreat) == null ? void 0 : _na[0]) != null ? _oa : null
|
|
15746
16282
|
},
|
|
15747
|
-
|
|
15748
|
-
|
|
15749
|
-
|
|
15750
|
-
|
|
15751
|
-
|
|
16283
|
+
discussion_parameters: {
|
|
16284
|
+
discussion_number: (_sa = (_ra = (_qa = getTextFromProduct({ message: (_pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _pa.description, find: [`Mesoscale Discussion `], removal: [`Mesoscale Discussion`, `Number`, `...`] })) == null ? void 0 : _qa.toString()) == null ? void 0 : _ra.padStart(4, "0")) != null ? _sa : null,
|
|
16285
|
+
discussion_concerning: (_ua = getTextFromProduct({ message: (_ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _ta.description, find: [`Concerning...`] })) != null ? _ua : null,
|
|
16286
|
+
discussion_max_tornado: (_wa = getTextFromProduct({ message: (_va = feature == null ? void 0 : feature.properties) == null ? void 0 : _va.description, find: [`MOST PROBABLE PEAK TORNADO INTENSITY...`] })) != null ? _wa : null,
|
|
16287
|
+
discussion_max_hail: (_ya = getTextFromProduct({ message: (_xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _xa.description, find: [`MOST PROBABLE PEAK HAIL SIZE...`] })) != null ? _ya : null,
|
|
16288
|
+
discussion_max_wind: (_Aa = getTextFromProduct({ message: (_za = feature == null ? void 0 : feature.properties) == null ? void 0 : _za.description, find: [`MOST PROBABLE PEAK WIND GUST...`] })) != null ? _Aa : null,
|
|
16289
|
+
discussion_watch_issuance: (_Ca = getTextFromProduct({ message: (_Ba = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ba.description, find: [`Probability of Watch Issuance...`], removal: [`percent`] })) != null ? _Ca : null
|
|
15752
16290
|
},
|
|
15753
16291
|
watch_parameters: {
|
|
15754
|
-
watch_number: (
|
|
15755
|
-
watch_type: ((
|
|
15756
|
-
additional_tornadoes_probability: (
|
|
15757
|
-
strong_tornadoes_probability: (
|
|
15758
|
-
severe_wind_probability: (
|
|
15759
|
-
severe_hail_probability: (
|
|
15760
|
-
hail_2in_probability: (
|
|
15761
|
-
combined_hail_wind_probability: (
|
|
15762
|
-
max_hail_in: (
|
|
15763
|
-
max_wind_surface: (
|
|
15764
|
-
max_tops_x100feet: (
|
|
15765
|
-
pds_watch: getTextFromProduct({ message: (
|
|
16292
|
+
watch_number: ((_Da = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Da.is_watch) && ((_Oa = (_Na = (_Ia = (_Ha = (_Ga = (_Fa = getTextFromProduct({ message: (_Ea = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ea.description, find: [`ITIES FOR`, `UPDATE FOR`, `Watch Number `], removal: [`%`, `<`, `:`] })) == null ? void 0 : _Fa.replace(/(WT|WS|)/g, "")) == null ? void 0 : _Ga.trim()) == null ? void 0 : _Ha.toString()) == null ? void 0 : _Ia.padStart(4, "0")) != null ? _Na : (_Ma = (_La = (_Ka = (_Ja = pVtec == null ? void 0 : pVtec[0]) == null ? void 0 : _Ja.tracking) == null ? void 0 : _Ka.slice(-4)) == null ? void 0 : _La.toString()) == null ? void 0 : _Ma.padStart(4, "0")) != null ? _Oa : null),
|
|
16293
|
+
watch_type: ((_Pa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Pa.description.includes(`TORNADO WATCH`)) ? `Tornado` : ((_Qa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Qa.description.includes(`SEVERE`)) ? `Severe` : null,
|
|
16294
|
+
additional_tornadoes_probability: (_Sa = getTextFromProduct({ message: (_Ra = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ra.description, find: [`PROB OF 2 OR MORE TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Sa : null,
|
|
16295
|
+
strong_tornadoes_probability: (_Ua = getTextFromProduct({ message: (_Ta = feature == null ? void 0 : feature.properties) == null ? void 0 : _Ta.description, find: [`PROB OF 1 OR MORE STRONG /EF2-EF5/ TORNADOES`], removal: [`%`, `<`, `:`] })) != null ? _Ua : null,
|
|
16296
|
+
severe_wind_probability: (_Wa = getTextFromProduct({ message: (_Va = feature == null ? void 0 : feature.properties) == null ? void 0 : _Va.description, find: [`PROB OF 10 OR MORE SEVERE WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Wa : null,
|
|
16297
|
+
severe_hail_probability: (_Ya = getTextFromProduct({ message: (_Xa = feature == null ? void 0 : feature.properties) == null ? void 0 : _Xa.description, find: [`PROB OF 10 OR MORE SEVERE HAIL EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _Ya : null,
|
|
16298
|
+
hail_2in_probability: (__a = getTextFromProduct({ message: (_Za = feature == null ? void 0 : feature.properties) == null ? void 0 : _Za.description, find: [`PROB OF 1 OR MORE HAIL EVENTS >= 2 INCHES`], removal: [`%`, `<`, `:`] })) != null ? __a : null,
|
|
16299
|
+
combined_hail_wind_probability: (_ab = getTextFromProduct({ message: (_$a = feature == null ? void 0 : feature.properties) == null ? void 0 : _$a.description, find: [`PROB OF 6 OR MORE COMBINED SEVERE HAIL/WIND EVENTS`], removal: [`%`, `<`, `:`] })) != null ? _ab : null,
|
|
16300
|
+
max_hail_in: (_cb = getTextFromProduct({ message: (_bb = feature == null ? void 0 : feature.properties) == null ? void 0 : _bb.description, find: [`MAX HAIL /INCHES/`], removal: [`%`, `<`, `:`] })) != null ? _cb : null,
|
|
16301
|
+
max_wind_surface: (_eb = getTextFromProduct({ message: (_db = feature == null ? void 0 : feature.properties) == null ? void 0 : _db.description, find: [`MAX WIND GUSTS SURFACE /KNOTS/`], removal: [`%`, `<`, `:`] })) != null ? _eb : null,
|
|
16302
|
+
max_tops_x100feet: (_gb = getTextFromProduct({ message: (_fb = feature == null ? void 0 : feature.properties) == null ? void 0 : _fb.description, find: [`MAX TOPS /X 100 FEET/`], removal: [`%`, `<`, `:`] })) != null ? _gb : null,
|
|
16303
|
+
pds_watch: getTextFromProduct({ message: (_hb = feature == null ? void 0 : feature.properties) == null ? void 0 : _hb.description, find: [`PARTICULARLY DANGEROUS SITUATION`], removal: [`%`, `<`, `:`] }) === `YES`
|
|
15766
16304
|
},
|
|
15767
16305
|
metadata: {
|
|
15768
16306
|
ms: performance.now() - tick,
|
|
15769
16307
|
source: `events.api`,
|
|
15770
|
-
tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (
|
|
15771
|
-
header: `ZCZC-ATMOSX-${(
|
|
15772
|
-
vtec: pVtec,
|
|
16308
|
+
tracking: getEventTracking({ type: `API`, organization: { wmoidentifier: (_kb = (_jb = (_ib = feature == null ? void 0 : feature.properties) == null ? void 0 : _ib.parameters) == null ? void 0 : _jb.WMOidentifier) == null ? void 0 : _kb[0], featureId: feature == null ? void 0 : feature.id }, vtec: pVtec == null ? void 0 : pVtec[0] }),
|
|
16309
|
+
header: `ZCZC-ATMOSX-${(_mb = (_lb = feature == null ? void 0 : feature.properties) == null ? void 0 : _lb.parameters) == null ? void 0 : _mb.WMOidentifier}`,
|
|
16310
|
+
vtec: pVtec == null ? void 0 : pVtec[0],
|
|
15773
16311
|
hvtec: null,
|
|
16312
|
+
raw: (_nb = feature == null ? void 0 : feature.properties) == null ? void 0 : _nb.description,
|
|
15774
16313
|
history: [
|
|
15775
16314
|
{
|
|
15776
|
-
description: (
|
|
15777
|
-
issued: ((
|
|
15778
|
-
status: (
|
|
16315
|
+
description: (_ob = feature == null ? void 0 : feature.properties) == null ? void 0 : _ob.description,
|
|
16316
|
+
issued: ((_pb = feature == null ? void 0 : feature.properties) == null ? void 0 : _pb.sent) ? new Date((_qb = feature == null ? void 0 : feature.properties) == null ? void 0 : _qb.sent).toISOString() : null,
|
|
16317
|
+
status: (_sb = (_rb = feature == null ? void 0 : feature.properties) == null ? void 0 : _rb.messageType) != null ? _sb : null
|
|
15779
16318
|
}
|
|
15780
16319
|
]
|
|
15781
16320
|
}
|
|
@@ -15911,8 +16450,8 @@ var setSleep = (options) => __async(null, null, function* () {
|
|
|
15911
16450
|
});
|
|
15912
16451
|
});
|
|
15913
16452
|
|
|
15914
|
-
// src/@dictionaries/dictionaries.
|
|
15915
|
-
var
|
|
16453
|
+
// src/@dictionaries/dictionaries.shapefiles.ts
|
|
16454
|
+
var dict_shapefiles = [
|
|
15916
16455
|
{ name: "us_counties", id: "C", link: "https://www.weather.gov/source/gis/Shapefiles/County/c_16ap26.zip" },
|
|
15917
16456
|
{ name: "us_states_territories", id: "Z", link: "https://www.weather.gov/source/gis/Shapefiles/County/s_16ap26.zip" },
|
|
15918
16457
|
{ name: "fire_weather_zones", id: "Z", link: "https://www.weather.gov/source/gis/Shapefiles/WSOM/fz16ap26.zip" },
|
|
@@ -15933,7 +16472,7 @@ var importShapefiles = () => __async(null, null, function* () {
|
|
|
15933
16472
|
if (tShapefiles === 0) {
|
|
15934
16473
|
yield setSleep({ timeout: 1e3 });
|
|
15935
16474
|
setWarning({ message: `Shapefiles are currently building, please DO NOT close your terminal. The shapefiles will not finish and will remain incomplete. If you do mess up, you will need to delete ${settings.Database} and restart the application.` });
|
|
15936
|
-
for (const shapefile of
|
|
16475
|
+
for (const shapefile of dict_shapefiles) {
|
|
15937
16476
|
const response2 = yield fetch(shapefile.link);
|
|
15938
16477
|
const arrayBuff = yield response2.arrayBuffer();
|
|
15939
16478
|
const content = yield loadAsync(arrayBuff);
|
|
@@ -15963,613 +16502,251 @@ var importShapefiles = () => __async(null, null, function* () {
|
|
|
15963
16502
|
if (properties2.FIPS) {
|
|
15964
16503
|
final2 = `${properties2.STATE}${shapefile.id}${properties2.FIPS.substring(2)}`;
|
|
15965
16504
|
location = `${properties2.COUNTYNAME}, ${properties2.STATE}`;
|
|
15966
|
-
} else if (properties2.FULLSTAID) {
|
|
15967
|
-
final2 = `${properties2.ST}${shapefile.id}${properties2.WFO}`;
|
|
15968
|
-
location = `${properties2.CITY}, ${properties2.STATE}`;
|
|
15969
|
-
} else if (properties2.STATE) {
|
|
15970
|
-
final2 = `${properties2.STATE}${shapefile.id}${(_a2 = properties2.ZONE) != null ? _a2 : properties2.SITE_ID}`;
|
|
15971
|
-
location = `${(_b2 = properties2.NAME) != null ? _b2 : `${properties2.RFC_NAME} ${properties2.RFC_CITY}`}, ${properties2.STATE}`;
|
|
15972
|
-
} else {
|
|
15973
|
-
final2 = (_c = properties2.ID) != null ? _c : properties2.WFO;
|
|
15974
|
-
location = properties2.NAME;
|
|
15975
|
-
}
|
|
15976
|
-
insert.run(final2, location, JSON.stringify(geometry));
|
|
15977
|
-
}
|
|
15978
|
-
});
|
|
15979
|
-
fs.unlinkSync(`${filepath}.shp`);
|
|
15980
|
-
fs.unlinkSync(`${filepath}.dbf`);
|
|
15981
|
-
setWarning({ message: `Cleaned up temporary files for ${shapefile.name}_${shapefile.id}` });
|
|
15982
|
-
transaction(features);
|
|
15983
|
-
}
|
|
15984
|
-
setWarning({ message: `Shapefiles have finished compiling, you can now continue and close this terminal` });
|
|
15985
|
-
fs.rm(resolve5(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
|
|
15986
|
-
});
|
|
15987
|
-
}
|
|
15988
|
-
} catch (error) {
|
|
15989
|
-
setWarning({ message: `An error occurred while compiling shapefiles: ${error.message}` });
|
|
15990
|
-
}
|
|
15991
|
-
});
|
|
15992
|
-
|
|
15993
|
-
// src/@modules/@database/database.init.ts
|
|
15994
|
-
var initializeDatabase = () => __async(null, null, function* () {
|
|
15995
|
-
const settings = bootstrap.settings;
|
|
15996
|
-
try {
|
|
15997
|
-
if (!fs2.existsSync(settings.Database)) {
|
|
15998
|
-
fs2.writeFileSync(settings.Database, "");
|
|
15999
|
-
setWarning({ message: `Creating new database at ${settings.Database}` });
|
|
16000
|
-
}
|
|
16001
|
-
bootstrap.database = new sqlite3(settings.Database);
|
|
16002
|
-
bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS stanzas ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, issued TEXT, stanza TEXT )`).run();
|
|
16003
|
-
bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`).run();
|
|
16004
|
-
yield importShapefiles();
|
|
16005
|
-
} catch (error) {
|
|
16006
|
-
setWarning({ message: `An error occurred while initializing the database: ${error.message}` });
|
|
16007
|
-
}
|
|
16008
|
-
});
|
|
16009
|
-
|
|
16010
|
-
// src/@modules/@database/database.cache.ts
|
|
16011
|
-
var getCachedEvents = () => __async(null, null, function* () {
|
|
16012
|
-
var _a;
|
|
16013
|
-
try {
|
|
16014
|
-
const settings = bootstrap.settings;
|
|
16015
|
-
const tick = performance.now();
|
|
16016
|
-
if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
|
|
16017
|
-
const max = (_a = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory) != null ? _a : 500;
|
|
16018
|
-
const get = yield bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max);
|
|
16019
|
-
setWarning({ message: `Fetched ${get.length} cached events from the database in ${Math.floor(performance.now() - tick)} ms` });
|
|
16020
|
-
let events = get.map((row) => JSON.parse(row.stanza)).filter((stanza) => {
|
|
16021
|
-
if (!stanza) {
|
|
16022
|
-
return;
|
|
16023
|
-
}
|
|
16024
|
-
const isSkippable = stanza.isIgnored || stanza.isCapEvent || stanza.isCapEvent && !stanza.isCapAreaDescription;
|
|
16025
|
-
return !isSkippable;
|
|
16026
|
-
});
|
|
16027
|
-
events = events.sort((a, b) => b.issued - a.issued);
|
|
16028
|
-
yield Promise.all(events.map((event) => createEvent(event)));
|
|
16029
|
-
setWarning({ message: `Processed ${events.length} cached events in ${Math.floor(performance.now() - tick)} ms` });
|
|
16030
|
-
}
|
|
16031
|
-
} catch (error) {
|
|
16032
|
-
setWarning({ message: `An error occurred while fetching cached events: ${error.message} -> ${error.stack}` });
|
|
16033
|
-
}
|
|
16034
|
-
});
|
|
16035
|
-
|
|
16036
|
-
// src/@modules/@xmpp/xmpp.xReconnect.ts
|
|
16037
|
-
var xReconnect = (interval) => __async(null, null, function* () {
|
|
16038
|
-
const settings = bootstrap.settings;
|
|
16039
|
-
const lastStanza = Date.now() - bootstrap.cache.lastStanza;
|
|
16040
|
-
if (interval < 15) {
|
|
16041
|
-
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
|
|
16042
|
-
interval = 15;
|
|
16043
|
-
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
16044
|
-
}
|
|
16045
|
-
const reconnectThreshold = interval * 1e3;
|
|
16046
|
-
if (!bootstrap.cache.isConnected && !bootstrap.cache.sigHault || !bootstrap.session_xmpp) {
|
|
16047
|
-
return;
|
|
16048
|
-
}
|
|
16049
|
-
if (lastStanza > reconnectThreshold) {
|
|
16050
|
-
if (!bootstrap.cache.isReconnecting) {
|
|
16051
|
-
bootstrap.cache.isReconnecting = true;
|
|
16052
|
-
bootstrap.cache.isConnected = false;
|
|
16053
|
-
bootstrap.cache.tReconnects += 1;
|
|
16054
|
-
try {
|
|
16055
|
-
setEventEmit({
|
|
16056
|
-
event: `onServiceStatus`,
|
|
16057
|
-
metadata: {
|
|
16058
|
-
message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
|
|
16059
|
-
data: {
|
|
16060
|
-
last_stanza: lastStanza,
|
|
16061
|
-
nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
|
|
16062
|
-
},
|
|
16063
|
-
type: `reconnect`,
|
|
16064
|
-
error: true
|
|
16065
|
-
}
|
|
16066
|
-
});
|
|
16067
|
-
yield bootstrap.session_xmpp.stop().catch(() => {
|
|
16068
|
-
});
|
|
16069
|
-
yield bootstrap.session_xmpp.start().catch(() => {
|
|
16070
|
-
});
|
|
16071
|
-
} catch (error) {
|
|
16072
|
-
setWarning({ message: `XMPP Reconnect Failed - ${error.message}` });
|
|
16073
|
-
} finally {
|
|
16074
|
-
bootstrap.cache.isReconnecting = false;
|
|
16075
|
-
}
|
|
16076
|
-
}
|
|
16077
|
-
}
|
|
16078
|
-
});
|
|
16079
|
-
|
|
16080
|
-
// src/@modules/@utilities/utilities.setCronSchedule.ts
|
|
16081
|
-
var setCronSchedule = () => __async(null, null, function* () {
|
|
16082
|
-
const settings = bootstrap.settings;
|
|
16083
|
-
if (settings.EnableWireService) {
|
|
16084
|
-
if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
|
|
16085
|
-
void xReconnect(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval);
|
|
16086
|
-
}
|
|
16087
|
-
} else {
|
|
16088
|
-
const response2 = yield createHttp({
|
|
16089
|
-
url: settings.NationalWeatherServiceSettings.EventsEndpoint,
|
|
16090
|
-
headers: {
|
|
16091
|
-
"User-Agent": "@atmosx/event-product-parser"
|
|
16092
|
-
}
|
|
16093
|
-
});
|
|
16094
|
-
if (response2.error) {
|
|
16095
|
-
return setEventEmit({
|
|
16096
|
-
event: `onServiceStatus`,
|
|
16097
|
-
metadata: {
|
|
16098
|
-
type: "fetch-api",
|
|
16099
|
-
message: `Failed to fetch latest events from National Weather Service API - ${response2.message}`,
|
|
16100
|
-
data: {},
|
|
16101
|
-
error: true
|
|
16102
|
-
}
|
|
16103
|
-
});
|
|
16104
|
-
}
|
|
16105
|
-
setEventEmit({
|
|
16106
|
-
event: `onServiceStatus`,
|
|
16107
|
-
metadata: {
|
|
16108
|
-
message: `Fetched latest events from National Weather Service API`,
|
|
16109
|
-
data: {},
|
|
16110
|
-
type: "fetch-api",
|
|
16111
|
-
error: false
|
|
16112
|
-
}
|
|
16113
|
-
});
|
|
16114
|
-
createEvent({ message: response2.message, isNWWS: false });
|
|
16115
|
-
}
|
|
16116
|
-
});
|
|
16117
|
-
|
|
16118
|
-
// src/@manager/manager.updateEvents.ts
|
|
16119
|
-
var updateEvents = (selectedEvent) => __async(null, null, function* () {
|
|
16120
|
-
const events = bootstrap.cache.events.features;
|
|
16121
|
-
function update(evt) {
|
|
16122
|
-
return __async(this, null, function* () {
|
|
16123
|
-
if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
|
|
16124
|
-
rmEvent(evt);
|
|
16125
|
-
}
|
|
16126
|
-
});
|
|
16127
|
-
}
|
|
16128
|
-
if (!selectedEvent) {
|
|
16129
|
-
yield Promise.all(events.map((evt) => __async(null, null, function* () {
|
|
16130
|
-
yield update(evt);
|
|
16131
|
-
})));
|
|
16132
|
-
}
|
|
16133
|
-
if (selectedEvent) {
|
|
16134
|
-
yield update(selectedEvent);
|
|
16135
|
-
}
|
|
16136
|
-
});
|
|
16137
|
-
|
|
16138
|
-
// src/@core/core.start.ts
|
|
16139
|
-
import { Cron } from "croner";
|
|
16140
|
-
var startService = (configurations) => __async(null, null, function* () {
|
|
16141
|
-
if (!bootstrap.isReady) {
|
|
16142
|
-
return setWarning({
|
|
16143
|
-
message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
|
|
16144
|
-
});
|
|
16145
|
-
}
|
|
16146
|
-
const settings = setSettings(configurations);
|
|
16147
|
-
bootstrap.isReady = true;
|
|
16148
|
-
yield initializeDatabase();
|
|
16149
|
-
if (settings.EnableWireService) {
|
|
16150
|
-
(() => __async(null, null, function* () {
|
|
16151
|
-
yield getCachedEvents();
|
|
16152
|
-
yield xDeploy();
|
|
16153
|
-
}))();
|
|
16154
|
-
}
|
|
16155
|
-
yield setCronSchedule();
|
|
16156
|
-
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
16157
|
-
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
16158
|
-
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
|
|
16159
|
-
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
16160
|
-
scheduleInterval = 15;
|
|
16161
|
-
}
|
|
16162
|
-
bootstrap.cron = new Cron(`*/${scheduleInterval} * * * * *`, () => __async(null, null, function* () {
|
|
16163
|
-
yield setCronSchedule();
|
|
16164
|
-
}));
|
|
16165
|
-
bootstrap.cron = new Cron(`* * * * * *`, () => __async(null, null, function* () {
|
|
16166
|
-
yield updateNode();
|
|
16167
|
-
yield updateEvents();
|
|
16168
|
-
}));
|
|
16169
|
-
});
|
|
16170
|
-
|
|
16171
|
-
// src/@core/core.stop.ts
|
|
16172
|
-
var stopService = () => __async(null, null, function* () {
|
|
16173
|
-
if (bootstrap.isReady) {
|
|
16174
|
-
bootstrap.isReady = false;
|
|
16175
|
-
if (bootstrap.session_xmpp) {
|
|
16176
|
-
try {
|
|
16177
|
-
yield bootstrap.session_xmpp.stop();
|
|
16178
|
-
} catch (e) {
|
|
16505
|
+
} else if (properties2.FULLSTAID) {
|
|
16506
|
+
final2 = `${properties2.ST}${shapefile.id}${properties2.WFO}`;
|
|
16507
|
+
location = `${properties2.CITY}, ${properties2.STATE}`;
|
|
16508
|
+
} else if (properties2.STATE) {
|
|
16509
|
+
final2 = `${properties2.STATE}${shapefile.id}${(_a2 = properties2.ZONE) != null ? _a2 : properties2.SITE_ID}`;
|
|
16510
|
+
location = `${(_b2 = properties2.NAME) != null ? _b2 : `${properties2.RFC_NAME} ${properties2.RFC_CITY}`}, ${properties2.STATE}`;
|
|
16511
|
+
} else {
|
|
16512
|
+
final2 = (_c = properties2.ID) != null ? _c : properties2.WFO;
|
|
16513
|
+
location = properties2.NAME;
|
|
16514
|
+
}
|
|
16515
|
+
insert.run(final2, location, JSON.stringify(geometry));
|
|
16516
|
+
}
|
|
16517
|
+
});
|
|
16518
|
+
fs.unlinkSync(`${filepath}.shp`);
|
|
16519
|
+
fs.unlinkSync(`${filepath}.dbf`);
|
|
16520
|
+
setWarning({ message: `Cleaned up temporary files for ${shapefile.name}_${shapefile.id}` });
|
|
16521
|
+
transaction(features);
|
|
16179
16522
|
}
|
|
16180
|
-
|
|
16181
|
-
|
|
16182
|
-
|
|
16523
|
+
setWarning({ message: `Shapefiles have finished compiling, you can now continue and close this terminal` });
|
|
16524
|
+
fs.rm(resolve5(__dirname, "../../shapefiles"), { recursive: true, force: true }, () => {
|
|
16525
|
+
});
|
|
16183
16526
|
}
|
|
16527
|
+
} catch (error) {
|
|
16528
|
+
setWarning({ message: `An error occurred while compiling shapefiles: ${error.message}` });
|
|
16184
16529
|
}
|
|
16185
16530
|
});
|
|
16186
16531
|
|
|
16187
|
-
// src/@
|
|
16188
|
-
var
|
|
16189
|
-
|
|
16190
|
-
|
|
16191
|
-
|
|
16192
|
-
|
|
16193
|
-
|
|
16194
|
-
|
|
16195
|
-
|
|
16196
|
-
|
|
16197
|
-
|
|
16198
|
-
|
|
16199
|
-
|
|
16200
|
-
|
|
16201
|
-
{ regex: /\bAKST\b(?!\w)/g, replacement: "Alaska Standard Time" },
|
|
16202
|
-
{ regex: /\bAKDT\b(?!\w)/g, replacement: "Alaska Daylight Time" },
|
|
16203
|
-
{ regex: /\bHST\b(?!\w)/g, replacement: "Hawaii Standard Time" },
|
|
16204
|
-
{ regex: /\bHDT\b(?!\w)/g, replacement: "Hawaii Daylight Time" },
|
|
16205
|
-
{ regex: /\bmph\b(?!\w)/g, replacement: "miles per hour" },
|
|
16206
|
-
{ regex: /\bkm\/h\b(?!\w)/g, replacement: "kilometers per hour" },
|
|
16207
|
-
{ regex: /\bkmh\b(?!\w)/g, replacement: "kilometers per hour" },
|
|
16208
|
-
{ regex: /\bkt\b(?!\w)/g, replacement: "knots" },
|
|
16209
|
-
{ regex: /\bNE\b(?!\w)/g, replacement: "northeast" },
|
|
16210
|
-
{ regex: /\bNW\b(?!\w)/g, replacement: "northwest" },
|
|
16211
|
-
{ regex: /\bSE\b(?!\w)/g, replacement: "southeast" },
|
|
16212
|
-
{ regex: /\bSW\b(?!\w)/g, replacement: "southwest" },
|
|
16213
|
-
{ regex: /\bNM\b(?!\w)/g, replacement: "nautical miles" },
|
|
16214
|
-
{ regex: /\bdeg\b(?!\w)/g, replacement: "degrees" },
|
|
16215
|
-
{ regex: /\btstm\b(?!\w)/g, replacement: "thunderstorm" },
|
|
16216
|
-
{ regex: /\bmm\b(?!\w)/g, replacement: "millimeters" },
|
|
16217
|
-
{ regex: /\bcm\b(?!\w)/g, replacement: "centimeters" },
|
|
16218
|
-
{ regex: /\bin.\b(?!\w)/g, replacement: "inches" },
|
|
16219
|
-
{ regex: /\bft\b(?!\w)/g, replacement: "feet" },
|
|
16220
|
-
{ regex: /\bmi\b(?!\w)/g, replacement: "miles" },
|
|
16221
|
-
{ regex: /\bhr\b(?!\w)/g, replacement: "hour" },
|
|
16222
|
-
{ regex: /\bhourly\b(?!\w)/g, replacement: "per hour" },
|
|
16223
|
-
{ regex: /\bkg\b(?!\w)/g, replacement: "kilograms" },
|
|
16224
|
-
{ regex: /\bg\/kg\b(?!\w)/g, replacement: "grams per kilogram" },
|
|
16225
|
-
{ regex: /\bmb\b(?!\w)/g, replacement: "millibars" },
|
|
16226
|
-
{ regex: /\bhPa\b(?!\w)/g, replacement: "hectopascals" },
|
|
16227
|
-
{ regex: /\bPa\b(?!\w)/g, replacement: "pascals" },
|
|
16228
|
-
{ regex: /\bKPa\b(?!\w)/g, replacement: "kilopascals" },
|
|
16229
|
-
{ regex: /\bC\/hr\b(?!\w)/g, replacement: "degrees Celsius per hour" },
|
|
16230
|
-
{ regex: /\bF\/hr\b(?!\w)/g, replacement: "degrees Fahrenheit per hour" },
|
|
16231
|
-
{ regex: /\bC\/min\b(?!\w)/g, replacement: "degrees Celsius per minute" },
|
|
16232
|
-
{ regex: /\bF\/min\b(?!\w)/g, replacement: "degrees Fahrenheit per minute" },
|
|
16233
|
-
{ regex: /\bC\b(?!\w)/g, replacement: "degrees Celsius" },
|
|
16234
|
-
{ regex: /\bF\b(?!\w)/g, replacement: "degrees Fahrenheit" }
|
|
16235
|
-
];
|
|
16236
|
-
|
|
16237
|
-
// src/@modules/@eas/eas.getWavPCM16.ts
|
|
16238
|
-
var getWavPCM16 = (buffer) => {
|
|
16239
|
-
if (buffer.toString("ascii", 0, 4) !== "RIFF" || buffer.toString("ascii", 8, 12) !== "WAVE") {
|
|
16240
|
-
return null;
|
|
16241
|
-
}
|
|
16242
|
-
let fmt = null;
|
|
16243
|
-
let data = null;
|
|
16244
|
-
let i = 12;
|
|
16245
|
-
while (i + 8 <= buffer.length) {
|
|
16246
|
-
const id2 = buffer.toString("ascii", i, i + 4);
|
|
16247
|
-
const size = buffer.readUInt32LE(i + 4);
|
|
16248
|
-
const start = i + 8;
|
|
16249
|
-
const end = start + size;
|
|
16250
|
-
if (id2 === "fmt ") fmt = buffer.slice(start, end);
|
|
16251
|
-
if (id2 === "data") data = buffer.slice(start, end);
|
|
16252
|
-
i = end + size % 2;
|
|
16253
|
-
}
|
|
16254
|
-
if (!fmt || !data) return null;
|
|
16255
|
-
const audioFormat = fmt.readUInt16LE(0);
|
|
16256
|
-
const channels = fmt.readUInt16LE(2);
|
|
16257
|
-
const sampleRate = fmt.readUInt32LE(4);
|
|
16258
|
-
const bitsPerSample = fmt.readUInt16LE(14);
|
|
16259
|
-
if (audioFormat !== 1 || bitsPerSample !== 16 || channels !== 1) {
|
|
16260
|
-
return null;
|
|
16261
|
-
}
|
|
16262
|
-
const samples = new Int16Array(data.buffer, data.byteOffset, data.length / 2);
|
|
16263
|
-
return { samples: new Int16Array(samples), sampleRate, channels, bitsPerSample };
|
|
16264
|
-
};
|
|
16265
|
-
|
|
16266
|
-
// src/@modules/@eas/eas.getSampledPCM16.ts
|
|
16267
|
-
var getSampledPCM16 = (int16, originalRate, targetRate) => {
|
|
16268
|
-
if (originalRate === targetRate) return int16;
|
|
16269
|
-
const ratio = targetRate / originalRate;
|
|
16270
|
-
const outLen = Math.max(1, Math.round(int16.length * ratio));
|
|
16271
|
-
const out = new Int16Array(outLen);
|
|
16272
|
-
for (let i = 0; i < outLen; i++) {
|
|
16273
|
-
const pos = i / ratio;
|
|
16274
|
-
const i0 = Math.floor(pos);
|
|
16275
|
-
const i1 = Math.min(i0 + 1, int16.length - 1);
|
|
16276
|
-
const frac = pos - i0;
|
|
16277
|
-
const v = int16[i0] * (1 - frac) + int16[i1] * frac;
|
|
16278
|
-
out[i] = Math.round(v);
|
|
16279
|
-
}
|
|
16280
|
-
return out;
|
|
16281
|
-
};
|
|
16282
|
-
|
|
16283
|
-
// src/@modules/@eas/eas.getPCMToFloat.ts
|
|
16284
|
-
var getPCMToFloat = (int16) => {
|
|
16285
|
-
const out = new Float32Array(int16.length);
|
|
16286
|
-
for (let i = 0; i < int16.length; i++) out[i] = int16[i] / 32768;
|
|
16287
|
-
return out;
|
|
16288
|
-
};
|
|
16289
|
-
|
|
16290
|
-
// src/@modules/@eas/eas.getFloatPCM16.ts
|
|
16291
|
-
var getFloatPCM16 = (float32) => {
|
|
16292
|
-
const out = new Int16Array(float32.length);
|
|
16293
|
-
for (let i = 0; i < float32.length; i++) {
|
|
16294
|
-
let v = Math.max(-1, Math.min(1, float32[i]));
|
|
16295
|
-
out[i] = Math.round(v * 32767);
|
|
16296
|
-
}
|
|
16297
|
-
return out;
|
|
16298
|
-
};
|
|
16299
|
-
|
|
16300
|
-
// src/@modules/@eas/eas.setRadioEffect.ts
|
|
16301
|
-
var setRadioEffect = (int16, sampleRate) => {
|
|
16302
|
-
const hpCut = 3555;
|
|
16303
|
-
const lpCut = 1600;
|
|
16304
|
-
const x = getPCMToFloat(int16);
|
|
16305
|
-
const dt = 1 / sampleRate;
|
|
16306
|
-
const rcHP = 1 / (2 * Math.PI * hpCut);
|
|
16307
|
-
const aHP = rcHP / (rcHP + dt);
|
|
16308
|
-
let yHP = 0, xPrev = 0;
|
|
16309
|
-
for (let i = 0; i < x.length; i++) {
|
|
16310
|
-
const xi = x[i];
|
|
16311
|
-
yHP = aHP * (yHP + xi - xPrev);
|
|
16312
|
-
xPrev = xi;
|
|
16313
|
-
x[i] = yHP;
|
|
16314
|
-
}
|
|
16315
|
-
const rcLP = 1 / (2 * Math.PI * lpCut);
|
|
16316
|
-
const aLP = dt / (rcLP + dt);
|
|
16317
|
-
let yLP = 0;
|
|
16318
|
-
for (let i = 0; i < x.length; i++) {
|
|
16319
|
-
yLP = yLP + aLP * (x[i] - yLP);
|
|
16320
|
-
x[i] = yLP;
|
|
16532
|
+
// src/@modules/@database/database.init.ts
|
|
16533
|
+
var initializeDatabase = () => __async(null, null, function* () {
|
|
16534
|
+
const settings = bootstrap.settings;
|
|
16535
|
+
try {
|
|
16536
|
+
if (!fs2.existsSync(settings.Database)) {
|
|
16537
|
+
fs2.writeFileSync(settings.Database, "");
|
|
16538
|
+
setWarning({ message: `Creating new database at ${settings.Database}` });
|
|
16539
|
+
}
|
|
16540
|
+
bootstrap.database = new sqlite3(settings.Database);
|
|
16541
|
+
bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS stanzas ( id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, issued TEXT, stanza TEXT )`).run();
|
|
16542
|
+
bootstrap.database.prepare(`CREATE TABLE IF NOT EXISTS shapefiles (id TEXT PRIMARY KEY, location TEXT, geometry TEXT)`).run();
|
|
16543
|
+
yield importShapefiles();
|
|
16544
|
+
} catch (error) {
|
|
16545
|
+
setWarning({ message: `An error occurred while initializing the database: ${error.message}` });
|
|
16321
16546
|
}
|
|
16322
|
-
|
|
16323
|
-
const norm = Math.tanh(compGain);
|
|
16324
|
-
for (let i = 0; i < x.length; i++) x[i] = Math.tanh(x[i] * compGain) / norm;
|
|
16325
|
-
return getFloatPCM16(x);
|
|
16326
|
-
};
|
|
16547
|
+
});
|
|
16327
16548
|
|
|
16328
|
-
// src/@modules/@
|
|
16329
|
-
var
|
|
16330
|
-
|
|
16331
|
-
|
|
16332
|
-
|
|
16333
|
-
|
|
16334
|
-
|
|
16335
|
-
|
|
16336
|
-
|
|
16337
|
-
|
|
16338
|
-
|
|
16339
|
-
|
|
16340
|
-
|
|
16341
|
-
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
|
|
16347
|
-
|
|
16348
|
-
if (phase > twoPi) phase -= twoPi;
|
|
16549
|
+
// src/@modules/@database/database.cache.ts
|
|
16550
|
+
var getCachedEvents = () => __async(null, null, function* () {
|
|
16551
|
+
var _a;
|
|
16552
|
+
try {
|
|
16553
|
+
const settings = bootstrap.settings;
|
|
16554
|
+
const tick = performance.now();
|
|
16555
|
+
if (settings.NOAAWeatherWireServiceSettings.CacheSettings.Enabled) {
|
|
16556
|
+
const max = (_a = settings.NOAAWeatherWireServiceSettings.CacheSettings.MaxRetentionHistory) != null ? _a : 500;
|
|
16557
|
+
const get = yield bootstrap.database.prepare(`SELECT * FROM stanzas ORDER BY rowid DESC LIMIT ?`).all(max);
|
|
16558
|
+
setWarning({ message: `Fetched ${get.length} cached events from the database in ${Math.floor(performance.now() - tick)} ms` });
|
|
16559
|
+
let events = get.map((row) => JSON.parse(row.stanza)).filter((stanza) => {
|
|
16560
|
+
if (!stanza) {
|
|
16561
|
+
return;
|
|
16562
|
+
}
|
|
16563
|
+
const isSkippable = stanza.isIgnored || stanza.isCapEvent || stanza.isCapEvent && !stanza.isCapAreaDescription;
|
|
16564
|
+
return !isSkippable;
|
|
16565
|
+
});
|
|
16566
|
+
events = events.sort((a, b) => b.issued - a.issued);
|
|
16567
|
+
yield Promise.all(events.map((event) => createEvent(event)));
|
|
16568
|
+
setWarning({ message: `Processed ${events.length} cached events in ${Math.floor(performance.now() - tick)} ms` });
|
|
16349
16569
|
}
|
|
16570
|
+
} catch (error) {
|
|
16571
|
+
setWarning({ message: `An error occurred while fetching cached events: ${error.message} -> ${error.stack}` });
|
|
16350
16572
|
}
|
|
16351
|
-
|
|
16352
|
-
for (let i = 0; i < fadeSamples; i++) {
|
|
16353
|
-
const gain = i / fadeSamples;
|
|
16354
|
-
result[i] = Math.round(result[i] * gain);
|
|
16355
|
-
result[result.length - 1 - i] = Math.round(result[result.length - 1 - i] * gain);
|
|
16356
|
-
}
|
|
16357
|
-
return Int16Array.from(result);
|
|
16358
|
-
};
|
|
16573
|
+
});
|
|
16359
16574
|
|
|
16360
|
-
// src/@modules/@
|
|
16361
|
-
var
|
|
16362
|
-
const
|
|
16363
|
-
|
|
16364
|
-
|
|
16365
|
-
|
|
16366
|
-
|
|
16367
|
-
|
|
16575
|
+
// src/@modules/@xmpp/xmpp.xReconnect.ts
|
|
16576
|
+
var xReconnect = (interval) => __async(null, null, function* () {
|
|
16577
|
+
const settings = bootstrap.settings;
|
|
16578
|
+
const lastStanza = Date.now() - bootstrap.cache.lastStanza;
|
|
16579
|
+
if (interval < 15) {
|
|
16580
|
+
setWarning({ message: `Reconnection interval of ${interval} seconds is too low, setting to 15 seconds` });
|
|
16581
|
+
interval = 15;
|
|
16582
|
+
bootstrap.settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval = 15;
|
|
16368
16583
|
}
|
|
16369
|
-
|
|
16370
|
-
|
|
16371
|
-
|
|
16372
|
-
// src/@modules/@eas/eas.getMergedPCM16.ts
|
|
16373
|
-
var getMergedPCM16 = (arrays) => {
|
|
16374
|
-
let total = 0;
|
|
16375
|
-
for (const a of arrays) total += a.length;
|
|
16376
|
-
const out = new Int16Array(total);
|
|
16377
|
-
let o = 0;
|
|
16378
|
-
for (const a of arrays) {
|
|
16379
|
-
out.set(a, o);
|
|
16380
|
-
o += a.length;
|
|
16584
|
+
const reconnectThreshold = interval * 1e3;
|
|
16585
|
+
if (!bootstrap.cache.isConnected && !bootstrap.cache.sigHault || !bootstrap.session_xmpp) {
|
|
16586
|
+
return;
|
|
16381
16587
|
}
|
|
16382
|
-
|
|
16383
|
-
|
|
16384
|
-
|
|
16385
|
-
|
|
16386
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
|
|
16396
|
-
|
|
16397
|
-
|
|
16398
|
-
|
|
16588
|
+
if (lastStanza > reconnectThreshold) {
|
|
16589
|
+
if (!bootstrap.cache.isReconnecting) {
|
|
16590
|
+
bootstrap.cache.isReconnecting = true;
|
|
16591
|
+
bootstrap.cache.isConnected = false;
|
|
16592
|
+
bootstrap.cache.tReconnects += 1;
|
|
16593
|
+
try {
|
|
16594
|
+
setEventEmit({
|
|
16595
|
+
event: `onServiceStatus`,
|
|
16596
|
+
metadata: {
|
|
16597
|
+
message: `Attempting to reconnect to XMPP Service (Reconnect Attempt ${bootstrap.cache.tReconnects})`,
|
|
16598
|
+
data: {
|
|
16599
|
+
last_stanza: lastStanza,
|
|
16600
|
+
nickname: settings.NOAAWeatherWireServiceSettings.CredentialSettings.Nickname
|
|
16601
|
+
},
|
|
16602
|
+
type: `reconnect`,
|
|
16603
|
+
error: true
|
|
16604
|
+
}
|
|
16605
|
+
});
|
|
16606
|
+
yield bootstrap.session_xmpp.stop().catch(() => {
|
|
16607
|
+
});
|
|
16608
|
+
yield bootstrap.session_xmpp.start().catch(() => {
|
|
16609
|
+
});
|
|
16610
|
+
} catch (error) {
|
|
16611
|
+
setWarning({ message: `XMPP Reconnect Failed - ${error.message}` });
|
|
16612
|
+
} finally {
|
|
16613
|
+
bootstrap.cache.isReconnecting = false;
|
|
16614
|
+
}
|
|
16399
16615
|
}
|
|
16400
|
-
extendedBody.set(gap, extendedBodyDuration);
|
|
16401
|
-
bursts.push(extendedBody);
|
|
16402
|
-
if (i !== repeats - 1) bursts.push(gap);
|
|
16403
|
-
}
|
|
16404
|
-
return getMergedPCM16(bursts);
|
|
16405
|
-
};
|
|
16406
|
-
|
|
16407
|
-
// src/@modules/@eas/eas.setAttentionTone.ts
|
|
16408
|
-
var setAttentionTone = (ms, sampleRate) => {
|
|
16409
|
-
const len = Math.floor(ms * sampleRate);
|
|
16410
|
-
const out = new Int16Array(len);
|
|
16411
|
-
const f1 = 853;
|
|
16412
|
-
const f2 = 960;
|
|
16413
|
-
const twoPi = Math.PI * 2;
|
|
16414
|
-
const amp = 0.1;
|
|
16415
|
-
const fadeLen = Math.floor(sampleRate * 0);
|
|
16416
|
-
for (let i = 0; i < len; i++) {
|
|
16417
|
-
const t = i / sampleRate;
|
|
16418
|
-
const s = Math.sin(twoPi * f1 * t) + Math.sin(twoPi * f2 * t);
|
|
16419
|
-
let gain = 1;
|
|
16420
|
-
if (i < fadeLen) gain = i / fadeLen;
|
|
16421
|
-
else if (i > len - fadeLen) gain = (len - i) / fadeLen;
|
|
16422
|
-
const v = Math.max(-1, Math.min(1, s / 2 * amp * gain));
|
|
16423
|
-
out[i] = Math.round(v * 32767);
|
|
16424
|
-
}
|
|
16425
|
-
return out;
|
|
16426
|
-
};
|
|
16427
|
-
|
|
16428
|
-
// src/@modules/@eas/eas.setNoise.ts
|
|
16429
|
-
var setNoise = (int16, noiseLevel = 0.02) => {
|
|
16430
|
-
const x = getPCMToFloat(int16);
|
|
16431
|
-
for (let i = 0; i < x.length; i++) x[i] += (Math.random() * 2 - 1) * noiseLevel;
|
|
16432
|
-
let peak = 0;
|
|
16433
|
-
for (let i = 0; i < x.length; i++) peak = Math.max(peak, Math.abs(x[i]));
|
|
16434
|
-
if (peak > 1) for (let i = 0; i < x.length; i++) x[i] *= 0.98 / peak;
|
|
16435
|
-
return getFloatPCM16(x);
|
|
16436
|
-
};
|
|
16437
|
-
|
|
16438
|
-
// src/@modules/@eas/eas.getPCM16.ts
|
|
16439
|
-
var getPCM16 = (samples, sampleRate) => {
|
|
16440
|
-
let o = 0;
|
|
16441
|
-
const bytesPerSample = 2;
|
|
16442
|
-
const blockAlign = 1 * bytesPerSample;
|
|
16443
|
-
const byteRate = sampleRate * blockAlign;
|
|
16444
|
-
const subchunk2Size = samples.length * bytesPerSample;
|
|
16445
|
-
const chunkSize = 36 + subchunk2Size;
|
|
16446
|
-
const buffer = Buffer.alloc(44 + subchunk2Size);
|
|
16447
|
-
buffer.write("RIFF", o);
|
|
16448
|
-
o += 4;
|
|
16449
|
-
buffer.writeUInt32LE(chunkSize, o);
|
|
16450
|
-
o += 4;
|
|
16451
|
-
buffer.write("WAVE", o);
|
|
16452
|
-
o += 4;
|
|
16453
|
-
buffer.write("fmt ", o);
|
|
16454
|
-
o += 4;
|
|
16455
|
-
buffer.writeUInt32LE(16, o);
|
|
16456
|
-
o += 4;
|
|
16457
|
-
buffer.writeUInt16LE(1, o);
|
|
16458
|
-
o += 2;
|
|
16459
|
-
buffer.writeUInt16LE(1, o);
|
|
16460
|
-
o += 2;
|
|
16461
|
-
buffer.writeUInt32LE(sampleRate, o);
|
|
16462
|
-
o += 4;
|
|
16463
|
-
buffer.writeUInt32LE(byteRate, o);
|
|
16464
|
-
o += 4;
|
|
16465
|
-
buffer.writeUInt16LE(blockAlign, o);
|
|
16466
|
-
o += 2;
|
|
16467
|
-
buffer.writeUInt16LE(16, o);
|
|
16468
|
-
o += 2;
|
|
16469
|
-
buffer.write("data", o);
|
|
16470
|
-
o += 4;
|
|
16471
|
-
buffer.writeUInt32LE(subchunk2Size, o);
|
|
16472
|
-
o += 4;
|
|
16473
|
-
for (let i = 0; i < samples.length; i++, o += 2) {
|
|
16474
|
-
buffer.writeInt16LE(samples[i].value, o);
|
|
16475
16616
|
}
|
|
16476
|
-
|
|
16477
|
-
};
|
|
16617
|
+
});
|
|
16478
16618
|
|
|
16479
|
-
// src/@modules/@
|
|
16480
|
-
import {
|
|
16481
|
-
import {
|
|
16482
|
-
|
|
16483
|
-
import { platform } from "os";
|
|
16484
|
-
import say from "say";
|
|
16485
|
-
var setEasTone = (options) => __async(null, null, function* () {
|
|
16619
|
+
// src/@modules/@utilities/utilities.setCronSchedule.ts
|
|
16620
|
+
import { readdirSync, unlinkSync as unlinkSync2, statSync, existsSync as existsSync3 } from "fs";
|
|
16621
|
+
import { join as join2 } from "path";
|
|
16622
|
+
var setCronSchedule = () => __async(null, null, function* () {
|
|
16486
16623
|
const settings = bootstrap.settings;
|
|
16487
|
-
const
|
|
16488
|
-
const
|
|
16489
|
-
|
|
16490
|
-
|
|
16491
|
-
|
|
16492
|
-
|
|
16493
|
-
|
|
16494
|
-
|
|
16495
|
-
|
|
16496
|
-
|
|
16497
|
-
|
|
16498
|
-
|
|
16499
|
-
|
|
16624
|
+
const TTL = settings.GlobalSettings.ArchiveSettings.TTL;
|
|
16625
|
+
const TTLCUT = Date.now() - TTL * 1e3;
|
|
16626
|
+
const walk = (dir) => {
|
|
16627
|
+
if (existsSync3(dir)) {
|
|
16628
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
16629
|
+
for (const entry of entries) {
|
|
16630
|
+
const fullPath = join2(dir, entry.name);
|
|
16631
|
+
if (entry.isDirectory()) {
|
|
16632
|
+
walk(fullPath);
|
|
16633
|
+
continue;
|
|
16634
|
+
}
|
|
16635
|
+
const stats = statSync(fullPath);
|
|
16636
|
+
if (stats.mtime.getTime() < TTLCUT) {
|
|
16637
|
+
try {
|
|
16638
|
+
unlinkSync2(fullPath);
|
|
16639
|
+
} catch (err) {
|
|
16640
|
+
console.error(`Failed to delete ${fullPath}:`, err);
|
|
16641
|
+
}
|
|
16642
|
+
}
|
|
16643
|
+
}
|
|
16644
|
+
}
|
|
16645
|
+
};
|
|
16646
|
+
walk(settings.GlobalSettings.ArchiveSettings.TextDirectory);
|
|
16647
|
+
walk(settings.GlobalSettings.ArchiveSettings.EasDirectory);
|
|
16648
|
+
if (settings.EnableWireService) {
|
|
16649
|
+
if (settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.Enabled) {
|
|
16650
|
+
void xReconnect(settings.NOAAWeatherWireServiceSettings.ReconnectionSettings.ReconnectionInterval);
|
|
16651
|
+
}
|
|
16652
|
+
} else {
|
|
16653
|
+
const response2 = yield createHttp({
|
|
16654
|
+
url: settings.NationalWeatherServiceSettings.EventsEndpoint,
|
|
16655
|
+
headers: {
|
|
16656
|
+
"User-Agent": "@atmosx/event-product-parser"
|
|
16657
|
+
}
|
|
16658
|
+
});
|
|
16659
|
+
if (response2.error) {
|
|
16660
|
+
return setEventEmit({
|
|
16661
|
+
event: `onServiceStatus`,
|
|
16662
|
+
metadata: {
|
|
16663
|
+
type: "fetch-api",
|
|
16664
|
+
message: `Failed to fetch latest events from National Weather Service API - ${response2.message}`,
|
|
16665
|
+
data: {},
|
|
16666
|
+
error: true
|
|
16667
|
+
}
|
|
16668
|
+
});
|
|
16669
|
+
}
|
|
16670
|
+
setEventEmit({
|
|
16671
|
+
event: `onServiceStatus`,
|
|
16672
|
+
metadata: {
|
|
16673
|
+
message: `Fetched latest events from National Weather Service API`,
|
|
16674
|
+
data: {},
|
|
16675
|
+
type: "fetch-api",
|
|
16676
|
+
error: false
|
|
16677
|
+
}
|
|
16678
|
+
});
|
|
16679
|
+
createEvent({ message: response2.message, isNWWS: false });
|
|
16500
16680
|
}
|
|
16501
|
-
|
|
16502
|
-
|
|
16681
|
+
});
|
|
16682
|
+
|
|
16683
|
+
// src/@manager/manager.updateEvents.ts
|
|
16684
|
+
var updateEvents = (selectedEvent) => __async(null, null, function* () {
|
|
16685
|
+
const events = bootstrap.cache.events.features;
|
|
16686
|
+
function update(evt) {
|
|
16687
|
+
return __async(this, null, function* () {
|
|
16688
|
+
if (new Date(evt.properties.expires) < /* @__PURE__ */ new Date()) {
|
|
16689
|
+
rmEvent(evt);
|
|
16690
|
+
}
|
|
16691
|
+
});
|
|
16503
16692
|
}
|
|
16504
|
-
if (!
|
|
16505
|
-
|
|
16693
|
+
if (!selectedEvent) {
|
|
16694
|
+
yield Promise.all(events.map((evt) => __async(null, null, function* () {
|
|
16695
|
+
yield update(evt);
|
|
16696
|
+
})));
|
|
16506
16697
|
}
|
|
16507
|
-
|
|
16508
|
-
|
|
16698
|
+
if (selectedEvent) {
|
|
16699
|
+
yield update(selectedEvent);
|
|
16509
16700
|
}
|
|
16510
|
-
|
|
16511
|
-
|
|
16512
|
-
|
|
16513
|
-
|
|
16701
|
+
});
|
|
16702
|
+
|
|
16703
|
+
// src/@core/core.start.ts
|
|
16704
|
+
import { Cron } from "croner";
|
|
16705
|
+
var startService = (configurations) => __async(null, null, function* () {
|
|
16706
|
+
if (!bootstrap.isReady) {
|
|
16707
|
+
return setWarning({
|
|
16708
|
+
message: `You can not create another instance without shutting down the current one first, please make sure to call the stop() method first!`
|
|
16514
16709
|
});
|
|
16515
|
-
return null;
|
|
16516
16710
|
}
|
|
16517
|
-
|
|
16518
|
-
|
|
16519
|
-
|
|
16711
|
+
const settings = setSettings(configurations);
|
|
16712
|
+
bootstrap.isReady = true;
|
|
16713
|
+
yield initializeDatabase();
|
|
16714
|
+
if (settings.EnableWireService) {
|
|
16715
|
+
(() => __async(null, null, function* () {
|
|
16716
|
+
yield getCachedEvents();
|
|
16717
|
+
yield xDeploy();
|
|
16718
|
+
}))();
|
|
16520
16719
|
}
|
|
16521
|
-
|
|
16522
|
-
|
|
16523
|
-
|
|
16524
|
-
|
|
16525
|
-
|
|
16526
|
-
|
|
16527
|
-
|
|
16720
|
+
yield setCronSchedule();
|
|
16721
|
+
let scheduleInterval = !settings.EnableWireService ? settings.NationalWeatherServiceSettings.CallbackInterval : 1;
|
|
16722
|
+
if (!settings.EnableWireService && scheduleInterval < 15) {
|
|
16723
|
+
setWarning({ message: `Schedule interval of ${scheduleInterval} seconds is too low, setting to 15 seconds` });
|
|
16724
|
+
bootstrap.settings.NationalWeatherServiceSettings.CallbackInterval = 15;
|
|
16725
|
+
scheduleInterval = 15;
|
|
16726
|
+
}
|
|
16727
|
+
bootstrap.cron = new Cron(`*/${scheduleInterval} * * * * *`, () => __async(null, null, function* () {
|
|
16728
|
+
yield setCronSchedule();
|
|
16729
|
+
}));
|
|
16730
|
+
bootstrap.cron = new Cron(`* * * * * *`, () => __async(null, null, function* () {
|
|
16731
|
+
yield updateNode();
|
|
16732
|
+
yield updateEvents();
|
|
16733
|
+
}));
|
|
16734
|
+
});
|
|
16735
|
+
|
|
16736
|
+
// src/@core/core.stop.ts
|
|
16737
|
+
var stopService = () => __async(null, null, function* () {
|
|
16738
|
+
if (bootstrap.isReady) {
|
|
16739
|
+
bootstrap.isReady = false;
|
|
16740
|
+
if (bootstrap.session_xmpp) {
|
|
16528
16741
|
try {
|
|
16529
|
-
|
|
16530
|
-
execSync(`ffmpeg -y -i "${prefix}" -ar 8000 -ac 1 -sample_fmt s16 "${converted}"`, { stdio: "ignore" });
|
|
16531
|
-
if (existsSync(converted)) {
|
|
16532
|
-
tBuffer = readFileSync(converted);
|
|
16533
|
-
tWav = getWavPCM16(tBuffer);
|
|
16534
|
-
try {
|
|
16535
|
-
unlinkSync(converted);
|
|
16536
|
-
} catch (e) {
|
|
16537
|
-
}
|
|
16538
|
-
}
|
|
16742
|
+
yield bootstrap.session_xmpp.stop();
|
|
16539
16743
|
} catch (e) {
|
|
16540
16744
|
}
|
|
16745
|
+
bootstrap.cache.isConnected = false;
|
|
16746
|
+
bootstrap.cache.sigHault = true;
|
|
16747
|
+
bootstrap.session_xmpp = null;
|
|
16541
16748
|
}
|
|
16542
|
-
if (tWav == null) {
|
|
16543
|
-
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.` });
|
|
16544
|
-
return null;
|
|
16545
|
-
}
|
|
16546
|
-
const tSamples = tWav.sampleRate != 8e3 ? getSampledPCM16(tWav.samples, tWav.sampleRate, 8e3) : tWav.samples;
|
|
16547
|
-
buffRadio = setRadioEffect(tSamples, 8e3);
|
|
16548
|
-
}
|
|
16549
|
-
buffFull = buffRadio != null ? [buffRadio, new Int16Array(Math.floor(0.5 * 8e3))] : [];
|
|
16550
|
-
buffFull.push(
|
|
16551
|
-
setSameHeader(header, 3, 8e3, {
|
|
16552
|
-
preMarkSec: 1.1,
|
|
16553
|
-
gapSec: 0.5
|
|
16554
|
-
}),
|
|
16555
|
-
new Int16Array(Math.floor(0.5 * 8e3)),
|
|
16556
|
-
setAttentionTone(8, 8e3),
|
|
16557
|
-
new Int16Array(Math.floor(0.5 * 8e3)),
|
|
16558
|
-
vRadio
|
|
16559
|
-
);
|
|
16560
|
-
for (let i = 0; i < 3; i++) {
|
|
16561
|
-
buffFull.push(setSameHeader(header, 1, 8e3, { preMarkSec: 0.5, gapSec: 0.1 }));
|
|
16562
|
-
buffFull.push(new Int16Array(Math.floor(0.5 * 8e3)));
|
|
16563
|
-
}
|
|
16564
|
-
const aSamples = getMergedPCM16(buffFull);
|
|
16565
|
-
const aFinal = setNoise(aSamples, 2e-3);
|
|
16566
|
-
const aBuffer = getPCM16(Array.from(aFinal).map((v) => ({ value: v })), 8e3);
|
|
16567
|
-
writeFileSync(outTTS, aBuffer);
|
|
16568
|
-
try {
|
|
16569
|
-
unlinkSync(tmpTTS);
|
|
16570
|
-
} catch (e) {
|
|
16571
16749
|
}
|
|
16572
|
-
return outTTS;
|
|
16573
16750
|
});
|
|
16574
16751
|
|
|
16575
16752
|
// src/@core/core.setNode.ts
|
|
@@ -16635,6 +16812,59 @@ var getNodes = () => {
|
|
|
16635
16812
|
return bootstrap.cache.nodes;
|
|
16636
16813
|
};
|
|
16637
16814
|
|
|
16815
|
+
// src/@core/core.createEvent.ts
|
|
16816
|
+
var createEvent2 = (options) => {
|
|
16817
|
+
var _a;
|
|
16818
|
+
const tick = performance.now();
|
|
16819
|
+
validateEvents([{
|
|
16820
|
+
type: `Feature`,
|
|
16821
|
+
geometry: {
|
|
16822
|
+
type: `Point`,
|
|
16823
|
+
coordinates: options.coordinates
|
|
16824
|
+
},
|
|
16825
|
+
properties: {
|
|
16826
|
+
event: options.event,
|
|
16827
|
+
parent: options.event,
|
|
16828
|
+
status: options.status,
|
|
16829
|
+
issued: options.issued.toISOString(),
|
|
16830
|
+
expires: options.expires.toISOString(),
|
|
16831
|
+
locations: options.locations,
|
|
16832
|
+
description: options.description,
|
|
16833
|
+
geocode: {
|
|
16834
|
+
office: {
|
|
16835
|
+
office: `ATMX`,
|
|
16836
|
+
name: `AtmosphericX Manual Event`
|
|
16837
|
+
},
|
|
16838
|
+
organization: `AtmosphericX`,
|
|
16839
|
+
ugc: [],
|
|
16840
|
+
polygon: options.coordinates.length > 0 ? Buffer.from(JSON.stringify([options.coordinates[0]])).toString("base64") : null,
|
|
16841
|
+
polygon_generated: options.coordinates.length > 0 ? true : false
|
|
16842
|
+
},
|
|
16843
|
+
status_metadata: {
|
|
16844
|
+
is_issued: options.status == `Issued`,
|
|
16845
|
+
is_updated: options.status == `Updated`,
|
|
16846
|
+
is_expired: options.status == `Expired`,
|
|
16847
|
+
is_test: options.status == `Test`,
|
|
16848
|
+
is_statement: options.status == `Statement`
|
|
16849
|
+
},
|
|
16850
|
+
metadata: {
|
|
16851
|
+
ms: performance.now() - tick,
|
|
16852
|
+
source: `events.manual`,
|
|
16853
|
+
tracking: `ATMX-M-W-01`,
|
|
16854
|
+
header: `ZCZC-ATMOSX-ATMX-M-W-01`,
|
|
16855
|
+
raw: options.description,
|
|
16856
|
+
history: [
|
|
16857
|
+
{
|
|
16858
|
+
description: options.description,
|
|
16859
|
+
issued: options.issued.toISOString(),
|
|
16860
|
+
status: (_a = options.status) != null ? _a : null
|
|
16861
|
+
}
|
|
16862
|
+
]
|
|
16863
|
+
}
|
|
16864
|
+
}
|
|
16865
|
+
}]);
|
|
16866
|
+
};
|
|
16867
|
+
|
|
16638
16868
|
// src/@core/core.getRandomEvent.ts
|
|
16639
16869
|
var getRandomEvent = () => {
|
|
16640
16870
|
return bootstrap.cache.events.features[Math.floor(Math.random() * bootstrap.cache.events.features.length)];
|
|
@@ -16694,6 +16924,7 @@ var index_default = Manager;
|
|
|
16694
16924
|
export {
|
|
16695
16925
|
Manager,
|
|
16696
16926
|
clearEvents,
|
|
16927
|
+
createEvent2 as createEvent,
|
|
16697
16928
|
index_default as default,
|
|
16698
16929
|
getCleanedEvent,
|
|
16699
16930
|
getEventGeometry,
|