@fboes/aerofly-custom-missions 1.0.4 → 1.1.1
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/CHANGELOG.md +12 -0
- package/README.md +46 -1
- package/dist/index.js +119 -28
- package/dist/index.test.js +29 -6
- package/package.json +1 -1
- package/src/index.test.ts +33 -7
- package/src/index.ts +201 -24
- package/types/index.d.ts +109 -6
- package/types/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.1
|
|
4
|
+
|
|
5
|
+
- Minor styling fixes
|
|
6
|
+
|
|
7
|
+
## 1.1.0
|
|
8
|
+
|
|
9
|
+
- Added new mission properties `tags`, `isFeatured`, `difficulty`, `distance`, `duration` and translations
|
|
10
|
+
- Added new flight settings `"winch_launch`, `aerotow`
|
|
11
|
+
- Improved temperature property
|
|
12
|
+
|
|
13
|
+
## 1.0.4
|
|
14
|
+
|
|
3
15
|
- Added documentation for known issues
|
|
4
16
|
- Added property `AeroflyMissionConditions.temperature`
|
|
5
17
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Builder for Aerofly FS4 Custom Missions Files
|
|
4
4
|
|
|
5
|
-
[Aerofly Flight Simulator 4](https://www.aerofly.com/) has a custom missions file `custom_missions_user.tmc` with a very unique format. To help you build this custom missions file, this JavaScript / TypeScript library offers Data Objects to create this file
|
|
5
|
+
[Aerofly Flight Simulator 4](https://www.aerofly.com/) has a custom missions file `custom_missions_user.tmc` with a very unique format. To help you build this custom missions file, this JavaScript / TypeScript library offers Data Objects to create this file programmatically.
|
|
6
6
|
|
|
7
7
|
This library is intended to work in modern browsers as well as [Node.js](https://nodejs.org/en).
|
|
8
8
|
|
|
@@ -119,6 +119,44 @@ console.log(missionList.toString());
|
|
|
119
119
|
|
|
120
120
|
As there are lots of properties for the mission object, check the type hinting on the various objects to find out which properties you are able to set.
|
|
121
121
|
|
|
122
|
+
### Values for tags
|
|
123
|
+
|
|
124
|
+
The `tags` property of a single mission can contain multiple values. The following values have been used officially by Aerofly FS4.
|
|
125
|
+
|
|
126
|
+
- aerobatics
|
|
127
|
+
- aerotow
|
|
128
|
+
- airline
|
|
129
|
+
- airshow
|
|
130
|
+
- circling_approach
|
|
131
|
+
- crosswind
|
|
132
|
+
- dropoff
|
|
133
|
+
- full_flight
|
|
134
|
+
- gliding
|
|
135
|
+
- instruments
|
|
136
|
+
- landing
|
|
137
|
+
- law_enforcement
|
|
138
|
+
- low_level_flight
|
|
139
|
+
- low_visibility
|
|
140
|
+
- medical
|
|
141
|
+
- military
|
|
142
|
+
- night
|
|
143
|
+
- pattern
|
|
144
|
+
- practice
|
|
145
|
+
- race
|
|
146
|
+
- short_runway
|
|
147
|
+
- sidestep_approach
|
|
148
|
+
- sight_seeing
|
|
149
|
+
- sloped_runway
|
|
150
|
+
- steep_approach
|
|
151
|
+
- straight_in_approach
|
|
152
|
+
- supersonic
|
|
153
|
+
- surveillance
|
|
154
|
+
- takeoff
|
|
155
|
+
- terrain_avoidance
|
|
156
|
+
- vip
|
|
157
|
+
- winch_launch
|
|
158
|
+
- windy
|
|
159
|
+
|
|
122
160
|
### Important notices
|
|
123
161
|
|
|
124
162
|
- Be aware that `mission.origin` and `mission.destination` do not need to match the flight plan. In case of `origin` you may want to set the position to the actual parking position of your aircraft, which may not be the first way point in your flight plan.
|
|
@@ -129,6 +167,13 @@ As there are lots of properties for the mission object, check the type hinting o
|
|
|
129
167
|
- `destination`
|
|
130
168
|
- Be aware that all units for altitude, elevation or distance are measured in meters! In most cases there will be helper functions for defining these values in feet (for length, altitude, elevation) or statute miles (for visibility).
|
|
131
169
|
|
|
170
|
+
There are also some unsupported properties, which are present in Aerofly FS4, but as of yet will not be generated by this library:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
<[string8][tutorial_name][c172]> // Opens https://www.aerofly.com/aircraft-tutorials/${tutorial_name}
|
|
174
|
+
<[bool][is_scheduled][true]>
|
|
175
|
+
```
|
|
176
|
+
|
|
132
177
|
### Known issues
|
|
133
178
|
|
|
134
179
|
- `AeroflyMissionConditions.time`: Even though a date property is available in Aerofly FS 4 (which is not accessible to the user), [the custom missions cannot change the date in Aerofly FS 4](https://www.aerofly.com/community/forum/index.php?thread/22487-more-settings-for-environment-conditions/&pageNo=1).
|
package/dist/index.js
CHANGED
|
@@ -40,15 +40,21 @@ export class AeroflyMission {
|
|
|
40
40
|
* @param {string} title of this flight plan
|
|
41
41
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
42
42
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
43
|
-
* @param {
|
|
43
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
44
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
45
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
46
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
47
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
44
48
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
45
49
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
46
50
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
47
51
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
52
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
53
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
48
54
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
49
55
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
50
56
|
*/
|
|
51
|
-
constructor(title, { description = "", flightSetting = "taxi", aircraft = {
|
|
57
|
+
constructor(title, { description = "", localizedTexts = [], tags = [], isFeatured = false, difficulty = undefined, flightSetting = "taxi", aircraft = {
|
|
52
58
|
name: "c172",
|
|
53
59
|
icao: "",
|
|
54
60
|
livery: "",
|
|
@@ -64,15 +70,21 @@ export class AeroflyMission {
|
|
|
64
70
|
latitude: 0,
|
|
65
71
|
dir: 0,
|
|
66
72
|
alt: 0,
|
|
67
|
-
}, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
|
|
73
|
+
}, distance = 0, duration = 0, conditions = new AeroflyMissionConditions(), checkpoints = [], } = {}) {
|
|
68
74
|
this.title = title;
|
|
69
75
|
this.checkpoints = checkpoints;
|
|
70
76
|
this.description = description;
|
|
77
|
+
this.localizedTexts = localizedTexts;
|
|
78
|
+
this.tags = tags;
|
|
79
|
+
this.isFeatured = isFeatured;
|
|
80
|
+
this.difficulty = difficulty;
|
|
71
81
|
this.flightSetting = flightSetting;
|
|
72
82
|
this.aircraft = aircraft;
|
|
73
83
|
this.callsign = callsign;
|
|
74
84
|
this.origin = origin;
|
|
75
85
|
this.destination = destination;
|
|
86
|
+
this.distance = distance;
|
|
87
|
+
this.duration = duration;
|
|
76
88
|
this.conditions = conditions;
|
|
77
89
|
}
|
|
78
90
|
/**
|
|
@@ -85,6 +97,16 @@ export class AeroflyMission {
|
|
|
85
97
|
})
|
|
86
98
|
.join("\n");
|
|
87
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* @returns {string} indexed checkpoints
|
|
102
|
+
*/
|
|
103
|
+
getLocalizedTextsString() {
|
|
104
|
+
return this.localizedTexts
|
|
105
|
+
.map((c, index) => {
|
|
106
|
+
return c.toString(index);
|
|
107
|
+
})
|
|
108
|
+
.join("\n");
|
|
109
|
+
}
|
|
88
110
|
/**
|
|
89
111
|
* @throws {Error} on missing waypoints
|
|
90
112
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -113,9 +135,31 @@ export class AeroflyMission {
|
|
|
113
135
|
alt: lastCheckpoint.altitude,
|
|
114
136
|
};
|
|
115
137
|
}
|
|
138
|
+
const optionalProperties = [];
|
|
139
|
+
if (this.localizedTexts.length > 0) {
|
|
140
|
+
optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
|
|
141
|
+
${this.getLocalizedTextsString()}
|
|
142
|
+
>`);
|
|
143
|
+
}
|
|
144
|
+
if (this.tags.length > 0) {
|
|
145
|
+
optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
|
|
146
|
+
}
|
|
147
|
+
if (this.difficulty !== undefined) {
|
|
148
|
+
optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
|
|
149
|
+
}
|
|
150
|
+
if (this.isFeatured) {
|
|
151
|
+
optionalProperties.push(` <[bool] [is_featured] [${this.isFeatured ? "true" : "false"}]>`);
|
|
152
|
+
}
|
|
153
|
+
const moreOptionalProperties = [];
|
|
154
|
+
if (this.distance) {
|
|
155
|
+
moreOptionalProperties.push(` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`);
|
|
156
|
+
}
|
|
157
|
+
if (this.duration) {
|
|
158
|
+
moreOptionalProperties.push(` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`);
|
|
159
|
+
}
|
|
116
160
|
return ` <[tmmission_definition][mission][]
|
|
117
161
|
<[string8][title][${this.title}]>
|
|
118
|
-
<[string8][description][${this.description}]>
|
|
162
|
+
<[string8][description][${this.description}]>${optionalProperties.length > 0 ? "\n" + optionalProperties.join("\n") : ""}
|
|
119
163
|
<[string8] [flight_setting] [${this.flightSetting}]>
|
|
120
164
|
<[string8u] [aircraft_name] [${this.aircraft.name}]>
|
|
121
165
|
//<[string8u][aircraft_livery] [${this.aircraft.livery}]>
|
|
@@ -123,11 +167,12 @@ export class AeroflyMission {
|
|
|
123
167
|
<[stringt8c] [callsign] [${this.callsign}]>
|
|
124
168
|
<[stringt8c] [origin_icao] [${this.origin.icao}]>
|
|
125
169
|
<[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
|
|
170
|
+
<[float64] [origin_alt] [${this.origin.alt}]> // ${Math.ceil(this.origin.alt * feetPerMeter)} ft MSL
|
|
126
171
|
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
127
|
-
<[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
|
|
128
172
|
<[stringt8c] [destination_icao] [${this.destination.icao}]>
|
|
129
173
|
<[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
|
|
130
|
-
<[float64] [
|
|
174
|
+
<[float64] [destination_alt] [${this.destination.alt}]> // ${Math.ceil(this.destination.alt * feetPerMeter)} ft MSL
|
|
175
|
+
<[float64] [destination_dir] [${this.destination.dir}]>${moreOptionalProperties.length > 0 ? "\n" + moreOptionalProperties.join("\n") : ""}
|
|
131
176
|
${this.conditions}
|
|
132
177
|
<[list_tmmission_checkpoint][checkpoints][]
|
|
133
178
|
${this.getCheckpointsString()}
|
|
@@ -152,27 +197,31 @@ export class AeroflyMissionConditions {
|
|
|
152
197
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
153
198
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
154
199
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
155
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
200
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
201
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
156
202
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
157
203
|
*/
|
|
158
204
|
constructor({ time = new Date(), wind = {
|
|
159
205
|
direction: 0,
|
|
160
206
|
speed: 0,
|
|
161
207
|
gusts: 0,
|
|
162
|
-
}, turbulenceStrength = 0, thermalStrength = 0, visibility =
|
|
208
|
+
}, turbulenceStrength = 0, thermalStrength = 0, visibility = 25000, visibility_sm = null, temperature = null, clouds = [], } = {}) {
|
|
163
209
|
/**
|
|
164
210
|
* @property {AeroflyMissionConditionsCloud[]} clouds for the whole flight
|
|
165
211
|
*/
|
|
166
212
|
this.clouds = [];
|
|
167
|
-
if (visibility_sm) {
|
|
168
|
-
visibility = visibility_sm * meterPerStatuteMile;
|
|
169
|
-
}
|
|
170
213
|
this.time = time;
|
|
171
214
|
this.wind = wind;
|
|
172
215
|
this.turbulenceStrength = turbulenceStrength;
|
|
173
216
|
this.thermalStrength = thermalStrength;
|
|
174
217
|
this.visibility = visibility;
|
|
175
218
|
this.clouds = clouds;
|
|
219
|
+
if (visibility_sm) {
|
|
220
|
+
this.visibility_sm = visibility_sm;
|
|
221
|
+
}
|
|
222
|
+
if (temperature) {
|
|
223
|
+
this.temperature = temperature;
|
|
224
|
+
}
|
|
176
225
|
}
|
|
177
226
|
/**
|
|
178
227
|
* @returns {number} the Aerofly value for UTC hours + minutes/60 + seconds/3600. Ignores milliseconds ;)
|
|
@@ -207,8 +256,14 @@ export class AeroflyMissionConditions {
|
|
|
207
256
|
* @param {number} temperature in °C
|
|
208
257
|
*/
|
|
209
258
|
set temperature(temperature) {
|
|
210
|
-
// Range from
|
|
211
|
-
this.thermalStrength = Math.max(0, (temperature
|
|
259
|
+
// Range from -15°C to 35°C
|
|
260
|
+
this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* @returns {number} in °C
|
|
264
|
+
*/
|
|
265
|
+
get temperature() {
|
|
266
|
+
return Math.sqrt(this.thermalStrength) * 50 - 15;
|
|
212
267
|
}
|
|
213
268
|
/**
|
|
214
269
|
* @returns {string}
|
|
@@ -238,7 +293,7 @@ export class AeroflyMissionConditions {
|
|
|
238
293
|
<[float64][wind_speed][${this.wind.speed}]> // kts
|
|
239
294
|
<[float64][wind_gusts][${this.wind.gusts}]> // kts
|
|
240
295
|
<[float64][turbulence_strength][${this.turbulenceStrength}]>
|
|
241
|
-
<[float64][thermal_strength][${this.thermalStrength}]>
|
|
296
|
+
<[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
|
|
242
297
|
<[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
|
|
243
298
|
${this.getCloudsString()}
|
|
244
299
|
>`;
|
|
@@ -333,20 +388,14 @@ export class AeroflyMissionCheckpoint {
|
|
|
333
388
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
334
389
|
* 84 reference ellipsoid
|
|
335
390
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
336
|
-
* 84 reference ellipsoid
|
|
391
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
337
392
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
338
393
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
339
394
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
340
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
395
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
341
396
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
342
397
|
*/
|
|
343
398
|
constructor(name, type, longitude, latitude, { altitude = 0, altitude_feet = null, direction = null, slope = null, length = null, length_feet = null, frequency = null, } = {}) {
|
|
344
|
-
if (altitude_feet) {
|
|
345
|
-
altitude = altitude_feet / feetPerMeter;
|
|
346
|
-
}
|
|
347
|
-
if (length_feet) {
|
|
348
|
-
length = length_feet / feetPerMeter;
|
|
349
|
-
}
|
|
350
399
|
this.type = type;
|
|
351
400
|
this.name = name;
|
|
352
401
|
this.longitude = longitude;
|
|
@@ -356,6 +405,12 @@ export class AeroflyMissionCheckpoint {
|
|
|
356
405
|
this.slope = slope;
|
|
357
406
|
this.length = length;
|
|
358
407
|
this.frequency = frequency;
|
|
408
|
+
if (altitude_feet) {
|
|
409
|
+
this.altitude_feet = altitude_feet;
|
|
410
|
+
}
|
|
411
|
+
if (length_feet) {
|
|
412
|
+
this.length_feet = length_feet;
|
|
413
|
+
}
|
|
359
414
|
}
|
|
360
415
|
/**
|
|
361
416
|
* @param {number} altitude_feet
|
|
@@ -388,11 +443,11 @@ export class AeroflyMissionCheckpoint {
|
|
|
388
443
|
if (!this.frequency) {
|
|
389
444
|
return "None";
|
|
390
445
|
}
|
|
391
|
-
if (this.frequency >
|
|
392
|
-
return String(this.frequency /
|
|
446
|
+
if (this.frequency > 1000000) {
|
|
447
|
+
return String(this.frequency / 1000000) + " MHz";
|
|
393
448
|
}
|
|
394
|
-
if (this.frequency >
|
|
395
|
-
return String(this.frequency /
|
|
449
|
+
if (this.frequency > 1000) {
|
|
450
|
+
return String(this.frequency / 1000) + " kHz";
|
|
396
451
|
}
|
|
397
452
|
return String(this.frequency) + " Hz";
|
|
398
453
|
}
|
|
@@ -405,18 +460,54 @@ export class AeroflyMissionCheckpoint {
|
|
|
405
460
|
<[string8u][type][${this.type}]>
|
|
406
461
|
<[string8u][name][${this.name}]>
|
|
407
462
|
<[vector2_float64][lon_lat][${this.longitude} ${this.latitude}]>
|
|
408
|
-
<[float64][altitude][${this.altitude}]> // ${this.altitude_feet} ft
|
|
463
|
+
<[float64][altitude][${this.altitude}]> // ${Math.ceil(this.altitude_feet)} ft
|
|
409
464
|
<[float64][direction][${this.direction ?? (index === 0 ? -1 : 0)}]>
|
|
410
465
|
<[float64][slope][${this.slope ?? 0}]>
|
|
411
|
-
<[float64][length][${this.length ?? 0}]> // ${this.length_feet} ft
|
|
466
|
+
<[float64][length][${this.length ?? 0}]> // ${Math.floor(this.length_feet)} ft
|
|
412
467
|
<[float64][frequency][${this.frequency ?? 0}]> // ${this.frequency_string}
|
|
413
468
|
>`;
|
|
414
469
|
}
|
|
415
470
|
}
|
|
471
|
+
export class AeroflyLocalizedText {
|
|
472
|
+
/**
|
|
473
|
+
* @param {string} language like
|
|
474
|
+
* - br
|
|
475
|
+
* - cn
|
|
476
|
+
* - de
|
|
477
|
+
* - es
|
|
478
|
+
* - fr
|
|
479
|
+
* - id
|
|
480
|
+
* - it
|
|
481
|
+
* - jp
|
|
482
|
+
* - kr
|
|
483
|
+
* - pl
|
|
484
|
+
* - sv
|
|
485
|
+
* - tr
|
|
486
|
+
* @param {string} title of this flight plan
|
|
487
|
+
* @param {string} description text, mission briefing, etc
|
|
488
|
+
*/
|
|
489
|
+
constructor(language, title, description) {
|
|
490
|
+
this.language = language;
|
|
491
|
+
this.title = title;
|
|
492
|
+
this.description = description;
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* @param {number} index if used in an array will se the array index
|
|
496
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
497
|
+
*/
|
|
498
|
+
toString(index) {
|
|
499
|
+
return ` <[tmmission_definition_localized][element][${index}]
|
|
500
|
+
<[string8u][language][${this.language}]>
|
|
501
|
+
<[string8][title][${this.title}]>
|
|
502
|
+
<[string8][description][${this.description}]>
|
|
503
|
+
>`;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
416
506
|
export default {
|
|
417
507
|
AeroflyMissionsList,
|
|
418
508
|
AeroflyMission,
|
|
419
509
|
AeroflyMissionConditions,
|
|
420
510
|
AeroflyMissionConditionsCloud,
|
|
421
511
|
AeroflyMissionCheckpoint,
|
|
512
|
+
AeroflyLocalizedText,
|
|
422
513
|
};
|
package/dist/index.test.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, } from "./index.js";
|
|
1
|
+
import { AeroflyMissionsList, AeroflyMission, AeroflyMissionConditions, AeroflyMissionConditionsCloud, AeroflyMissionCheckpoint, AeroflyLocalizedText, } from "./index.js";
|
|
2
2
|
import { strict as assert } from "node:assert";
|
|
3
3
|
{
|
|
4
4
|
const mission = new AeroflyMission("Title");
|
|
@@ -53,7 +53,7 @@ import { strict as assert } from "node:assert";
|
|
|
53
53
|
gusts: 22,
|
|
54
54
|
},
|
|
55
55
|
turbulenceStrength: 1,
|
|
56
|
-
|
|
56
|
+
temperature: 21,
|
|
57
57
|
visibility: 14484.096000000001,
|
|
58
58
|
clouds: [
|
|
59
59
|
AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
|
|
@@ -64,7 +64,7 @@ import { strict as assert } from "node:assert";
|
|
|
64
64
|
assert.strictEqual(conditions.wind.speed, 11);
|
|
65
65
|
assert.strictEqual(conditions.wind.gusts, 22);
|
|
66
66
|
assert.strictEqual(conditions.turbulenceStrength, 1);
|
|
67
|
-
assert.strictEqual(conditions.
|
|
67
|
+
assert.strictEqual(conditions.temperature, 21);
|
|
68
68
|
assert.strictEqual(conditions.visibility, 14484.096000000001);
|
|
69
69
|
const checkpoints = [
|
|
70
70
|
new AeroflyMissionCheckpoint("KCCR", "origin", -122.057, 37.9897, {
|
|
@@ -115,9 +115,7 @@ import { strict as assert } from "node:assert";
|
|
|
115
115
|
assert.strictEqual(missionList.missions.length, 1);
|
|
116
116
|
assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
|
|
117
117
|
assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
|
|
118
|
-
|
|
119
|
-
const missionListString = missionList.toString();
|
|
120
|
-
//console.log(missionListString);
|
|
118
|
+
let missionListString = missionList.toString();
|
|
121
119
|
assert.ok(missionListString.includes("[origin]"));
|
|
122
120
|
assert.ok(missionListString.includes("[tmmission_definition]"));
|
|
123
121
|
assert.ok(missionListString.includes("[list_tmmission_checkpoint]"));
|
|
@@ -130,5 +128,30 @@ import { strict as assert } from "node:assert";
|
|
|
130
128
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
|
|
131
129
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
|
|
132
130
|
assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
|
|
131
|
+
assert.ok(!missionListString.includes("[tags]"));
|
|
132
|
+
assert.ok(!missionListString.includes("[difficulty]"));
|
|
133
|
+
assert.ok(!missionListString.includes("[is_featured]"));
|
|
134
|
+
assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
135
|
+
assert.ok(!missionListString.includes("[distance]"));
|
|
136
|
+
assert.ok(!missionListString.includes("[duration]"));
|
|
137
|
+
//console.log(missionListString);
|
|
138
|
+
mission.difficulty = 1.0;
|
|
139
|
+
mission.isFeatured = true;
|
|
140
|
+
mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
|
|
141
|
+
mission.distance = 1400;
|
|
142
|
+
mission.duration = 2 * 60 * 60;
|
|
143
|
+
mission.tags.push("approach");
|
|
144
|
+
mission.tags.push("pattern");
|
|
145
|
+
missionListString = missionList.toString();
|
|
146
|
+
assert.ok(missionListString.includes("[tags]"));
|
|
147
|
+
assert.ok(missionListString.includes("[difficulty]"));
|
|
148
|
+
assert.ok(missionListString.includes("[is_featured]"));
|
|
149
|
+
assert.ok(missionListString.includes("true"));
|
|
150
|
+
assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
151
|
+
assert.ok(missionListString.includes("Landeübung"));
|
|
152
|
+
assert.ok(missionListString.includes("[distance]"));
|
|
153
|
+
assert.ok(missionListString.includes("[duration]"));
|
|
154
|
+
//console.dir(missionList.missions[0], { depth: null });
|
|
155
|
+
//console.log(missionListString);
|
|
133
156
|
console.log("✅ AeroflyMissionsList test successful");
|
|
134
157
|
}
|
package/package.json
CHANGED
package/src/index.test.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
AeroflyMissionConditions,
|
|
5
5
|
AeroflyMissionConditionsCloud,
|
|
6
6
|
AeroflyMissionCheckpoint,
|
|
7
|
+
AeroflyLocalizedText,
|
|
7
8
|
} from "./index.js";
|
|
8
9
|
import { strict as assert } from "node:assert";
|
|
9
10
|
|
|
@@ -69,7 +70,7 @@ import { strict as assert } from "node:assert";
|
|
|
69
70
|
gusts: 22,
|
|
70
71
|
},
|
|
71
72
|
turbulenceStrength: 1,
|
|
72
|
-
|
|
73
|
+
temperature: 21,
|
|
73
74
|
visibility: 14484.096000000001,
|
|
74
75
|
clouds: [
|
|
75
76
|
AeroflyMissionConditionsCloud.createInFeet(0.1, 5000),
|
|
@@ -81,7 +82,7 @@ import { strict as assert } from "node:assert";
|
|
|
81
82
|
assert.strictEqual(conditions.wind.speed, 11);
|
|
82
83
|
assert.strictEqual(conditions.wind.gusts, 22);
|
|
83
84
|
assert.strictEqual(conditions.turbulenceStrength, 1);
|
|
84
|
-
assert.strictEqual(conditions.
|
|
85
|
+
assert.strictEqual(conditions.temperature, 21);
|
|
85
86
|
assert.strictEqual(conditions.visibility, 14484.096000000001);
|
|
86
87
|
|
|
87
88
|
const checkpoints = [
|
|
@@ -137,11 +138,7 @@ import { strict as assert } from "node:assert";
|
|
|
137
138
|
assert.strictEqual(missionList.missions[0].aircraft.name, "c172");
|
|
138
139
|
assert.strictEqual(missionList.missions[0].aircraft.icao, "C172");
|
|
139
140
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const missionListString = missionList.toString();
|
|
143
|
-
|
|
144
|
-
//console.log(missionListString);
|
|
141
|
+
let missionListString = missionList.toString();
|
|
145
142
|
|
|
146
143
|
assert.ok(missionListString.includes("[origin]"));
|
|
147
144
|
assert.ok(missionListString.includes("[tmmission_definition]"));
|
|
@@ -155,6 +152,35 @@ import { strict as assert } from "node:assert";
|
|
|
155
152
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][2]"));
|
|
156
153
|
assert.ok(missionListString.includes("[tmmission_checkpoint][element][3]"));
|
|
157
154
|
assert.ok(missionListString.includes("<[float64][length][844.2959729825288]>"));
|
|
155
|
+
assert.ok(!missionListString.includes("[tags]"));
|
|
156
|
+
assert.ok(!missionListString.includes("[difficulty]"));
|
|
157
|
+
assert.ok(!missionListString.includes("[is_featured]"));
|
|
158
|
+
assert.ok(!missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
159
|
+
assert.ok(!missionListString.includes("[distance]"));
|
|
160
|
+
assert.ok(!missionListString.includes("[duration]"));
|
|
161
|
+
|
|
162
|
+
//console.log(missionListString);
|
|
163
|
+
|
|
164
|
+
mission.difficulty = 1.0;
|
|
165
|
+
mission.isFeatured = true;
|
|
166
|
+
mission.localizedTexts.push(new AeroflyLocalizedText("de", "Landeübung #1", "Probier die Landung"));
|
|
167
|
+
mission.distance = 1400;
|
|
168
|
+
mission.duration = 2 * 60 * 60;
|
|
169
|
+
mission.tags.push("approach");
|
|
170
|
+
mission.tags.push("pattern");
|
|
171
|
+
missionListString = missionList.toString();
|
|
172
|
+
|
|
173
|
+
assert.ok(missionListString.includes("[tags]"));
|
|
174
|
+
assert.ok(missionListString.includes("[difficulty]"));
|
|
175
|
+
assert.ok(missionListString.includes("[is_featured]"));
|
|
176
|
+
assert.ok(missionListString.includes("true"));
|
|
177
|
+
assert.ok(missionListString.includes("[tmmission_definition_localized]"), "has `tmmission_definition_localized`");
|
|
178
|
+
assert.ok(missionListString.includes("Landeübung"));
|
|
179
|
+
assert.ok(missionListString.includes("[distance]"));
|
|
180
|
+
assert.ok(missionListString.includes("[duration]"));
|
|
181
|
+
|
|
182
|
+
//console.dir(missionList.missions[0], { depth: null });
|
|
183
|
+
//console.log(missionListString);
|
|
158
184
|
|
|
159
185
|
console.log("✅ AeroflyMissionsList test successful");
|
|
160
186
|
}
|
package/src/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type AeroflyMissionPosition = {
|
|
|
25
25
|
/**
|
|
26
26
|
* State of aircraft systems. Configures power settings, flap positions etc
|
|
27
27
|
*/
|
|
28
|
-
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
|
|
28
|
+
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
|
|
@@ -112,6 +112,8 @@ export class AeroflyMissionsList {
|
|
|
112
112
|
* for this file via the `toString()` method.
|
|
113
113
|
*/
|
|
114
114
|
export class AeroflyMission {
|
|
115
|
+
// tutorial_name
|
|
116
|
+
|
|
115
117
|
/**
|
|
116
118
|
* @property {string} title of this flight plan
|
|
117
119
|
*/
|
|
@@ -123,7 +125,27 @@ export class AeroflyMission {
|
|
|
123
125
|
description: string;
|
|
124
126
|
|
|
125
127
|
/**
|
|
126
|
-
* @property {
|
|
128
|
+
* @property {AeroflyLocalizedText[]} localizedTexts for title and description
|
|
129
|
+
*/
|
|
130
|
+
localizedTexts: AeroflyLocalizedText[];
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* @property {string[]} tags
|
|
134
|
+
*/
|
|
135
|
+
tags: string[];
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* @property {boolean} isFeatured makes this mission pop up in "Challenges"
|
|
139
|
+
*/
|
|
140
|
+
isFeatured: boolean;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* @property {number|undefined} difficulty in 0..1, percentage
|
|
144
|
+
*/
|
|
145
|
+
difficulty: number | undefined;
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
|
|
127
149
|
*/
|
|
128
150
|
flightSetting: AeroflyMissionSetting;
|
|
129
151
|
|
|
@@ -147,6 +169,16 @@ export class AeroflyMission {
|
|
|
147
169
|
*/
|
|
148
170
|
destination: AeroflyMissionPosition;
|
|
149
171
|
|
|
172
|
+
/**
|
|
173
|
+
* @property {number} in meters
|
|
174
|
+
*/
|
|
175
|
+
distance: number;
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* @property {number} in seconds
|
|
179
|
+
*/
|
|
180
|
+
duration: number;
|
|
181
|
+
|
|
150
182
|
/**
|
|
151
183
|
* @property {AeroflyMissionConditions} conditions like time and weather for mission
|
|
152
184
|
*/
|
|
@@ -161,11 +193,17 @@ export class AeroflyMission {
|
|
|
161
193
|
* @param {string} title of this flight plan
|
|
162
194
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
163
195
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
164
|
-
* @param {
|
|
196
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
197
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
198
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
199
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
200
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
165
201
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
166
202
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
167
203
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
168
204
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
205
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
206
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
169
207
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
170
208
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
171
209
|
*/
|
|
@@ -173,6 +211,10 @@ export class AeroflyMission {
|
|
|
173
211
|
title: string,
|
|
174
212
|
{
|
|
175
213
|
description = "",
|
|
214
|
+
localizedTexts = [],
|
|
215
|
+
tags = [],
|
|
216
|
+
isFeatured = false,
|
|
217
|
+
difficulty = undefined,
|
|
176
218
|
flightSetting = "taxi",
|
|
177
219
|
aircraft = {
|
|
178
220
|
name: "c172",
|
|
@@ -194,15 +236,23 @@ export class AeroflyMission {
|
|
|
194
236
|
dir: 0,
|
|
195
237
|
alt: 0,
|
|
196
238
|
},
|
|
239
|
+
distance = 0,
|
|
240
|
+
duration = 0,
|
|
197
241
|
conditions = new AeroflyMissionConditions(),
|
|
198
242
|
checkpoints = [],
|
|
199
243
|
}: {
|
|
200
244
|
description?: string;
|
|
245
|
+
localizedTexts?: AeroflyLocalizedText[];
|
|
246
|
+
tags?: string[];
|
|
247
|
+
isFeatured?: boolean;
|
|
248
|
+
difficulty?: number | undefined;
|
|
201
249
|
flightSetting?: AeroflyMissionSetting;
|
|
202
250
|
aircraft?: AeroflyMissionAircraft;
|
|
203
251
|
callsign?: string;
|
|
204
252
|
origin?: AeroflyMissionPosition;
|
|
205
253
|
destination?: AeroflyMissionPosition;
|
|
254
|
+
distance?: number;
|
|
255
|
+
duration?: number;
|
|
206
256
|
conditions?: AeroflyMissionConditions;
|
|
207
257
|
checkpoints?: AeroflyMissionCheckpoint[];
|
|
208
258
|
} = {},
|
|
@@ -210,11 +260,17 @@ export class AeroflyMission {
|
|
|
210
260
|
this.title = title;
|
|
211
261
|
this.checkpoints = checkpoints;
|
|
212
262
|
this.description = description;
|
|
263
|
+
this.localizedTexts = localizedTexts;
|
|
264
|
+
this.tags = tags;
|
|
265
|
+
this.isFeatured = isFeatured;
|
|
266
|
+
this.difficulty = difficulty;
|
|
213
267
|
this.flightSetting = flightSetting;
|
|
214
268
|
this.aircraft = aircraft;
|
|
215
269
|
this.callsign = callsign;
|
|
216
270
|
this.origin = origin;
|
|
217
271
|
this.destination = destination;
|
|
272
|
+
this.distance = distance;
|
|
273
|
+
this.duration = duration;
|
|
218
274
|
this.conditions = conditions;
|
|
219
275
|
}
|
|
220
276
|
|
|
@@ -229,6 +285,17 @@ export class AeroflyMission {
|
|
|
229
285
|
.join("\n");
|
|
230
286
|
}
|
|
231
287
|
|
|
288
|
+
/**
|
|
289
|
+
* @returns {string} indexed checkpoints
|
|
290
|
+
*/
|
|
291
|
+
getLocalizedTextsString(): string {
|
|
292
|
+
return this.localizedTexts
|
|
293
|
+
.map((c: AeroflyLocalizedText, index: number): string => {
|
|
294
|
+
return c.toString(index);
|
|
295
|
+
})
|
|
296
|
+
.join("\n");
|
|
297
|
+
}
|
|
298
|
+
|
|
232
299
|
/**
|
|
233
300
|
* @throws {Error} on missing waypoints
|
|
234
301
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -260,9 +327,39 @@ export class AeroflyMission {
|
|
|
260
327
|
};
|
|
261
328
|
}
|
|
262
329
|
|
|
330
|
+
const optionalProperties = [];
|
|
331
|
+
if (this.localizedTexts.length > 0) {
|
|
332
|
+
optionalProperties.push(` <[list_tmmission_definition_localized][localized_text][]
|
|
333
|
+
${this.getLocalizedTextsString()}
|
|
334
|
+
>`);
|
|
335
|
+
}
|
|
336
|
+
if (this.tags.length > 0) {
|
|
337
|
+
optionalProperties.push(` <[string8u][tags][ ${this.tags.join(" ")} ]>`);
|
|
338
|
+
}
|
|
339
|
+
if (this.difficulty !== undefined) {
|
|
340
|
+
optionalProperties.push(` <[float64] [difficulty] [${this.difficulty}]>`);
|
|
341
|
+
}
|
|
342
|
+
if (this.isFeatured) {
|
|
343
|
+
optionalProperties.push(
|
|
344
|
+
` <[bool] [is_featured] [${this.isFeatured ? "true" : "false"}]>`,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const moreOptionalProperties = [];
|
|
349
|
+
if (this.distance) {
|
|
350
|
+
moreOptionalProperties.push(
|
|
351
|
+
` <[float64] [distance] [${this.distance}]> // ${Math.ceil(this.distance / 1000)} km`,
|
|
352
|
+
);
|
|
353
|
+
}
|
|
354
|
+
if (this.duration) {
|
|
355
|
+
moreOptionalProperties.push(
|
|
356
|
+
` <[float64] [duration] [${this.duration}]> // ${Math.ceil(this.duration / 60)} min`,
|
|
357
|
+
);
|
|
358
|
+
}
|
|
359
|
+
|
|
263
360
|
return ` <[tmmission_definition][mission][]
|
|
264
361
|
<[string8][title][${this.title}]>
|
|
265
|
-
<[string8][description][${this.description}]>
|
|
362
|
+
<[string8][description][${this.description}]>${optionalProperties.length > 0 ? "\n" + optionalProperties.join("\n") : ""}
|
|
266
363
|
<[string8] [flight_setting] [${this.flightSetting}]>
|
|
267
364
|
<[string8u] [aircraft_name] [${this.aircraft.name}]>
|
|
268
365
|
//<[string8u][aircraft_livery] [${this.aircraft.livery}]>
|
|
@@ -270,11 +367,12 @@ export class AeroflyMission {
|
|
|
270
367
|
<[stringt8c] [callsign] [${this.callsign}]>
|
|
271
368
|
<[stringt8c] [origin_icao] [${this.origin.icao}]>
|
|
272
369
|
<[tmvector2d][origin_lon_lat] [${this.origin.longitude} ${this.origin.latitude}]>
|
|
370
|
+
<[float64] [origin_alt] [${this.origin.alt}]> // ${Math.ceil(this.origin.alt * feetPerMeter)} ft MSL
|
|
273
371
|
<[float64] [origin_dir] [${this.origin.dir}]>
|
|
274
|
-
<[float64] [origin_alt] [${this.origin.alt}]> // ${this.origin.alt * feetPerMeter} ft MSL
|
|
275
372
|
<[stringt8c] [destination_icao] [${this.destination.icao}]>
|
|
276
373
|
<[tmvector2d][destination_lon_lat][${this.destination.longitude} ${this.destination.latitude}]>
|
|
277
|
-
<[float64] [
|
|
374
|
+
<[float64] [destination_alt] [${this.destination.alt}]> // ${Math.ceil(this.destination.alt * feetPerMeter)} ft MSL
|
|
375
|
+
<[float64] [destination_dir] [${this.destination.dir}]>${moreOptionalProperties.length > 0 ? "\n" + moreOptionalProperties.join("\n") : ""}
|
|
278
376
|
${this.conditions}
|
|
279
377
|
<[list_tmmission_checkpoint][checkpoints][]
|
|
280
378
|
${this.getCheckpointsString()}
|
|
@@ -331,7 +429,8 @@ export class AeroflyMissionConditions {
|
|
|
331
429
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
332
430
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
333
431
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
334
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
432
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
433
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
335
434
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
336
435
|
*/
|
|
337
436
|
constructor({
|
|
@@ -345,6 +444,7 @@ export class AeroflyMissionConditions {
|
|
|
345
444
|
thermalStrength = 0,
|
|
346
445
|
visibility = 25_000,
|
|
347
446
|
visibility_sm = null,
|
|
447
|
+
temperature = null,
|
|
348
448
|
clouds = [],
|
|
349
449
|
}: {
|
|
350
450
|
time?: Date;
|
|
@@ -357,17 +457,22 @@ export class AeroflyMissionConditions {
|
|
|
357
457
|
thermalStrength?: number;
|
|
358
458
|
visibility?: number;
|
|
359
459
|
visibility_sm?: number | null;
|
|
460
|
+
temperature?: number | null;
|
|
360
461
|
clouds?: AeroflyMissionConditionsCloud[];
|
|
361
462
|
} = {}) {
|
|
362
|
-
if (visibility_sm) {
|
|
363
|
-
visibility = visibility_sm * meterPerStatuteMile;
|
|
364
|
-
}
|
|
365
463
|
this.time = time;
|
|
366
464
|
this.wind = wind;
|
|
367
465
|
this.turbulenceStrength = turbulenceStrength;
|
|
368
466
|
this.thermalStrength = thermalStrength;
|
|
369
467
|
this.visibility = visibility;
|
|
370
468
|
this.clouds = clouds;
|
|
469
|
+
|
|
470
|
+
if (visibility_sm) {
|
|
471
|
+
this.visibility_sm = visibility_sm;
|
|
472
|
+
}
|
|
473
|
+
if (temperature) {
|
|
474
|
+
this.temperature = temperature;
|
|
475
|
+
}
|
|
371
476
|
}
|
|
372
477
|
|
|
373
478
|
/**
|
|
@@ -407,8 +512,15 @@ export class AeroflyMissionConditions {
|
|
|
407
512
|
* @param {number} temperature in °C
|
|
408
513
|
*/
|
|
409
514
|
set temperature(temperature: number) {
|
|
410
|
-
// Range from
|
|
411
|
-
this.thermalStrength = Math.max(0, (temperature
|
|
515
|
+
// Range from -15°C to 35°C
|
|
516
|
+
this.thermalStrength = Math.max(0, (temperature + 15) / 50) ** 2;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* @returns {number} in °C
|
|
521
|
+
*/
|
|
522
|
+
get temperature(): number {
|
|
523
|
+
return Math.sqrt(this.thermalStrength) * 50 - 15;
|
|
412
524
|
}
|
|
413
525
|
|
|
414
526
|
/**
|
|
@@ -441,7 +553,7 @@ export class AeroflyMissionConditions {
|
|
|
441
553
|
<[float64][wind_speed][${this.wind.speed}]> // kts
|
|
442
554
|
<[float64][wind_gusts][${this.wind.gusts}]> // kts
|
|
443
555
|
<[float64][turbulence_strength][${this.turbulenceStrength}]>
|
|
444
|
-
<[float64][thermal_strength][${this.thermalStrength}]>
|
|
556
|
+
<[float64][thermal_strength][${this.thermalStrength}]> // ${this.temperature} °C
|
|
445
557
|
<[float64][visibility][${this.visibility}]> // ${this.visibility_sm} SM
|
|
446
558
|
${this.getCloudsString()}
|
|
447
559
|
>`;
|
|
@@ -602,11 +714,11 @@ export class AeroflyMissionCheckpoint {
|
|
|
602
714
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
603
715
|
* 84 reference ellipsoid
|
|
604
716
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
605
|
-
* 84 reference ellipsoid
|
|
717
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
606
718
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
607
719
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
608
720
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
609
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
721
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
610
722
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
611
723
|
*/
|
|
612
724
|
constructor(
|
|
@@ -632,13 +744,6 @@ export class AeroflyMissionCheckpoint {
|
|
|
632
744
|
frequency?: number | null;
|
|
633
745
|
} = {},
|
|
634
746
|
) {
|
|
635
|
-
if (altitude_feet) {
|
|
636
|
-
altitude = altitude_feet / feetPerMeter;
|
|
637
|
-
}
|
|
638
|
-
if (length_feet) {
|
|
639
|
-
length = length_feet / feetPerMeter;
|
|
640
|
-
}
|
|
641
|
-
|
|
642
747
|
this.type = type;
|
|
643
748
|
this.name = name;
|
|
644
749
|
this.longitude = longitude;
|
|
@@ -648,6 +753,13 @@ export class AeroflyMissionCheckpoint {
|
|
|
648
753
|
this.slope = slope;
|
|
649
754
|
this.length = length;
|
|
650
755
|
this.frequency = frequency;
|
|
756
|
+
|
|
757
|
+
if (altitude_feet) {
|
|
758
|
+
this.altitude_feet = altitude_feet;
|
|
759
|
+
}
|
|
760
|
+
if (length_feet) {
|
|
761
|
+
this.length_feet = length_feet;
|
|
762
|
+
}
|
|
651
763
|
}
|
|
652
764
|
|
|
653
765
|
/**
|
|
@@ -704,19 +816,84 @@ export class AeroflyMissionCheckpoint {
|
|
|
704
816
|
<[string8u][type][${this.type}]>
|
|
705
817
|
<[string8u][name][${this.name}]>
|
|
706
818
|
<[vector2_float64][lon_lat][${this.longitude} ${this.latitude}]>
|
|
707
|
-
<[float64][altitude][${this.altitude}]> // ${this.altitude_feet} ft
|
|
819
|
+
<[float64][altitude][${this.altitude}]> // ${Math.ceil(this.altitude_feet)} ft
|
|
708
820
|
<[float64][direction][${this.direction ?? (index === 0 ? -1 : 0)}]>
|
|
709
821
|
<[float64][slope][${this.slope ?? 0}]>
|
|
710
|
-
<[float64][length][${this.length ?? 0}]> // ${this.length_feet} ft
|
|
822
|
+
<[float64][length][${this.length ?? 0}]> // ${Math.floor(this.length_feet)} ft
|
|
711
823
|
<[float64][frequency][${this.frequency ?? 0}]> // ${this.frequency_string}
|
|
712
824
|
>`;
|
|
713
825
|
}
|
|
714
826
|
}
|
|
715
827
|
|
|
828
|
+
export class AeroflyLocalizedText {
|
|
829
|
+
/**
|
|
830
|
+
* @property {string} language like
|
|
831
|
+
* - br
|
|
832
|
+
* - cn
|
|
833
|
+
* - de
|
|
834
|
+
* - es
|
|
835
|
+
* - fr
|
|
836
|
+
* - id
|
|
837
|
+
* - it
|
|
838
|
+
* - jp
|
|
839
|
+
* - kr
|
|
840
|
+
* - pl
|
|
841
|
+
* - sv
|
|
842
|
+
* - tr
|
|
843
|
+
*/
|
|
844
|
+
language: string;
|
|
845
|
+
|
|
846
|
+
/**
|
|
847
|
+
* @property {string} title of this flight plan
|
|
848
|
+
*/
|
|
849
|
+
title: string;
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* @property {string} description text, mission briefing, etc
|
|
853
|
+
*/
|
|
854
|
+
description: string;
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* @param {string} language like
|
|
858
|
+
* - br
|
|
859
|
+
* - cn
|
|
860
|
+
* - de
|
|
861
|
+
* - es
|
|
862
|
+
* - fr
|
|
863
|
+
* - id
|
|
864
|
+
* - it
|
|
865
|
+
* - jp
|
|
866
|
+
* - kr
|
|
867
|
+
* - pl
|
|
868
|
+
* - sv
|
|
869
|
+
* - tr
|
|
870
|
+
* @param {string} title of this flight plan
|
|
871
|
+
* @param {string} description text, mission briefing, etc
|
|
872
|
+
*/
|
|
873
|
+
constructor(language: string, title: string, description: string) {
|
|
874
|
+
this.language = language;
|
|
875
|
+
this.title = title;
|
|
876
|
+
this.description = description;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* @param {number} index if used in an array will se the array index
|
|
881
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
882
|
+
*/
|
|
883
|
+
toString(index: number): string {
|
|
884
|
+
return ` <[tmmission_definition_localized][element][${index}]
|
|
885
|
+
<[string8u][language][${this.language}]>
|
|
886
|
+
<[string8][title][${this.title}]>
|
|
887
|
+
<[string8][description][${this.description}]>
|
|
888
|
+
>`;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
|
|
716
892
|
export default {
|
|
717
893
|
AeroflyMissionsList,
|
|
718
894
|
AeroflyMission,
|
|
719
895
|
AeroflyMissionConditions,
|
|
720
896
|
AeroflyMissionConditionsCloud,
|
|
721
897
|
AeroflyMissionCheckpoint,
|
|
898
|
+
AeroflyLocalizedText,
|
|
722
899
|
};
|
package/types/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type AeroflyMissionPosition = {
|
|
|
21
21
|
/**
|
|
22
22
|
* State of aircraft systems. Configures power settings, flap positions etc
|
|
23
23
|
*/
|
|
24
|
-
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing";
|
|
24
|
+
export type AeroflyMissionSetting = "taxi" | "takeoff" | "cruise" | "approach" | "landing" | "winch_launch" | "aerotow";
|
|
25
25
|
/**
|
|
26
26
|
* Types of checkpoints. Required are usually "origin", "departure_runway" at the start and "destination_runway", "destination" at the end.
|
|
27
27
|
*/
|
|
@@ -100,7 +100,23 @@ export declare class AeroflyMission {
|
|
|
100
100
|
*/
|
|
101
101
|
description: string;
|
|
102
102
|
/**
|
|
103
|
-
* @property {
|
|
103
|
+
* @property {AeroflyLocalizedText[]} localizedTexts for title and description
|
|
104
|
+
*/
|
|
105
|
+
localizedTexts: AeroflyLocalizedText[];
|
|
106
|
+
/**
|
|
107
|
+
* @property {string[]} tags
|
|
108
|
+
*/
|
|
109
|
+
tags: string[];
|
|
110
|
+
/**
|
|
111
|
+
* @property {boolean} isFeatured makes this mission pop up in "Challenges"
|
|
112
|
+
*/
|
|
113
|
+
isFeatured: boolean;
|
|
114
|
+
/**
|
|
115
|
+
* @property {number|undefined} difficulty in 0..1, percentage
|
|
116
|
+
*/
|
|
117
|
+
difficulty: number | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* @property {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} flightSetting of aircraft, like "taxi", "cruise"
|
|
104
120
|
*/
|
|
105
121
|
flightSetting: AeroflyMissionSetting;
|
|
106
122
|
/**
|
|
@@ -119,6 +135,14 @@ export declare class AeroflyMission {
|
|
|
119
135
|
* @property {object} destination position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
120
136
|
*/
|
|
121
137
|
destination: AeroflyMissionPosition;
|
|
138
|
+
/**
|
|
139
|
+
* @property {number} in meters
|
|
140
|
+
*/
|
|
141
|
+
distance: number;
|
|
142
|
+
/**
|
|
143
|
+
* @property {number} in seconds
|
|
144
|
+
*/
|
|
145
|
+
duration: number;
|
|
122
146
|
/**
|
|
123
147
|
* @property {AeroflyMissionConditions} conditions like time and weather for mission
|
|
124
148
|
*/
|
|
@@ -131,11 +155,17 @@ export declare class AeroflyMission {
|
|
|
131
155
|
* @param {string} title of this flight plan
|
|
132
156
|
* @param {object} [additionalAttributes] allows to set additional attributes on creation
|
|
133
157
|
* @param {string} [additionalAttributes.description] text, mission briefing, etc
|
|
134
|
-
* @param {
|
|
158
|
+
* @param {AeroflyLocalizedText[]} [additionalAttributes.localizedTexts] translations for title and description
|
|
159
|
+
* @param {string[]} [additionalAttributes.tags]
|
|
160
|
+
* @param {boolean} [additionalAttributes.isFeatured] makes this mission pop up in "Challenges"
|
|
161
|
+
* @param {number|undefined} [additionalAttributes.difficulty] 0..1, percentage
|
|
162
|
+
* @param {"taxi"|"takeoff"|"cruise"|"approach"|"landing"|"winch_launch"|"aerotow"} [additionalAttributes.flightSetting] of aircraft, like "taxi", "cruise"
|
|
135
163
|
* @param {{name:string,livery:string,icao:string}} [additionalAttributes.aircraft] for this mission
|
|
136
164
|
* @param {string} [additionalAttributes.callsign] of aircraft, uppercased
|
|
137
165
|
* @param {object} [additionalAttributes.origin] position of aircraft, as well as name of starting airport. Position does not have match airport.
|
|
138
166
|
* @param {object} [additionalAttributes.destination] position of aircraft, as well as name of destination airport. Position does not have match airport.
|
|
167
|
+
* @param {number} [additionalAttributes.distance] in meters
|
|
168
|
+
* @param {number} [additionalAttributes.duration] in seconds
|
|
139
169
|
* @param {AeroflyMissionConditions} [additionalAttributes.conditions] like time and weather for mission
|
|
140
170
|
* @param {AeroflyMissionCheckpoint[]} [additionalAttributes.checkpoints] form the actual flight plan
|
|
141
171
|
*/
|
|
@@ -143,20 +173,32 @@ export declare class AeroflyMission {
|
|
|
143
173
|
title: string,
|
|
144
174
|
{
|
|
145
175
|
description,
|
|
176
|
+
localizedTexts,
|
|
177
|
+
tags,
|
|
178
|
+
isFeatured,
|
|
179
|
+
difficulty,
|
|
146
180
|
flightSetting,
|
|
147
181
|
aircraft,
|
|
148
182
|
callsign,
|
|
149
183
|
origin,
|
|
150
184
|
destination,
|
|
185
|
+
distance,
|
|
186
|
+
duration,
|
|
151
187
|
conditions,
|
|
152
188
|
checkpoints,
|
|
153
189
|
}?: {
|
|
154
190
|
description?: string;
|
|
191
|
+
localizedTexts?: AeroflyLocalizedText[];
|
|
192
|
+
tags?: string[];
|
|
193
|
+
isFeatured?: boolean;
|
|
194
|
+
difficulty?: number | undefined;
|
|
155
195
|
flightSetting?: AeroflyMissionSetting;
|
|
156
196
|
aircraft?: AeroflyMissionAircraft;
|
|
157
197
|
callsign?: string;
|
|
158
198
|
origin?: AeroflyMissionPosition;
|
|
159
199
|
destination?: AeroflyMissionPosition;
|
|
200
|
+
distance?: number;
|
|
201
|
+
duration?: number;
|
|
160
202
|
conditions?: AeroflyMissionConditions;
|
|
161
203
|
checkpoints?: AeroflyMissionCheckpoint[];
|
|
162
204
|
},
|
|
@@ -165,6 +207,10 @@ export declare class AeroflyMission {
|
|
|
165
207
|
* @returns {string} indexed checkpoints
|
|
166
208
|
*/
|
|
167
209
|
getCheckpointsString(): string;
|
|
210
|
+
/**
|
|
211
|
+
* @returns {string} indexed checkpoints
|
|
212
|
+
*/
|
|
213
|
+
getLocalizedTextsString(): string;
|
|
168
214
|
/**
|
|
169
215
|
* @throws {Error} on missing waypoints
|
|
170
216
|
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
@@ -213,7 +259,8 @@ export declare class AeroflyMissionConditions {
|
|
|
213
259
|
* @param {number} [additionalAttributes.turbulenceStrength] 0..1, percentage
|
|
214
260
|
* @param {number} [additionalAttributes.thermalStrength] 0..1, percentage
|
|
215
261
|
* @param {number} [additionalAttributes.visibility] in meters
|
|
216
|
-
* @param {number?} [additionalAttributes.visibility_sm] in statute miles
|
|
262
|
+
* @param {number?} [additionalAttributes.visibility_sm] in statute miles, will overwrite visibility
|
|
263
|
+
* @param {number?} [additionalAttributes.temperature] in °C, will overwrite thermalStrength
|
|
217
264
|
* @param {AeroflyMissionConditionsCloud[]} [additionalAttributes.clouds] for the whole flight
|
|
218
265
|
*/
|
|
219
266
|
constructor({
|
|
@@ -223,6 +270,7 @@ export declare class AeroflyMissionConditions {
|
|
|
223
270
|
thermalStrength,
|
|
224
271
|
visibility,
|
|
225
272
|
visibility_sm,
|
|
273
|
+
temperature,
|
|
226
274
|
clouds,
|
|
227
275
|
}?: {
|
|
228
276
|
time?: Date;
|
|
@@ -235,6 +283,7 @@ export declare class AeroflyMissionConditions {
|
|
|
235
283
|
thermalStrength?: number;
|
|
236
284
|
visibility?: number;
|
|
237
285
|
visibility_sm?: number | null;
|
|
286
|
+
temperature?: number | null;
|
|
238
287
|
clouds?: AeroflyMissionConditionsCloud[];
|
|
239
288
|
});
|
|
240
289
|
/**
|
|
@@ -258,6 +307,10 @@ export declare class AeroflyMissionConditions {
|
|
|
258
307
|
* @param {number} temperature in °C
|
|
259
308
|
*/
|
|
260
309
|
set temperature(temperature: number);
|
|
310
|
+
/**
|
|
311
|
+
* @returns {number} in °C
|
|
312
|
+
*/
|
|
313
|
+
get temperature(): number;
|
|
261
314
|
/**
|
|
262
315
|
* @returns {string}
|
|
263
316
|
*/
|
|
@@ -378,11 +431,11 @@ export declare class AeroflyMissionCheckpoint {
|
|
|
378
431
|
* @param {number} [additionalAttributes.altitude] The height in meters above or below the WGS
|
|
379
432
|
* 84 reference ellipsoid
|
|
380
433
|
* @param {number?} [additionalAttributes.altitude_feet] The height in feet above or below the WGS
|
|
381
|
-
* 84 reference ellipsoid
|
|
434
|
+
* 84 reference ellipsoid. Will overwrite altitude
|
|
382
435
|
* @param {number} [additionalAttributes.direction] of runway, in degree
|
|
383
436
|
* @param {number?} [additionalAttributes.slope] of runway
|
|
384
437
|
* @param {number?} [additionalAttributes.length] of runway, in meters
|
|
385
|
-
* @param {number?} [additionalAttributes.length_feet] of runway, in feet
|
|
438
|
+
* @param {number?} [additionalAttributes.length_feet] of runway, in feet. Will overwrite length
|
|
386
439
|
* @param {number?} [additionalAttributes.frequency] of runways or navigational aids, in Hz; multiply by 1000 for kHz, 1_000_000 for MHz
|
|
387
440
|
*/
|
|
388
441
|
constructor(
|
|
@@ -434,12 +487,62 @@ export declare class AeroflyMissionCheckpoint {
|
|
|
434
487
|
*/
|
|
435
488
|
toString(index?: number): string;
|
|
436
489
|
}
|
|
490
|
+
export declare class AeroflyLocalizedText {
|
|
491
|
+
/**
|
|
492
|
+
* @property {string} language like
|
|
493
|
+
* - br
|
|
494
|
+
* - cn
|
|
495
|
+
* - de
|
|
496
|
+
* - es
|
|
497
|
+
* - fr
|
|
498
|
+
* - id
|
|
499
|
+
* - it
|
|
500
|
+
* - jp
|
|
501
|
+
* - kr
|
|
502
|
+
* - pl
|
|
503
|
+
* - sv
|
|
504
|
+
* - tr
|
|
505
|
+
*/
|
|
506
|
+
language: string;
|
|
507
|
+
/**
|
|
508
|
+
* @property {string} title of this flight plan
|
|
509
|
+
*/
|
|
510
|
+
title: string;
|
|
511
|
+
/**
|
|
512
|
+
* @property {string} description text, mission briefing, etc
|
|
513
|
+
*/
|
|
514
|
+
description: string;
|
|
515
|
+
/**
|
|
516
|
+
* @param {string} language like
|
|
517
|
+
* - br
|
|
518
|
+
* - cn
|
|
519
|
+
* - de
|
|
520
|
+
* - es
|
|
521
|
+
* - fr
|
|
522
|
+
* - id
|
|
523
|
+
* - it
|
|
524
|
+
* - jp
|
|
525
|
+
* - kr
|
|
526
|
+
* - pl
|
|
527
|
+
* - sv
|
|
528
|
+
* - tr
|
|
529
|
+
* @param {string} title of this flight plan
|
|
530
|
+
* @param {string} description text, mission briefing, etc
|
|
531
|
+
*/
|
|
532
|
+
constructor(language: string, title: string, description: string);
|
|
533
|
+
/**
|
|
534
|
+
* @param {number} index if used in an array will se the array index
|
|
535
|
+
* @returns {string} to use in Aerofly FS4's `custom_missions_user.tmc`
|
|
536
|
+
*/
|
|
537
|
+
toString(index: number): string;
|
|
538
|
+
}
|
|
437
539
|
declare const _default: {
|
|
438
540
|
AeroflyMissionsList: typeof AeroflyMissionsList;
|
|
439
541
|
AeroflyMission: typeof AeroflyMission;
|
|
440
542
|
AeroflyMissionConditions: typeof AeroflyMissionConditions;
|
|
441
543
|
AeroflyMissionConditionsCloud: typeof AeroflyMissionConditionsCloud;
|
|
442
544
|
AeroflyMissionCheckpoint: typeof AeroflyMissionCheckpoint;
|
|
545
|
+
AeroflyLocalizedText: typeof AeroflyLocalizedText;
|
|
443
546
|
};
|
|
444
547
|
export default _default;
|
|
445
548
|
//# sourceMappingURL=index.d.ts.map
|
package/types/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAAC;AAExH;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAClC,QAAQ,GACR,kBAAkB,GAClB,WAAW,GACX,UAAU,GACV,SAAS,GACT,UAAU,GACV,oBAAoB,GACpB,aAAa,CAAC;AAEpB;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,sCAAsC,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE3F;;;;;;;GAOG;AACH,qBAAa,mBAAmB;IAC5B;;OAEG;IACH,QAAQ,EAAE,cAAc,EAAE,CAAC;IAE3B;;OAEG;gBACS,QAAQ,GAAE,cAAc,EAAO;IAI3C;;OAEG;IACH,QAAQ,IAAI,MAAM;CAQrB;AAED;;;;;;;GAOG;AACH,qBAAa,cAAc;IAGvB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,oBAAoB,EAAE,CAAC;IAEvC;;OAEG;IACH,IAAI,EAAE,MAAM,EAAE,CAAC;IAEf;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/B;;OAEG;IACH,aAAa,EAAE,qBAAqB,CAAC;IAErC;;OAEG;IACH,QAAQ,EAAE,sBAAsB,CAAC;IAEjC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,MAAM,EAAE,sBAAsB,CAAC;IAE/B;;OAEG;IACH,WAAW,EAAE,sBAAsB,CAAC;IAEpC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,UAAU,EAAE,wBAAwB,CAAC;IAErC;;OAEG;IACH,WAAW,EAAE,wBAAwB,EAAE,CAAC;IAExC;;;;;;;;;;;;;;;;;OAiBG;gBAEC,KAAK,EAAE,MAAM,EACb,EACI,WAAgB,EAChB,cAAmB,EACnB,IAAS,EACT,UAAkB,EAClB,UAAsB,EACtB,aAAsB,EACtB,QAIC,EACD,QAAa,EACb,MAMC,EACD,WAMC,EACD,QAAY,EACZ,QAAY,EACZ,UAA2C,EAC3C,WAAgB,GACnB,GAAE;QACC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,CAAC,EAAE,oBAAoB,EAAE,CAAC;QACxC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAChC,aAAa,CAAC,EAAE,qBAAqB,CAAC;QACtC,QAAQ,CAAC,EAAE,sBAAsB,CAAC;QAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,MAAM,CAAC,EAAE,sBAAsB,CAAC;QAChC,WAAW,CAAC,EAAE,sBAAsB,CAAC;QACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,wBAAwB,CAAC;QACtC,WAAW,CAAC,EAAE,wBAAwB,EAAE,CAAC;KACvC;IAmBV;;OAEG;IACH,oBAAoB,IAAI,MAAM;IAQ9B;;OAEG;IACH,uBAAuB,IAAI,MAAM;IAQjC;;;OAGG;IACH,QAAQ,IAAI,MAAM;CA6ErB;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAwB;IACjC;;;OAGG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;IAEnC;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,MAAM,EAAE,6BAA6B,EAAE,CAAM;IAE7C;;;;;;;;;;;OAWG;gBACS,EACR,IAAiB,EACjB,IAIC,EACD,kBAAsB,EACtB,eAAmB,EACnB,UAAmB,EACnB,aAAoB,EACpB,WAAkB,EAClB,MAAW,GACd,GAAE;QACC,IAAI,CAAC,EAAE,IAAI,CAAC;QACZ,IAAI,CAAC,EAAE;YACH,SAAS,EAAE,MAAM,CAAC;YAClB,KAAK,EAAE,MAAM,CAAC;YACd,KAAK,EAAE,MAAM,CAAC;SACjB,CAAC;QACF,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,MAAM,CAAC,EAAE,6BAA6B,EAAE,CAAC;KACvC;IAgBN;;OAEG;IACH,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED;;OAEG;IACH,IAAI,mBAAmB,IAAI,MAAM,CAMhC;IAED;;OAEG;IACH,IAAI,aAAa,CAAC,aAAa,EAAE,MAAM,EAEtC;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;;OAGG;IACH,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,EAGlC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,eAAe,IAAI,MAAM;IAQzB;;OAEG;IACH,QAAQ,IAAI,MAAM;CAqBrB;AAED;;;;;;;GAOG;AACH,qBAAa,6BAA6B;IACtC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;gBACS,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKvC;;;;OAIG;IACH,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,6BAA6B;IAIpF;;OAEG;IACH,IAAI,SAAS,CAAC,SAAS,EAAE,MAAM,EAE9B;IAED;;OAEG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;OAEG;IACH,IAAI,UAAU,IAAI,sCAAsC,CAWvD;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM;CAOtC;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAwB;IACjC;;OAEG;IACH,IAAI,EAAE,4BAA4B,CAAC;IAEnC;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;OAEG;IACH,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAEtB;;OAEG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAEzB;;;;;;;;;;;;;;;;;;;;OAoBG;gBAEC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,4BAA4B,EAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,EACI,QAAY,EACZ,aAAoB,EACpB,SAAgB,EAChB,KAAY,EACZ,MAAa,EACb,WAAkB,EAClB,SAAgB,GACnB,GAAE;QACC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACxB;IAoBV;;OAEG;IACH,IAAI,aAAa,CAAC,aAAa,EAAE,MAAM,EAEtC;IAED;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,IAAI,WAAW,CAAC,WAAW,EAAE,MAAM,EAElC;IAED;;OAEG;IACH,IAAI,WAAW,IAAI,MAAM,CAExB;IAED;;OAEG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAY7B;IAED;;;OAGG;IACH,QAAQ,CAAC,KAAK,GAAE,MAAU,GAAG,MAAM;CAYtC;AAED,qBAAa,oBAAoB;IAC7B;;;;;;;;;;;;;;OAcG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;;;OAgBG;gBACS,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM;IAMhE;;;OAGG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;CAOlC;;;;;;;;;AAED,wBAOE"}
|