@aeroswarm/weather 0.1.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,3 +46,69 @@ temperature) for any model source. `parseWeatherGridSeries`, `serializeWeatherGr
46
46
  `seriesFieldsAt`, and the Open-Meteo adapter (`latticePoints`, `weatherGridFromOpenMeteo`) are in the
47
47
  package; the network call stays in the app.
48
48
 
49
+ ## Tokens that are understood
50
+
51
+ Checked against 2,400 real METAR/SPECI and 212 real TAF from 100+ airports (see `test/fixtures/README.md`).
52
+ Every token of that corpus is either read or recognised as a group the model does not use; the one
53
+ exception is a typo in the source (`VEB03KT`), which stays visible in `unparsed`.
54
+
55
+ | Group | Read into the model | Recognised, not modelled |
56
+ |---|---|---|
57
+ | Wind | `dddffKT`, `dddffGggKT`, `dddffMPS`, `VRB`, variable range `dddVddd` (also glued to the wind group) | |
58
+ | Visibility | metres (`9999`, `0750`), statute miles (`10SM`, `1/2SM`, `1 1/2SM`, `P6SM`), `CAVOK` | directional lowest visibility (`0500NE`) |
59
+ | RVR | `R06R/0600N`, `R28/P2000`, `R35L/1200V1400FT` (metres or feet, trend, variable) in `conditions.rvr` | runway state (`R06C/CLRD62`, `R88/090065`) |
60
+ | Weather | intensity, descriptor and phenomena (`+TSRA`, `VCTS`, `FZFG`, `BCFG`...), `NSW` | recent weather (`RERA`, `RETS`) |
61
+ | Cloud | `FEW/SCT/BKN/OVC` with `CB/TCU`, `VV`, `SKC/CLR/NSC/NCD` | |
62
+ | Temperature, pressure | `tt/dd` (also `M`), `Qpppp`, `Appp` (inHg to hPa) | |
63
+ | Flags, trend | `AUTO`, `COR`, `NOSIG`, `BECMG`, `TEMPO`; everything after `RMK` is ignored | `//` (missing group), wind shear (`WS020/14030KT`, `WS R10`, `WS ALL RWY`) |
64
+ | TAF | `AMD`, `COR`, `CNL`, `FMddhhmm`, `BECMG`, `TEMPO`, `PROBnn [TEMPO]`, `TX/TN` | remarks |
65
+
66
+ A token that is none of these ends up in `Metar.unparsed` / `TafPeriod.unparsed` instead of silently
67
+ disappearing. A report with an impossible date (for example `0000/0000`) is rejected (`null`), not
68
+ guessed. A fuzz test mutates real reports (truncated, tokens removed, inserted, swapped) and requires
69
+ that the parser never throws and never returns invalid numbers or dates.
70
+
71
+ Not supported: the US domestic SIGMET formats (convective SIGMET, `AREA EMBD TS ...` with VOR-radial
72
+ points), graphical G-AIRMET, and ICAO Annex 3 trend groups with `FM`/`TL`/`AT` times inside a METAR
73
+ trend.
74
+
75
+
76
+
77
+ ## Warnings and special messages
78
+
79
+ `decodeWeatherMessage` and `extractReports` also recognise these, and tell them apart by `kind`:
80
+
81
+ | Kind | Reader | What is read | Verified against |
82
+ |---|---|---|---|
83
+ | `NIL` | `parseNil` | `METAR/SPECI/TAF [COR/AMD] ICAO [ddhhmmZ] NIL` | ICAO template only (no real NIL in the corpus) |
84
+ | `SIGMET`, `AIRMET` | `parseSigmet` | FIR, series, validity, MWO, hazard (thunderstorm, turbulence, icing, mountain wave, volcanic ash, tropical cyclone, dust/sand storm, radioactive cloud, surface wind/visibility/cloud, cancellation), observed or forecast time, area (polygon, line with side, circle, latitude/longitude line, corridor, entire FIR, several areas), levels, movement, trend, volcano and cyclone names with positions, forecast position | 124 real SIGMET (aviationweather.gov); AIRMET only against the Annex 3 template |
85
+ | `VAA` | `parseVaa` | VAAC, issue time, volcano and number, position, summit elevation, advisory number, colour code, eruption details, observed/estimated ash cloud, +6/+12/+18 h forecasts (layers with boundary points, movement, wind at the vent level), remarks, next advisory | 60 real advisories (Tokyo VAAC, JMA) |
86
+ | `SNOWTAM` | `parseSnowtam` | lettered format A) to T): aerodrome, assessment time, every runway (cleared length and width, deposits and depth per third, friction), next observation, remarks. The global reporting format: head only (aerodrome, time), the rest in `unparsed` | Annex 15 items only (no real message) |
87
+
88
+ Anything in these messages that is not understood is returned in `unparsed`, not dropped.
89
+ A message whose header cannot be read returns `null`. The store counts these messages as `other`
90
+ and does not keep them (they are not weather conditions at a station).
91
+
92
+ Honest limits: AIRMET, NIL and SNOWTAM were written from the ICAO specification because no real
93
+ messages could be collected (aviationweather.gov does not publish them; the Bureau of Meteorology
94
+ blocks automated access, so Darwin VAAC advisories were not collected). Treat those three as
95
+ specification-checked, not field-proven, until real samples are added to `test/fixtures`.
96
+
97
+ ## Operational information
98
+
99
+ Pure functions that turn conditions into what an aerodrome operation needs. Decisions never rely on
100
+ a guessed threshold: limits, minima and LVP values are passed in by the caller.
101
+
102
+ | Function | Gives |
103
+ |---|---|
104
+ | `flightCategory(conditions, thresholds?)` | VFR / MVFR / IFR / LIFR from visibility and ceiling (lowest BKN/OVC/VV), what decided it, and whether the ceiling is unknown. Defaults follow the FAA definition (ICAO has no categories); replace with `thresholds` |
105
+ | `windComponents(wind, runwayHeadingTrue)` | headwind, tailwind, crosswind and the side it comes from. A variable wind gives only the upper bound |
106
+ | `runwayAdvice(wind, runways, limits?)` | per runway and direction: steady and gust components, the more favourable direction, `exceeds` flags only for limits you give |
107
+ | `runwayFromHeading`, `runwayFromPolygon`, `headingFromPolygon`, `magneticToTrue` | build runways. METAR wind is **true**; runway headings are usually magnetic, so pass the magnetic variation |
108
+ | `evaluateMinima(conditions, minima)` | below/above, with every reason, and `unknown` for data that is missing or cannot decide (`P2000`, `M0050`). Missing data is never treated as safe. The same function serves LVP thresholds |
109
+ | `upcomingChanges(taf, from, hours, options?)` | category changes, thunderstorm/CB start and end, heavy precipitation, and (when you give the threshold) low visibility and wind changes, each with the TAF group that causes it. What is already happening at `from` is marked `ongoing` |
110
+ | `qnhTrend(previous, current, options?)` | change, rate and direction; `rapid` only against a rate you give |
111
+ | `stationOperations(store, station, at, config?)` | all of the above for one station from a `WeatherStore` |
112
+
113
+ Decision aid, not an official source.
114
+
package/dist/aftn.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import type { ReportKind } from "./types.js";
2
2
  export interface RawReport {
3
3
  kind: ReportKind;
4
- /** Teks laporan dari kata kunci (METAR/SPECI/TAF) sampai sebelum `=`, spasi dirapikan. */
4
+ /** Teks laporan dari kata kunci sampai sebelum laporan berikutnya, spasi dirapikan. */
5
5
  text: string;
6
6
  }
7
7
  /**
8
- * Ambil laporan cuaca dari teks mentah: boleh berupa laporan polos, buletin dengan header
9
- * (`SAID31 WARR 021030`), atau pesan AFTN lengkap (`ZCZC ... NNNN` dengan baris alamat). Satu pesan
10
- * bisa memuat beberapa laporan yang masing-masing diakhiri `=`.
8
+ * Ambil laporan dari teks mentah: boleh berupa laporan polos, buletin dengan header
9
+ * (`SAID31 WARR 021030`), atau pesan AFTN lengkap (`ZCZC ... NNNN` dengan baris alamat). Banyak laporan
10
+ * dalam satu pesan dipisah per kata kunci, dengan atau tanpa tanda `=`.
11
11
  */
12
12
  export declare function extractReports(message: string): RawReport[];
13
13
  //# sourceMappingURL=aftn.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"aftn.d.ts","sourceRoot":"","sources":["../src/aftn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAC;CACd;AAID;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAe3D"}
1
+ {"version":3,"file":"aftn.d.ts","sourceRoot":"","sources":["../src/aftn.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,UAAU,CAAC;IACjB,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;CACd;AAYD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,CAwB3D"}
@@ -78,9 +78,25 @@ export interface SnapshotInput {
78
78
  maxObservationAgeMs?: number;
79
79
  includeProbable?: boolean;
80
80
  }
81
+ /** Kondisi yang berlaku di satu stasiun pada satu waktu, dan dari mana asalnya. */
82
+ export interface SelectedConditions {
83
+ conditions: Conditions;
84
+ source: AnimationSource;
85
+ station: string;
86
+ /** Waktu yang diwakili data ini. */
87
+ validAt: Date;
88
+ /** Pengamatan lebih tua dari batas, dan tidak ada TAF yang berlaku sebagai gantinya. */
89
+ stale: boolean;
90
+ /** Dari TAF: kondisi sementara (TEMPO) sedang berlaku. */
91
+ temporary: boolean;
92
+ /** Dari TAF: 0-1 selama transisi BECMG berjalan. */
93
+ transition: number | null;
94
+ }
81
95
  /**
82
96
  * Pilih sumber terbaik untuk waktu `at`: pengamatan (METAR/SPECI) yang masih segar, lalu TAF yang
83
97
  * berlaku, lalu pengamatan lama (ditandai stale). Null bila tidak ada data sama sekali.
84
98
  */
99
+ export declare function selectConditions(input: SnapshotInput): SelectedConditions | null;
100
+ /** Seperti `selectConditions`, tetapi sudah diubah menjadi parameter animasi. */
85
101
  export declare function animationSnapshot(input: SnapshotInput): AnimationSnapshot | null;
86
102
  //# sourceMappingURL=animation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,UAAU,EAAE,KAAK,EAAkB,GAAG,EAAE,MAAM,YAAY,CAAC;AAErF,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAC7E,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE1F,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,uDAAuD;IACvD,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAC7B,mEAAmE;IACnE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,yDAAyD;QACzD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,wEAAwE;QACxE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,EAAE,MAAM,CAAC;QAChB,mFAAmF;QACnF,SAAS,EAAE,MAAM,CAAC;QAClB,+EAA+E;QAC/E,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,iDAAiD;QACjD,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,UAAU,EAAE;QACV,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,6DAA6D;QAC7D,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IACF,WAAW,EAAE;QAAE,IAAI,EAAE,eAAe,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC/D,aAAa,EAAE;QACb,IAAI,EAAE,iBAAiB,CAAC;QACxB,+CAA+C;QAC/C,SAAS,EAAE,MAAM,CAAC;QAClB,kEAAkE;QAClE,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,OAAO,CAAC;KACnB,GAAG,IAAI,CAAC;IACT,YAAY,EAAE;QACZ,oCAAoC;QACpC,QAAQ,EAAE,OAAO,CAAC;QAClB,uCAAuC;QACvC,QAAQ,EAAE,OAAO,CAAC;QAClB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,GAAG,IAAI,CAAC;CACV;AAuED,kFAAkF;AAClF,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc,CA+D9E;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,OAAO,GAAG,KAAK,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,OAAO,EAAE,IAAI,CAAC;IACd,wFAAwF;IACxF,KAAK,EAAE,OAAO,CAAC;IACf,0DAA0D;IAC1D,SAAS,EAAE,OAAO,CAAC;IACnB,oDAAoD;IACpD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,yFAAyF;IACzF,EAAE,CAAC,EAAE,IAAI,CAAC;IACV,iGAAiG;IACjG,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,GAAG,iBAAiB,GAAG,IAAI,CA6ChF"}
1
+ {"version":3,"file":"animation.d.ts","sourceRoot":"","sources":["../src/animation.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { CloudLayer, Conditions, PresentWeather, Wind } from "./types.js";
1
+ import type { CloudLayer, Conditions, PresentWeather, Rvr, Wind } from "./types.js";
2
2
  export declare function emptyConditions(): Conditions;
3
3
  export interface ConditionTokens {
4
4
  wind?: Wind;
@@ -6,6 +6,7 @@ export interface ConditionTokens {
6
6
  cavok?: boolean;
7
7
  clouds?: CloudLayer[];
8
8
  weather?: PresentWeather[];
9
+ rvr?: Rvr[];
9
10
  noSignificantWeather?: boolean;
10
11
  /** Token yang tidak dikenali (diteruskan ke pemanggil, mis. suhu atau QNH). */
11
12
  rest: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EACV,cAAc,EACd,IAAI,EAEL,MAAM,YAAY,CAAC;AAYpB,wBAAgB,eAAe,IAAI,UAAU,CAa5C;AAgCD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAkFtE;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D,UAAU,CAqBZ"}
1
+ {"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../src/conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,UAAU,EACV,UAAU,EACV,cAAc,EACd,GAAG,EACH,IAAI,EAEL,MAAM,YAAY,CAAC;AAgCpB,wBAAgB,eAAe,IAAI,UAAU,CAa5C;AAgCD,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;IACZ,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,+EAA+E;IAC/E,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,qFAAqF;AACrF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CA+JtE;AAED,yFAAyF;AACzF,wBAAgB,eAAe,CAC7B,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG;IAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D,UAAU,CAsBZ"}
package/dist/geo.d.ts ADDED
@@ -0,0 +1,54 @@
1
+ /** Posisi dan ketinggian pada pesan peringatan (SIGMET, AIRMET, VAA): murni, tanpa jaringan. */
2
+ export interface GeoPosition {
3
+ lat: number;
4
+ lon: number;
5
+ }
6
+ export type Compass = "N" | "NNE" | "NE" | "ENE" | "E" | "ESE" | "SE" | "SSE" | "S" | "SSW" | "SW" | "WSW" | "W" | "WNW" | "NW" | "NNW";
7
+ export declare const isCompass: (value: string) => value is Compass;
8
+ /** Derajat dari utara untuk arah mata angin 16 titik. */
9
+ export declare const compassDegrees: (direction: Compass) => number;
10
+ /**
11
+ * Satu titik seperti `N1034 W07726` atau `S0200W07820`. Lintang `ddmm` (atau `dd`), bujur `dddmm` (atau
12
+ * `ddd`). Bujur empat angka (`W5815`, salah ketik yang ada pada laporan nyata) dibaca `ddmm`.
13
+ */
14
+ export declare const POINT: string;
15
+ export declare function parsePosition(text: string): GeoPosition | null;
16
+ /** Semua titik dalam teks, berurutan. */
17
+ export declare function parsePositions(text: string): GeoPosition[];
18
+ /** Rentang ketinggian dalam kaki; `null` = tidak disebut, `0` = permukaan (SFC). */
19
+ export interface AltitudeRange {
20
+ baseFt: number | null;
21
+ topFt: number | null;
22
+ /** `TOP ABV FL450`: puncaknya di atas nilai itu. */
23
+ topAbove?: boolean;
24
+ }
25
+ export declare const ALTITUDE_PATTERNS: {
26
+ /** `TOP FL490`, `TOP ABV FL450`, `TOP FL250/390`. */
27
+ readonly top: RegExp;
28
+ /** `FL240/300`, `SFC/FL100`, `SFC/6000FT`, `2000/4000FT`. */
29
+ readonly range: RegExp;
30
+ /** `ABV FL250` sendirian. */
31
+ readonly above: RegExp;
32
+ };
33
+ /**
34
+ * Cari satu petunjuk ketinggian dalam `text`. Mengembalikan rentangnya dan bagian teks yang dipakai,
35
+ * atau null.
36
+ */
37
+ export declare function findAltitude(text: string): {
38
+ range: AltitudeRange;
39
+ matched: string;
40
+ } | null;
41
+ export interface Movement {
42
+ stationary: boolean;
43
+ direction?: Compass;
44
+ /** Kecepatan (kt); untuk rentang (`10-15KT`) nilai terbesar. */
45
+ speedKt?: number;
46
+ /** Batas bawah bila kecepatan dilaporkan sebagai rentang. */
47
+ speedMinKt?: number;
48
+ }
49
+ /** `MOV NW 10KT`, `MOV ENE`, `MOV E 25KMH`, `STNR`. */
50
+ export declare function findMovement(text: string): {
51
+ movement: Movement;
52
+ matched: string;
53
+ } | null;
54
+ //# sourceMappingURL=geo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geo.d.ts","sourceRoot":"","sources":["../src/geo.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,OAAO,GACf,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,GACL,GAAG,GACH,KAAK,GACL,IAAI,GACJ,KAAK,CAAC;AAqBV,eAAO,MAAM,SAAS,GAAI,OAAO,MAAM,KAAG,KAAK,IAAI,OAAmC,CAAC;AAEvF,yDAAyD;AACzD,eAAO,MAAM,cAAc,GAAI,WAAW,OAAO,KAAG,MAAoC,CAAC;AAEzF;;;GAGG;AACH,eAAO,MAAM,KAAK,QAAwC,CAAC;AAW3D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAU9D;AAED,yCAAyC;AACzC,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,EAAE,CAO1D;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAeD,eAAO,MAAM,iBAAiB;IAC5B,qDAAqD;;IAErD,6DAA6D;;IAE7D,6BAA6B;;CAErB,CAAC;AAEX;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAsC3F;AAED,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAmBzF"}
package/dist/index.d.ts CHANGED
@@ -2,16 +2,25 @@ import type { Report } from "./types.js";
2
2
  export * from "./aftn.js";
3
3
  export * from "./animation.js";
4
4
  export * from "./conditions.js";
5
+ export * from "./geo.js";
5
6
  export * from "./grid.js";
6
7
  export * from "./gridSeries.js";
7
8
  export * from "./openMeteo.js";
8
9
  export * from "./metar.js";
10
+ export * from "./nil.js";
11
+ export * from "./operations.js";
12
+ export * from "./ops.js";
13
+ export * from "./runway.js";
14
+ export * from "./sigmet.js";
15
+ export * from "./snowtam.js";
9
16
  export * from "./taf.js";
10
17
  export * from "./store.js";
11
18
  export * from "./time.js";
12
19
  export * from "./types.js";
20
+ export * from "./vaa.js";
13
21
  /**
14
- * Baca semua laporan cuaca (METAR, SPECI, TAF) dari satu pesan mentah, termasuk bungkus AFTN.
22
+ * Baca semua laporan cuaca dari satu pesan mentah, termasuk bungkus AFTN: METAR, SPECI, TAF, NIL,
23
+ * SIGMET, AIRMET, pemberitahuan abu vulkanik (VAA), dan SNOWTAM.
15
24
  * Laporan yang tidak terbaca dilewati. `reference` = waktu pesan diterima (menentukan bulan/tahun).
16
25
  */
17
26
  export declare function decodeWeatherMessage(message: string, reference?: Date): Report[];
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAE3B;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,IAAiB,GAC3B,MAAM,EAAE,CAUV"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEzC,cAAc,WAAW,CAAC;AAC1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,WAAW,CAAC;AAC1B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AAEzB;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,GAAE,IAAiB,GAC3B,MAAM,EAAE,CA0BV"}