initial commit
This commit is contained in:
commit
0297cfb600
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
Packages
|
||||
_PackageInt
|
||||
PackageSources/js-bundle/__generated__
|
||||
PackageSources/js-bundle/.rollup.cache
|
||||
PackageSources/js-bundle/node_modules
|
||||
PackageSources/html_ui
|
||||
|
||||
*.blend1
|
||||
22
.vscode/settings.json
vendored
Normal file
22
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"[javascript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[typescript]": {
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"yarn.lock": true,
|
||||
"package.json": true,
|
||||
"tsconfig.json": true,
|
||||
".*": true
|
||||
},
|
||||
"[xml]": {
|
||||
"editor.defaultFormatter": "redhat.vscode-xml"
|
||||
}
|
||||
}
|
||||
BIN
MD11_Profile/MD-11 Side Profile.png
Normal file
BIN
MD11_Profile/MD-11 Side Profile.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 475 KiB |
BIN
MD11_Profile/MD-11 Side Profile.xcf
Normal file
BIN
MD11_Profile/MD-11 Side Profile.xcf
Normal file
Binary file not shown.
BIN
MD11_Profile/MD-11 schematics.blend
Normal file
BIN
MD11_Profile/MD-11 schematics.blend
Normal file
Binary file not shown.
19
MD11_Profile/MD11 Profile SVG positions.txt
Normal file
19
MD11_Profile/MD11 Profile SVG positions.txt
Normal file
@ -0,0 +1,19 @@
|
||||
Mains y: 457,626
|
||||
Mains X:
|
||||
|
||||
344,088 + (1126,566 - 344,088) / 2
|
||||
|
||||
1126,566 + (1910,904 - 1126,566) / 2
|
||||
|
||||
1910,904 + (2693,220 - 1910,904) / 2
|
||||
|
||||
2693,220 + (3477,993 - 2693,220) / 2
|
||||
|
||||
|
||||
|
||||
Lower y: 623,816
|
||||
Lower Y:
|
||||
|
||||
679,888 + (1734,862 - 679,888) / 2
|
||||
|
||||
2392,429 + (3409,288 - 2392,429) / 2
|
||||
196
MD11_Profile/MD11_Profile.svg
Normal file
196
MD11_Profile/MD11_Profile.svg
Normal file
@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="4002"
|
||||
height="780"
|
||||
viewBox="0 0 4002 780"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
sodipodi:docname="MD11_Profile.svg"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96"
|
||||
inkscape:version="1.3.2 (091e20e, 2023-11-25, custom)"
|
||||
inkscape:export-filename="MD11_Profile_EXP.svg"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||
id="namedview2"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.5"
|
||||
inkscape:cx="3634"
|
||||
inkscape:cy="345"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1009"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="layer7"
|
||||
inkscape:export-bgcolor="#ffffff00" /><defs
|
||||
id="defs1" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer6"
|
||||
inkscape:label="Static"><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-17.1875"
|
||||
y="280.10175"
|
||||
id="text1-3"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1-9"
|
||||
x="-17.1875"
|
||||
y="280.10175">Pilots & Crew:</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-9.8828125"
|
||||
y="130.625"
|
||||
id="text1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan1"
|
||||
x="-9.8828125"
|
||||
y="130.625">OEW:</tspan></text></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer7"
|
||||
inkscape:label="Generics"><text
|
||||
xml:space="preserve"
|
||||
style="font-size:176px;line-height:1.25;font-family:sans-serif"
|
||||
x="1476.2501"
|
||||
y="276.92206"
|
||||
id="text2"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan2"
|
||||
x="1476.2501"
|
||||
y="276.92206">9999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-size:176px;line-height:1.25;font-family:sans-serif"
|
||||
x="1252.4691"
|
||||
y="130.53906"
|
||||
id="text3"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3"
|
||||
x="1252.4691"
|
||||
y="130.53906">999999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-size:133.333px;line-height:1.25;font-family:sans-serif;stroke-width:0.999998"
|
||||
x="3752.9043"
|
||||
y="778.24402"
|
||||
id="text4"><tspan
|
||||
sodipodi:role="line"
|
||||
x="3752.9043"
|
||||
y="778.24402"
|
||||
style="font-size:133.333px;stroke-width:0.999998"
|
||||
id="tspan6">LBS</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-size:176px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif"
|
||||
x="3518"
|
||||
y="320"
|
||||
id="text7"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan7"
|
||||
x="3518"
|
||||
y="320">ER</tspan></text></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer2"
|
||||
inkscape:label="Stations"><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;-inkscape-font-specification:'sans-serif, Normal';font-stretch:normal;font-variant:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal"
|
||||
x="725.61609"
|
||||
y="591.34473"
|
||||
id="text5"
|
||||
inkscape:label="upper1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5"
|
||||
x="725.61609"
|
||||
y="591.34473">999/999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:176px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="-179.32031"
|
||||
y="143.71875"
|
||||
id="text5-8"
|
||||
inkscape:label="upper1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-3"
|
||||
x="-179.32031"
|
||||
y="143.71875"
|
||||
style="text-align:start;text-anchor:start" /></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="1509.024"
|
||||
y="591.34473"
|
||||
id="text5-5"
|
||||
inkscape:label="upper1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-8"
|
||||
x="1509.024"
|
||||
y="591.34473">999/999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="2292.3511"
|
||||
y="591.34473"
|
||||
id="text5-6"
|
||||
inkscape:label="upper1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-7"
|
||||
x="2292.3511"
|
||||
y="591.34473">999/999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="3075.8955"
|
||||
y="591.34473"
|
||||
id="upper4"
|
||||
inkscape:label="upper4"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-0"
|
||||
x="3075.8955"
|
||||
y="591.34473">999/999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="1197.6641"
|
||||
y="754.35504"
|
||||
id="upper4-2"
|
||||
inkscape:label="lower1"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-0-0"
|
||||
x="1197.6641"
|
||||
y="754.35504">99999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:176px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none"
|
||||
x="2891.1475"
|
||||
y="754.35504"
|
||||
id="lower1"
|
||||
inkscape:label="upper4"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan5-0-03"
|
||||
x="2891.1475"
|
||||
y="754.35504">99999</tspan></text></g><g
|
||||
inkscape:groupmode="layer"
|
||||
id="layer3"
|
||||
inkscape:label="Sketch"><path
|
||||
id="path5"
|
||||
style="display:inline;fill:none;stroke:#646464;stroke-width:3.97267;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 1748.2487,624.45529 v 83.5816 z m 653.1368,98.40409 v 43.08593 z"
|
||||
transform="matrix(1.0068517,0,0,1.0069072,-24.265193,-12.003831)"
|
||||
inkscape:label="Dashed"
|
||||
sodipodi:nodetypes="cccccc" /><path
|
||||
id="path10"
|
||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:3.97527;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 119.50997,573.71703 h 128.0729 v 29.07865 h 119.1481 M 1922.9882,624.6584 V 378.08519 Z M 1143.9838,378.54476 v 246.57126 z m 1556.0004,1.0854 3e-4,245.70686 0.01,-245.70686 z M 119.47872,507.3493 V 686.42638 Z M 681.8277,784.08016 C 550.68986,778.56008 459.37243,767.83734 325.24777,742.2102 247.12441,727.28325 163.85922,704.53832 115.68874,684.96689 65.272866,664.48337 30.640554,635.98924 26.748642,611.79065 c -3.768329,-23.42962 7.455828,-38.32595 50.49813,-67.01953 6.041298,-4.02691 12.708263,-9.27073 14.816577,-11.65295 2.108023,-2.3822 4.524361,-4.48001 4.524361,-4.48001 0,0 45.05507,-44.22564 69.74451,-58.59581 72.48275,-42.18783 238.75927,-76.44031 425.63149,-87.67895 14.00372,-0.84197 33.99829,-2.07064 44.43261,-2.72959 26.21726,-1.65646 1973.24248,-2.45294 2062.36198,-0.84445 156.7316,2.82998 269.5005,7.74134 530.5511,23.10724 47.1495,2.7752 85.8534,4.90642 86.012,4.73564 0.6463,-0.69433 3.18,-46.35302 2.6116,-47.00235 -0.3392,-0.38606 -8.4798,-1.63074 -18.0917,-2.7653 -35.3422,-4.17401 -67.399,-11.82474 -77.0779,-18.39697 -3.9158,-2.65808 -3.9645,-3.95085 -1.9416,-51.11949 2.108,-49.16104 3.1187,-81.48815 3.1285,-100.00521 0,-21.77363 -0.1657,-21.37816 11.1206,-24.94772 37.4058,-11.83133 117.8811,-11.06942 171.1122,1.62031 15.227,3.62986 19.589,3.51496 35.5372,-0.93615 21.7001,-6.05753 21.0601,-5.51568 96.6373,-82.052719 33.1386,-33.558758 68.757,-66.037569 68.757,-66.037569 0,0 83.3796,-1.079949 169.2388,-1.079949 136.9782,0 171.6165,0.253341 171.2179,1.25017 -4.4107,11.004128 -56.5812,125.499597 -58.6917,128.808777 -4.6101,7.22481 -3.2139,7.88313 16.7587,7.90201 9.0622,0.008 22.5343,1.10293 37.2289,3.0234 4.1187,0.5386 15.3536,1.65343 24.9606,2.47749 9.6122,0.82422 19.8325,1.75756 22.7175,2.07418 5.0681,0.55713 9.0514,198.40717 3.9934,198.38178 -3.6049,-0.0227 -31.7008,3.23584 -34.6991,4.01865 -1.9198,0.50162 -6.9752,1.19264 -11.2312,1.53478 -7.7386,0.62215 -7.7386,0.62215 -7.7386,8.4184 0,8.93284 0.045,8.97847 9.985,9.03089 7.595,0.034 9.8124,1.63453 3.4137,2.45321 -2.7018,0.34575 -6.0356,0.83238 -7.4075,1.08266 -1.3721,0.25018 -13.4624,0.89408 -26.8658,1.43238 -13.4009,0.53851 -28.9024,1.4418 -34.4462,2.00812 -15.6072,1.59497 -41.7208,3.01042 -55.6346,3.01554 -20.6343,0.008 -19.0304,-1.48851 -18.6619,17.4164 0.3714,19.01843 2.3134,23.86211 11.5516,28.7958 5.5848,2.98376 0.3035,2.54795 88.3399,7.28999 84.7141,4.56302 75.158,-2.81091 75.158,57.97778 0,54.09028 0.038,53.96894 -18.7912,59.84504 -20.4081,6.36957 -118.4497,34.30825 -182.9044,52.12181 -74.4105,20.56545 -152.6321,42.51798 -160.2541,44.9738 -10.5871,3.41069 -57.1162,16.38817 -105.4333,29.40502 -184.6228,49.73829 -402.0471,89.78228 -516.1218,95.05681 -19.1654,0.88577 -2300.07154,1.25614 -2320.9699,0.37695 z m 1714.3911,-15.93638 c 14.3101,-1.72862 35.0046,-5.59211 45.932,-8.57466 47.3734,-12.93067 34.3571,-20.57346 -70.3941,-41.33854 -9.3343,-1.85054 -21.9156,-4.53045 -27.9568,-5.955 -119.2244,-28.11802 -135.9358,-31.16723 -227.3866,-41.48667 -32.4779,-3.66487 -84.0049,-11.3955 -126.5748,-18.9901 -77.6003,-13.84405 -129.5471,-21.9553 -156.762,-24.47858 -178.2016,-16.52165 -260.2497,38.68714 -109.1224,73.42801 7.2586,1.66798 18.9422,5.29576 25.9629,8.06195 39.3007,15.48166 111.0211,26.35086 233.4296,35.37682 97.5092,7.1897 247.1876,10.13705 247.9345,4.88196 0.6641,-4.66361 1.511,-4.79998 36.7154,-5.88569 22.9808,-0.70847 26.3783,-0.21481 26.3783,3.83836 0,2.5877 2.9594,14.02473 3.8762,14.97665 0.4007,0.41452 15.6685,2.27843 33.9288,4.14116 18.264,1.86268 33.4272,3.60903 33.698,3.88056 0.7657,0.76635 16.5438,-0.20912 30.341,-1.87623 z m -2029.36746,-359.3222 -0.0248,215.97654 1275.64716,-4.1e-4 h 1275.1949 l 132.9522,-2.46652 132.952,-2.4665 147.9241,-11.4452 147.9243,-11.4452 1.0236,-90.88061 1.0235,-90.88061 -83.3015,-4.35422 -83.3014,-4.35424 m -2614.52231,217.81122 -5e-5,159.11801 z M 1748.1434,708.5565 v 75.45385 z m 1663.0399,-106.30033 -1e-4,113.31756 z m -1009.9445,22.54108 v 99.39317 z m -4e-4,143.38207 v 15.78331 z"
|
||||
sodipodi:nodetypes="ccccccccccccccccccscscccccccsccccsccscscsccsssccssscsssssscsssssssccssscsscccscsscscsccccccccccccccccccccccccccc"
|
||||
transform="matrix(1.0068517,0,0,1.0069072,-24.265193,-12.003831)"
|
||||
inkscape:label="Solid" /></g></svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
54
MD11_Profile/MD11_Profile_EXP.svg
Normal file
54
MD11_Profile/MD11_Profile_EXP.svg
Normal file
@ -0,0 +1,54 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="4002"
|
||||
height="780"
|
||||
viewBox="0 0 4002 780"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" />
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:160px;line-height:1.25;font-family:sans-serif;text-anchor:end;display:inline"
|
||||
x="1476.2501"
|
||||
y="276.92206"
|
||||
id="text2"><tspan
|
||||
id="tspan2"
|
||||
x="1476.2501"
|
||||
y="276.92206">9999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-size:160px;line-height:1.25;font-family:sans-serif;text-anchor:end;display:inline"
|
||||
x="1476.2501"
|
||||
y="130.53906"
|
||||
id="text3"><tspan
|
||||
id="tspan3"
|
||||
x="1476.2501"
|
||||
y="130.53906">999999</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-size:133.333px;line-height:1.25;font-family:sans-serif;display:inline;stroke-width:0.999998"
|
||||
x="3752.9043"
|
||||
y="778.24402"
|
||||
id="text4"><tspan
|
||||
x="3752.9043"
|
||||
y="778.24402"
|
||||
style="font-size:133.333px;stroke-width:0.999998"
|
||||
id="tspan6">LBS</tspan></text><path
|
||||
id="text7"
|
||||
style="font-size:160px;line-height:1.25;-inkscape-font-specification:sans-serif;display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:7.99861;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 3616.1269,203.67131 -115.4682,116.32951 h 76.6132 l 13.6484,-13.75016 h -61.1499 l 42.8836,-43.20365 h 61.1499 l 13.6485,-13.75016 h -61.1499 l 31.6393,-31.87538 h 61.1499 l 13.6484,-13.75016 z m 101.1357,0 -115.4682,116.32951 h 15.4631 l 45.9082,-46.25055 h 21.7891 l -7.0158,46.25055 h 20.0709 l 6.7491,-50.85999 c 10.2365,-2.8646 20.2552,-7.10948 30.0559,-12.73452 9.8522,-5.67714 18.9402,-12.70852 27.2636,-21.09401 6.1521,-6.19797 10.0211,-11.30222 11.6068,-15.31268 1.6896,-4.06255 1.7441,-7.42197 0.1635,-10.07824 -1.4223,-2.34378 -4.0367,-3.95839 -7.8438,-4.84382 -3.7552,-0.93749 -9.1472,-1.40626 -16.176,-1.40625 z m 2.2801,13.2814 h 18.1967 c 4.165,0 7.4735,0.31252 9.9248,0.93751 2.5032,0.57292 4.1244,1.61462 4.8641,3.12503 0.9495,1.77087 0.7045,3.9584 -0.735,6.56258 -1.3356,2.55212 -3.6579,5.49487 -6.9666,8.82824 -4.3426,4.37505 -8.5084,7.9949 -12.4972,10.8595 -3.8849,2.81253 -8.0847,5.31258 -12.5989,7.50009 -4.8776,2.34378 -9.5781,3.95838 -14.1015,4.84381 -4.4716,0.83333 -9.1546,1.25002 -14.0487,1.25002 h -15.6194 z" /><path
|
||||
id="path10"
|
||||
style="display:inline;fill:none;fill-opacity:1;stroke:#000000;stroke-width:4.00262;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M 96.063623,565.67598 H 225.01404 v 29.2795 H 344.97851 M 1911.8987,616.96921 V 368.69287 Z m -784.3419,-247.8136 v 248.27438 z m 1566.6617,1.0929 3e-4,247.40401 0.01,-247.40401 z M 96.032159,498.84983 v 180.314 z M 662.23419,777.49213 C 530.19783,771.93392 438.25472,761.13712 303.21108,735.33296 224.55244,720.30291 140.71674,697.40088 92.216212,677.69426 41.454903,657.06926 6.5853009,628.37831 2.6667227,604.01258 -1.1274258,580.42113 10.173636,565.4219 53.510851,536.53013 c 6.082691,-4.05472 12.795336,-9.33476 14.918095,-11.73344 2.122467,-2.39865 4.555361,-4.51095 4.555361,-4.51095 0,0 45.363773,-44.53112 70.222383,-59.00054 72.97938,-42.47923 240.39517,-76.9683 428.54778,-88.28457 14.09967,-0.84779 34.23124,-2.08494 44.73705,-2.74844 26.3969,-1.66791 1986.76258,-2.46989 2076.49268,-0.85029 157.8055,2.84953 271.347,7.79481 534.1863,23.26685 47.4725,2.79437 86.4416,4.94031 86.6013,4.76835 0.6507,-0.69913 3.2018,-46.67319 2.6295,-47.32701 -0.3415,-0.38872 -8.5379,-1.642 -18.2157,-2.7844 -35.5843,-4.20284 -67.8608,-11.90641 -77.606,-18.52404 -3.9426,-2.67644 -3.9916,-3.97814 -1.9549,-51.47258 2.1225,-49.50061 3.1401,-82.051 3.1499,-100.69597 0,-21.92402 -0.1668,-21.52582 11.1968,-25.12003 37.6621,-11.91306 118.6888,-11.14588 172.2847,1.6315 15.3313,3.65493 19.7232,3.53924 35.7806,-0.94262 21.8488,-6.09937 21.2044,-5.55378 97.2995,-82.619473 33.3656,-33.790555 69.2278,-66.4937035 69.2278,-66.4937035 0,0 83.9512,-1.0874084 170.3986,-1.0874084 137.9168,0 172.7927,0.2550909 172.3914,1.2588052 -4.4409,11.0801357 -56.9692,126.3664497 -59.0942,129.6984897 -4.6416,7.27471 -3.2359,7.93758 16.8736,7.95659 9.1243,0.008 22.6887,1.11054 37.484,3.04428 4.1469,0.54232 15.4587,1.66485 25.1316,2.4946 9.678,0.82991 19.9684,1.7697 22.8731,2.08851 5.1029,0.56098 9.1134,199.77761 4.0208,199.75204 -3.6296,-0.0229 -31.918,3.25819 -34.9369,4.04641 -1.9329,0.50508 -7.023,1.20088 -11.3081,1.54538 -7.7916,0.62645 -7.7916,0.62645 -7.7916,8.47655 0,8.99454 0.045,9.04048 10.0534,9.09327 7.647,0.0342 9.8796,1.64582 3.4371,2.47015 -2.7203,0.34814 -6.077,0.83813 -7.4583,1.09014 -1.3815,0.25191 -13.5546,0.90025 -27.0499,1.44227 -13.4927,0.54223 -29.1004,1.45176 -34.6822,2.02199 -15.7141,1.60599 -42.0066,3.03122 -56.0158,3.03637 -20.7756,0.008 -19.1608,-1.49879 -18.7897,17.5367 0.3739,19.14979 2.3292,24.02693 11.6307,28.9947 5.6231,3.00437 0.3056,2.56555 88.9452,7.34034 85.2945,4.59454 75.673,-2.83032 75.673,58.37825 0,54.46389 0.038,54.34171 -18.92,60.2584 -20.5479,6.41356 -119.2613,34.54522 -184.1576,52.48182 -74.9203,20.7075 -153.6779,42.81166 -161.3521,45.28445 -10.6597,3.43424 -57.5076,16.50136 -106.1557,29.60812 -185.8878,50.08185 -404.8018,90.40243 -519.6581,95.71339 -19.2967,0.89189 -2315.83097,1.26482 -2336.87252,0.37955 z M 2388.3718,761.44567 c 14.4081,-1.74056 35.2444,-5.63073 46.2467,-8.63389 47.698,-13.01998 34.5925,-20.71556 -70.8764,-41.62407 -9.3983,-1.86332 -22.0658,-4.56174 -28.1484,-5.99613 -120.0413,-28.31224 -136.8672,-31.38251 -228.9446,-41.77323 -32.7004,-3.69018 -84.5804,-11.47421 -127.442,-19.12127 -78.132,-13.93967 -130.4347,-22.10695 -157.8361,-24.64765 -179.4226,-16.63577 -262.0329,38.95436 -109.8701,73.93519 7.3084,1.6795 19.072,5.33234 26.1408,8.11763 39.57,15.5886 111.7818,26.53287 235.029,35.62118 98.1773,7.23936 248.8813,10.20707 249.6333,4.91568 0.6686,-4.69582 1.5213,-4.83314 36.9669,-5.92635 23.1383,-0.71336 26.5591,-0.21629 26.5591,3.86488 0,2.60557 2.9797,14.1216 3.9027,15.08009 0.4035,0.41739 15.7759,2.29417 34.1613,4.16977 18.3891,1.87554 33.6562,3.63396 33.9289,3.90736 0.7709,0.77164 16.6571,-0.21056 30.5489,-1.88919 z M 345.0997,399.64156 l -0.025,217.46833 1284.3875,-4.1e-4 h 1283.9322 l 133.8631,-2.48356 133.863,-2.48353 148.9376,-11.52426 148.9379,-11.52425 1.0306,-91.50834 1.0305,-91.50834 -83.8723,-4.3843 -83.8721,-4.38431 m -2632.43629,219.31568 -5e-5,160.21707 z M 1735.856,701.44681 v 75.97503 z m 1674.4345,-107.03457 -1e-4,114.10027 z m -1016.8643,22.69678 v 100.0797 z m -4e-4,144.37244 v 15.89233 z" /><path
|
||||
id="path5"
|
||||
style="display:inline;fill:none;stroke:#646464;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
d="m 1735.962,616.7647 v 84.15891 z m 657.6119,99.08378 v 43.38354 z" /></svg>
|
||||
|
After Width: | Height: | Size: 6.8 KiB |
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<AssetPackage Version="0.1.0">
|
||||
<ItemSettings>
|
||||
<ContentType>MISC</ContentType>
|
||||
<Title>TFDi Design MD-11 Load Manager</Title>
|
||||
<Manufacturer/>
|
||||
<Creator>khofmann</Creator>
|
||||
</ItemSettings>
|
||||
<Flags>
|
||||
<VisibleInStore>false</VisibleInStore>
|
||||
<CanBeReferenced>false</CanBeReferenced>
|
||||
</Flags>
|
||||
<AssetGroups>
|
||||
<AssetGroup Name="ContentInfo">
|
||||
<Type>ContentInfo</Type>
|
||||
<Flags>
|
||||
<FSXCompatibility>false</FSXCompatibility>
|
||||
</Flags>
|
||||
<AssetDir>PackageDefinitions\xkhofmann-tfdidesign-md11-load-manager\ContentInfo\</AssetDir>
|
||||
<OutputDir>ContentInfo\xkhofmann-tfdidesign-md11-load-manager\</OutputDir>
|
||||
</AssetGroup>
|
||||
<AssetGroup Name="html-ui">
|
||||
<Type>Copy</Type>
|
||||
<Flags>
|
||||
<FSXCompatibility>false</FSXCompatibility>
|
||||
</Flags>
|
||||
<AssetDir>PackageSources\html_ui\</AssetDir>
|
||||
<OutputDir>html_ui\</OutputDir>
|
||||
</AssetGroup>
|
||||
<AssetGroup Name="load-manager-panel">
|
||||
<Type>SPB</Type>
|
||||
<Flags>
|
||||
<FSXCompatibility>false</FSXCompatibility>
|
||||
</Flags>
|
||||
<AssetDir>PackageSources\load-manager-panel\</AssetDir>
|
||||
<OutputDir>InGamePanels\</OutputDir>
|
||||
</AssetGroup>
|
||||
</AssetGroups>
|
||||
</AssetPackage>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
29
PackageSources/js-bundle/.eslintrc.cjs
Normal file
29
PackageSources/js-bundle/.eslintrc.cjs
Normal file
@ -0,0 +1,29 @@
|
||||
module.exports = {
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
node: {
|
||||
extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
|
||||
},
|
||||
},
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
},
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/errors',
|
||||
'plugin:import/typescript',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
rules: {
|
||||
'react/jsx-uses-react': 'off',
|
||||
'react/react-in-jsx-scope': 'off',
|
||||
'react/prop-types': 'off',
|
||||
'@typescript-eslint/no-shadow': 'error',
|
||||
},
|
||||
};
|
||||
1
PackageSources/js-bundle/.npmrc
Normal file
1
PackageSources/js-bundle/.npmrc
Normal file
@ -0,0 +1 @@
|
||||
engine-strict = true
|
||||
1
PackageSources/js-bundle/.nvmrc
Normal file
1
PackageSources/js-bundle/.nvmrc
Normal file
@ -0,0 +1 @@
|
||||
v18
|
||||
9
PackageSources/js-bundle/.prettierrc.cjs
Normal file
9
PackageSources/js-bundle/.prettierrc.cjs
Normal file
@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
printWidth: 120,
|
||||
tabWidth: 2,
|
||||
semi: true,
|
||||
trailingComma: 'es5',
|
||||
singleQuote: true,
|
||||
arrowParens: 'always',
|
||||
plugins: ['prettier-plugin-organize-imports'],
|
||||
};
|
||||
1
PackageSources/js-bundle/index.d.ts
vendored
Normal file
1
PackageSources/js-bundle/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="@microsoft/msfs-types/js/common.d.ts" />
|
||||
71
PackageSources/js-bundle/package.json
Normal file
71
PackageSources/js-bundle/package.json
Normal file
@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "tfdidesign-md11-load-manager",
|
||||
"version": "0.1.14",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"types": "rimraf __generated__ && typed-scss-modules ./src --nameFormat none --exportType default --outputFolder __generated__",
|
||||
"lint": "eslint ./src",
|
||||
"licenses": "license-report --output=markdown > ./src/assets/licenses_node.md",
|
||||
"debugger": "cd \"%MSFS_SDK%\\Tools\\CoherentGT Debugger\" && Debugger.exe",
|
||||
"locale": "cd \"%MSFS_SDK%\\Tools\\MSFS_Localization\" && MSFSLocalizationManager.exe",
|
||||
"dev": "npx rollup -c -w",
|
||||
"clean": "rimraf ../html_ui/InGamePanels/tfdidesign-md11-load-manager-panel/ && rimraf .rollup.cache",
|
||||
"build": "npm version patch && npx rollup -c",
|
||||
"release": "pnpm types && pnpm lint && pnpm run licenses && pnpm clean && npm version patch && cross-env NODE_ENV=production npx rollup -c"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@microsoft/msfs-types": "^1.14.6",
|
||||
"@rollup/plugin-commonjs": "^28.0.3",
|
||||
"@rollup/plugin-json": "^6.1.0",
|
||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||
"@rollup/plugin-replace": "^6.0.2",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@rollup/plugin-typescript": "^12.1.2",
|
||||
"@types/react": "^19.1.6",
|
||||
"@types/react-dom": "^19.1.6",
|
||||
"@types/uuid": "^10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.21.0",
|
||||
"@typescript-eslint/parser": "^6.21.0",
|
||||
"autoprefixer": "^10.4.21",
|
||||
"cross-env": "^7.0.3",
|
||||
"eslint": "^8.57.1",
|
||||
"eslint-plugin-import": "^2.31.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^4.6.2",
|
||||
"license-report": "^6.7.2",
|
||||
"postcss": "^8.5.4",
|
||||
"postcss-import": "^16.1.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-organize-imports": "^4.1.0",
|
||||
"rimraf": "^6.0.1",
|
||||
"rollup": "^4.42.0",
|
||||
"rollup-plugin-copy": "^3.5.0",
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"rollup-plugin-react-svg": "^3.0.3",
|
||||
"rollup-plugin-version-injector": "^1.3.3",
|
||||
"sass": "^1.89.1",
|
||||
"svg-slim": "^2.0.5",
|
||||
"tslib": "^2.8.1",
|
||||
"typed-scss-modules": "^8.1.1",
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@mui/icons-material": "^5.14.16",
|
||||
"@mui/material": "^5.14.17",
|
||||
"postcss-import": "^15.1.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.11.1+sha512.e519b9f7639869dc8d5c3c5dfef73b3f091094b0a006d7317353c72b124e80e1afd429732e28705ad6bfa1ee879c1fce46c128ccebd3192101f43dd67c667912"
|
||||
}
|
||||
6676
PackageSources/js-bundle/pnpm-lock.yaml
generated
Normal file
6676
PackageSources/js-bundle/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
72
PackageSources/js-bundle/rollup.config.js
Normal file
72
PackageSources/js-bundle/rollup.config.js
Normal file
@ -0,0 +1,72 @@
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import json from '@rollup/plugin-json';
|
||||
import resolve from '@rollup/plugin-node-resolve';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
import typescript from '@rollup/plugin-typescript';
|
||||
import autoprefixer from 'autoprefixer';
|
||||
import atImport from 'postcss-import';
|
||||
import copy from 'rollup-plugin-copy';
|
||||
import postcss from 'rollup-plugin-postcss';
|
||||
import reactSvg from 'rollup-plugin-react-svg';
|
||||
import versionInjector from 'rollup-plugin-version-injector';
|
||||
import svgs from 'svg-slim';
|
||||
|
||||
const { NODE_ENV: targetEnv = 'development' } = process.env;
|
||||
const outDirBase = '../html_ui';
|
||||
const panelDirBase = `${outDirBase}/InGamePanels/tfdidesign-md11-load-manager-panel`;
|
||||
|
||||
function svgSlim(code, id) {
|
||||
if (!id.endsWith('.svg')) return code;
|
||||
return svgs(code.toString(), {}).then((res) => res);
|
||||
}
|
||||
|
||||
export default {
|
||||
input: 'src/index.ts',
|
||||
output: {
|
||||
dir: panelDirBase,
|
||||
format: 'es',
|
||||
sourcemap: targetEnv !== 'production',
|
||||
},
|
||||
plugins: [
|
||||
replace({
|
||||
'process.env.NODE_ENV': JSON.stringify(targetEnv),
|
||||
'import.meta.env': true,
|
||||
'import.meta.env.MODE': JSON.stringify(targetEnv),
|
||||
}),
|
||||
versionInjector(),
|
||||
postcss({
|
||||
plugins: [autoprefixer(), atImport()],
|
||||
extract: true,
|
||||
use: ['sass'],
|
||||
sourceMap: 'inline',
|
||||
minimize: targetEnv === 'production',
|
||||
}),
|
||||
reactSvg(),
|
||||
resolve(),
|
||||
json(),
|
||||
typescript(),
|
||||
commonjs({
|
||||
requireReturnsDefault: 'auto',
|
||||
}),
|
||||
targetEnv === 'production' && terser(),
|
||||
copy({
|
||||
targets: [
|
||||
{ src: ['src/assets/*', '!**/*.svg'], dest: `${panelDirBase}/assets` },
|
||||
{ src: 'src/assets/img/*', dest: `${panelDirBase}/assets/img`, transform: svgSlim },
|
||||
{ src: ['src/index.html'], dest: `${panelDirBase}` },
|
||||
{
|
||||
src: ['src/assets/ICON_TFDIDESIGN_MD11_LOAD_MANAGER.svg'],
|
||||
dest: [`${outDirBase}/icons/toolbar`, `${outDirBase}/Textures/Menu/toolbar`],
|
||||
transform: svgSlim,
|
||||
},
|
||||
],
|
||||
}),
|
||||
],
|
||||
onwarn: function (warning, warn) {
|
||||
if (warning.code === 'MODULE_LEVEL_DIRECTIVE') {
|
||||
return;
|
||||
}
|
||||
warn(warning);
|
||||
},
|
||||
};
|
||||
9
PackageSources/js-bundle/src/App.module.scss
Normal file
9
PackageSources/js-bundle/src/App.module.scss
Normal file
@ -0,0 +1,9 @@
|
||||
@import 'fonts/300.css';
|
||||
@import 'fonts/400.css';
|
||||
@import 'fonts/500.css';
|
||||
@import 'fonts/700.css';
|
||||
|
||||
.app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
127
PackageSources/js-bundle/src/App.tsx
Normal file
127
PackageSources/js-bundle/src/App.tsx
Normal file
@ -0,0 +1,127 @@
|
||||
import { FC, StrictMode, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import Freight from './components/freight/Freight';
|
||||
import Pax from './components/pax/Pax';
|
||||
import { PayloadFreight, calculateCGsFreight, getWeightsFreight } from './configs/freighter';
|
||||
import { PaxConfig, PayloadPax } from './configs/pax';
|
||||
import { Fuel, getFuel, initialFuel, initialPayload } from './configs/shared';
|
||||
|
||||
interface IAppProps {
|
||||
commBus: ViewListener.ViewListener;
|
||||
}
|
||||
|
||||
const App: FC<IAppProps> = ({ commBus }) => {
|
||||
// Inferred
|
||||
const [unit, setUnit] = useState<'lbs' | 'kg'>('lbs');
|
||||
const [isCargo, setIsCargo] = useState(false);
|
||||
const [isER, setIsER] = useState(false);
|
||||
const [SBUsername, setSBUsername] = useState<string>();
|
||||
|
||||
// From sim
|
||||
const [payloadLive, setPayloadLive] = useState<PayloadPax | PayloadFreight>(initialPayload);
|
||||
const [fuel, setFuel] = useState<Fuel>(initialFuel);
|
||||
const [GSXPaxNum, setGSXPaxNum] = useState(0);
|
||||
const [GSXCargoPercent, setGSXCargoPercent] = useState(0);
|
||||
const [GSXState, setGSXState] = useState<'boarding' | 'deboarding' | 'idle'>('idle');
|
||||
|
||||
// Calculated
|
||||
const [CGs, setCGs] = useState<[number, number]>([0, 0]);
|
||||
|
||||
const [isReady, setIsReady] = useState(false);
|
||||
|
||||
const requestRef = useRef<number | undefined>(undefined);
|
||||
|
||||
// Main Loop for Live Payload
|
||||
const mainLoop = () => {
|
||||
try {
|
||||
if (SimVar.IsReady()) {
|
||||
setIsER(SimVar.GetSimVarValue('L:MD11_OPT_ER', 'bool'));
|
||||
setIsCargo(SimVar.GetSimVarValue('L:MD11_EFB_IS_CARGO', 'bool'));
|
||||
setUnit((SimVar.GetSimVarValue('L:MD11_EFB_OPTIONS_GENERAL', 'number') & 1) << 0 ? 'lbs' : 'kg');
|
||||
|
||||
// GSX
|
||||
const boardingState = SimVar.GetSimVarValue('L:FSDT_GSX_BOARDING_STATE', 'number');
|
||||
const deboardingState = SimVar.GetSimVarValue('L:FSDT_GSX_DEBOARDING_STATE', 'number');
|
||||
setGSXState(boardingState === 5 ? 'boarding' : deboardingState === 5 ? 'deboarding' : 'idle');
|
||||
setGSXPaxNum(
|
||||
boardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_NUMPASSENGERS_BOARDING_TOTAL', 'number')
|
||||
: deboardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_NUMPASSENGERS_DEBOARDING_TOTAL', 'number')
|
||||
: 0
|
||||
);
|
||||
setGSXCargoPercent(
|
||||
boardingState === 5
|
||||
? SimVar.GetSimVarValue('L:FSDT_GSX_BOARDING_CARGO_PERCENT', 'number')
|
||||
: deboardingState === 5
|
||||
? 100 - SimVar.GetSimVarValue('L:FSDT_GSX_DEBOARDING_CARGO_PERCENT', 'number')
|
||||
: 0
|
||||
);
|
||||
|
||||
const payload = isCargo ? getWeightsFreight(unit) : PaxConfig.getWeights(unit);
|
||||
const _fuel = getFuel(unit);
|
||||
|
||||
setCGs(
|
||||
isCargo
|
||||
? calculateCGsFreight(payload as PayloadFreight, _fuel)
|
||||
: PaxConfig.calculateCGs(payload as PayloadPax, _fuel)
|
||||
);
|
||||
setPayloadLive(payload);
|
||||
setFuel(_fuel);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
};
|
||||
useEffect(() => {
|
||||
requestRef.current = requestAnimationFrame(mainLoop);
|
||||
|
||||
if (requestRef.current !== undefined) return () => cancelAnimationFrame(requestRef.current as number);
|
||||
}, [unit, isCargo]);
|
||||
|
||||
// CommBus
|
||||
const usernameCallback = useCallback((username: string) => {
|
||||
setSBUsername(username);
|
||||
setIsReady(true);
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
console.log('Initializing CommBus');
|
||||
|
||||
commBus.on('receiveSimBriefUsername', usernameCallback);
|
||||
|
||||
setTimeout(() => {
|
||||
Coherent.call('COMM_BUS_WASM_CALLBACK', 'requestSimBriefUsername', 'null');
|
||||
}, 1000);
|
||||
|
||||
return () => commBus.off('receiveSimBriefUsername', usernameCallback);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StrictMode>
|
||||
<div className="flex w-full justify-center pt-2 bg-zinc-900">
|
||||
<div className="flex w-3/4 flex-col items-center">
|
||||
{isReady ? (
|
||||
isCargo ? (
|
||||
<Freight isER={isER} unit={unit} OEW={payloadLive.empty} CGs={CGs} />
|
||||
) : (
|
||||
<Pax
|
||||
isER={isER}
|
||||
unit={unit}
|
||||
CGs={CGs}
|
||||
fuelLive={fuel}
|
||||
payloadLive={payloadLive as PayloadPax}
|
||||
username={SBUsername}
|
||||
GSXPaxNum={GSXPaxNum}
|
||||
GSXCargoPercent={GSXCargoPercent}
|
||||
GSXState={GSXState}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<h1 className="text-sm font-medium">LOADING</h1>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</StrictMode>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@ -0,0 +1,10 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 54 35">
|
||||
<path
|
||||
d="M17.08737 32.03408c-6.24 0-11.298-5.216-11.298-11.651 0-6.434 5.058-11.651 11.298-11.651s11.298 5.217 11.298 11.651c0 .679-.059 1.343-.167 1.989l1.052.29c.13-.741.202-1.502.202-2.281 0-7.082-5.579-12.823-12.46-12.823-6.881 0-12.46 5.741-12.46 12.823 0 7.081 5.579 12.822 12.46 12.822 4.524 0 8.485-2.482 10.668-6.196h-1.301c-2.039 3.037-5.439 5.027-9.292 5.027" />
|
||||
<path
|
||||
d="M43.10237.39308s-1.764 2.479-3.978 5.076c-2.212 2.595-4.01 4.393-4.01 4.393l-.166-.716-.766-.116s2.147-2.33 4.343-4.56c2.197-2.23 4.577-4.077 4.577-4.077" />
|
||||
<path
|
||||
d="M34.63157 9.42938s-.316 1.082-.732 1.547c-.416.466-.949.649-1.431 1.065-.483.417-1.964 2.031-1.964 2.031s-5.525 5.974-9.186 9.302c-3.661 3.329-8.058 7.009-11.183 8.837-3.129 1.831-5.675 2.912-7.805 2.147-2.13-.766-2.32-2.96-1.864-4.693.416-1.581 1.598-2.646 1.598-2.646s-1.698 1.88-1.664 3.977c.014.899.299 1.664.732 2.23.251.328 1.794 1.632 4.476.766 1.598-.516 4.015-1.526 6.84-3.695 5.875-4.51 7.805-6.174 13.696-12.131 3.277-3.314 5.375-5.642 5.375-5.642s.483-.432.665-.798c.184-.367.367-1.049.883-1.448s1.564-.849 1.564-.849" />
|
||||
<path
|
||||
d="M17.89017 18.03288h1.023s3.096 2.696 6.915 3.994 6.989 1.997 13.28 2.296c6.29.3 10.958.375 12.431.575 1.473.199 2.197.499 2.197.499s-13.056.424-17.224.599c-4.169.174-11.857.823-11.857.823l-.625-.299 5.592-1.598-6.964-.075z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
1814
PackageSources/js-bundle/src/assets/efb.css
Normal file
1814
PackageSources/js-bundle/src/assets/efb.css
Normal file
File diff suppressed because it is too large
Load Diff
202
PackageSources/js-bundle/src/assets/fonts/LICENSE.txt
Normal file
202
PackageSources/js-bundle/src/assets/fonts/LICENSE.txt
Normal file
@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Black.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Black.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-BlackItalic.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-BlackItalic.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Bold.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Bold.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-BoldItalic.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Italic.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Italic.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Light.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Light.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-LightItalic.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-LightItalic.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Medium.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Medium.ttf
Normal file
Binary file not shown.
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Regular.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Regular.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Thin.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-Thin.ttf
Normal file
Binary file not shown.
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-ThinItalic.ttf
Normal file
BIN
PackageSources/js-bundle/src/assets/fonts/Roboto-ThinItalic.ttf
Normal file
Binary file not shown.
2
PackageSources/js-bundle/src/assets/licenses.md
Normal file
2
PackageSources/js-bundle/src/assets/licenses.md
Normal file
@ -0,0 +1,2 @@
|
||||
| Name | Modified | License type | Link | Author |
|
||||
| :--- | :------- | :----------- | :--- | :----- |
|
||||
44
PackageSources/js-bundle/src/assets/licenses_node.md
Normal file
44
PackageSources/js-bundle/src/assets/licenses_node.md
Normal file
@ -0,0 +1,44 @@
|
||||
| Department | Related to | Name | License period | Material not material | License type | Link | Remote version | Installed version | Defined version | Author |
|
||||
| :--------- | :--------- | :------------------------------- | :------------- | :-------------------- | :----------- | :------------------------------------------------------------------------ | :------------- | :---------------- | :-------------- | :---------------------------------------------------------- |
|
||||
| kessler | stuff | @emotion/react | perpetual | material | MIT | git+https://github.com/emotion-js/emotion.git#main | 11.14.0 | 11.14.0 | ^11.11.1 | Emotion Contributors |
|
||||
| kessler | stuff | @emotion/styled | perpetual | material | MIT | git+https://github.com/emotion-js/emotion.git#main | 11.14.0 | 11.14.0 | ^11.11.0 | n/a |
|
||||
| kessler | stuff | @mui/icons-material | perpetual | material | MIT | git+https://github.com/mui/material-ui.git | 5.17.1 | 5.17.1 | ^5.14.16 | MUI Team |
|
||||
| kessler | stuff | @mui/material | perpetual | material | MIT | git+https://github.com/mui/material-ui.git | 5.17.1 | 5.17.1 | ^5.14.17 | MUI Team |
|
||||
| kessler | stuff | postcss-import | perpetual | material | MIT | git+https://github.com/postcss/postcss-import.git | 15.1.0 | 15.1.0 | ^15.1.0 | Maxime Thirouin |
|
||||
| kessler | stuff | react | perpetual | material | MIT | git+https://github.com/facebook/react.git | 18.3.1 | 18.3.1 | ^18.2.0 | n/a |
|
||||
| kessler | stuff | react-dom | perpetual | material | MIT | git+https://github.com/facebook/react.git | 18.3.1 | 18.3.1 | ^18.2.0 | n/a |
|
||||
| kessler | stuff | uuid | perpetual | material | MIT | git+https://github.com/uuidjs/uuid.git | 9.0.1 | 9.0.1 | ^9.0.1 | n/a |
|
||||
| kessler | stuff | @microsoft/msfs-types | perpetual | material | MIT | git+https://github.com/microsoft/msfs-avionics-mirror.git | 1.14.6 | 1.14.6 | ^1.14.6 | Asobo Studio / Working Title Simulations |
|
||||
| kessler | stuff | @rollup/plugin-commonjs | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 25.0.8 | 25.0.8 | ^25.0.0 | Rich Harris <richard.a.harris@gmail.com> |
|
||||
| kessler | stuff | @rollup/plugin-json | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 6.1.0 | 6.1.0 | ^6.0.0 | rollup |
|
||||
| kessler | stuff | @rollup/plugin-node-resolve | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 15.3.1 | 15.3.1 | ^15.1.0 | Rich Harris <richard.a.harris@gmail.com> |
|
||||
| kessler | stuff | @rollup/plugin-replace | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 6.0.2 | 6.0.2 | ^6.0.2 | Rich Harris <richard.a.harris@gmail.com> |
|
||||
| kessler | stuff | @rollup/plugin-terser | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 0.4.4 | 0.4.4 | ^0.4.3 | Peter Placzek <peter.placzek1996@gmail.com> |
|
||||
| kessler | stuff | @rollup/plugin-typescript | perpetual | material | MIT | git+https://github.com/rollup/plugins.git | 11.1.6 | 11.1.6 | ^11.1.1 | Oskar Segersvärd |
|
||||
| kessler | stuff | @types/react | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 18.3.23 | 18.3.23 | ^18.2.8 | n/a |
|
||||
| kessler | stuff | @types/react-dom | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 18.3.7 | 18.3.7 | ^18.2.4 | n/a |
|
||||
| kessler | stuff | @types/uuid | perpetual | material | MIT | https://github.com/DefinitelyTyped/DefinitelyTyped.git | 9.0.8 | 9.0.8 | ^9.0.7 | n/a |
|
||||
| kessler | stuff | @typescript-eslint/eslint-plugin | perpetual | material | MIT | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.10.0 | n/a |
|
||||
| kessler | stuff | @typescript-eslint/parser | perpetual | material | BSD-2-Clause | git+https://github.com/typescript-eslint/typescript-eslint.git | 6.21.0 | 6.21.0 | ^6.10.0 | n/a |
|
||||
| kessler | stuff | autoprefixer | perpetual | material | MIT | git+https://github.com/postcss/autoprefixer.git | 10.4.21 | 10.4.21 | ^10.4.14 | Andrey Sitnik <andrey@sitnik.ru> |
|
||||
| kessler | stuff | cross-env | perpetual | material | MIT | git+https://github.com/kentcdodds/cross-env.git | 7.0.3 | 7.0.3 | ^7.0.3 | Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com) |
|
||||
| kessler | stuff | eslint | perpetual | material | MIT | git+https://github.com/eslint/eslint.git | 8.57.1 | 8.57.1 | ^8.42.0 | Nicholas C. Zakas <nicholas+npm@nczconsulting.com> |
|
||||
| kessler | stuff | eslint-plugin-import | perpetual | material | MIT | git+https://github.com/import-js/eslint-plugin-import.git | 2.31.0 | 2.31.0 | ^2.27.5 | Ben Mosher <me@benmosher.com> |
|
||||
| kessler | stuff | eslint-plugin-react | perpetual | material | MIT | git+https://github.com/jsx-eslint/eslint-plugin-react.git | 7.37.5 | 7.37.5 | ^7.32.2 | Yannick Croissant <yannick.croissant+npm@gmail.com> |
|
||||
| kessler | stuff | eslint-plugin-react-hooks | perpetual | material | MIT | git+https://github.com/facebook/react.git | 4.6.2 | 4.6.2 | ^4.6.0 | n/a |
|
||||
| kessler | stuff | license-report | perpetual | material | MIT | git+https://github.com/kessler/license-report.git | 6.7.2 | 6.7.2 | ^6.5.0 | Yaniv Kessler |
|
||||
| kessler | stuff | postcss | perpetual | material | MIT | git+https://github.com/postcss/postcss.git | 8.5.4 | 8.5.4 | ^8.4.24 | Andrey Sitnik <andrey@sitnik.ru> |
|
||||
| kessler | stuff | prettier | perpetual | material | MIT | git+https://github.com/prettier/prettier.git | 3.5.3 | 3.5.3 | ^3.0.3 | James Long |
|
||||
| kessler | stuff | prettier-plugin-organize-imports | perpetual | material | MIT | git+https://github.com/simonhaenisch/prettier-plugin-organize-imports.git | 3.2.4 | 3.2.4 | ^3.2.4 | Simon Haenisch (https://github.com/simonhaenisch) |
|
||||
| kessler | stuff | rimraf | perpetual | material | ISC | git://github.com/isaacs/rimraf.git | 5.0.10 | 5.0.10 | ^5.0.1 | Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/) |
|
||||
| kessler | stuff | rollup | perpetual | material | MIT | git+https://github.com/rollup/rollup.git | 4.41.1 | 4.41.1 | ^4.3.1 | Rich Harris |
|
||||
| kessler | stuff | rollup-plugin-copy | perpetual | material | MIT | git+https://github.com/vladshcherbin/rollup-plugin-copy.git | 3.5.0 | 3.5.0 | ^3.4.0 | Vlad Shcherbin <vlad.shcherbin@gmail.com> |
|
||||
| kessler | stuff | rollup-plugin-postcss | perpetual | material | MIT | git+https://github.com/egoist/rollup-plugin-postcss.git | 4.0.2 | 4.0.2 | ^4.0.2 | EGOIST <0x142857@gmail.com> |
|
||||
| kessler | stuff | rollup-plugin-react-svg | perpetual | material | MIT | git+https://github.com/boopathi/react-svg-loader.git | 3.0.3 | 3.0.3 | ^3.0.3 | boopathi |
|
||||
| kessler | stuff | rollup-plugin-version-injector | perpetual | material | ISC | git+https://github.com/djhouseknecht/rollup-plugin-version-injector.git | 1.3.3 | 1.3.3 | ^1.3.3 | David Houseknecht <david.j.houseknecht@gmail.com> |
|
||||
| kessler | stuff | sass | perpetual | material | MIT | git+https://github.com/sass/dart-sass.git | 1.89.1 | 1.89.1 | ^1.89.1 | Natalie Weizenbaum nweiz@google.com https://github.com/nex3 |
|
||||
| kessler | stuff | svg-slim | perpetual | material | MIT | git+https://github.com/benboba/svg-slim.git | 2.0.5 | 2.0.5 | ^2.0.5 | Wang Feng <benboba@gmail.com> |
|
||||
| kessler | stuff | tslib | perpetual | material | 0BSD | git+https://github.com/Microsoft/tslib.git | 2.8.1 | 2.8.1 | ^2.5.3 | Microsoft Corp. |
|
||||
| kessler | stuff | typed-scss-modules | perpetual | material | MIT | git+https://github.com/skovy/typed-scss-modules.git | 7.1.4 | 7.1.4 | ^7.1.0 | Spencer Miskoviak <smiskoviak@gmail.com> |
|
||||
| kessler | stuff | typescript | perpetual | material | Apache-2.0 | git+https://github.com/Microsoft/TypeScript.git | 5.2.2 | 5.2.2 | 5.2.2 | Microsoft Corp. |
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
import { FC } from 'react';
|
||||
import { SharedConfig } from '../../configs/shared';
|
||||
|
||||
interface CGSelectProps {
|
||||
value: number;
|
||||
disabled: boolean;
|
||||
increase: () => void;
|
||||
decrease: () => void;
|
||||
}
|
||||
|
||||
const CGSelect: FC<CGSelectProps> = ({ value, disabled, increase, decrease }) => {
|
||||
return (
|
||||
<div className="relative">
|
||||
<input
|
||||
disabled
|
||||
className="w-full rounded-lg border border-white bg-zinc-700 px-3 py-2 text-white shadow-sm focus:border-blue-600 focus:outline-none focus:ring-blue-600"
|
||||
value={value.toFixed(1)}
|
||||
/>
|
||||
<button
|
||||
disabled={disabled || value <= SharedConfig.CGLimits.min}
|
||||
className="absolute right-2 top-0 -mt-[.5px] border-t bg-zinc-700 text-white disabled:text-zinc-400"
|
||||
onClick={increase}
|
||||
>
|
||||
{/* FIXME: FONTAWESOME IN EFB */}
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="caret-up"
|
||||
className="svg-inline--fa fa-caret-up "
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512"
|
||||
style={{
|
||||
height: '1em',
|
||||
verticalAlign: '-0.125em',
|
||||
display: 'inline-block',
|
||||
boxSizing: 'content-box',
|
||||
}}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M182.6 137.4c-12.5-12.5-32.8-12.5-45.3 0l-128 128c-9.2 9.2-11.9 22.9-6.9 34.9s16.6 19.8 29.6 19.8H288c12.9 0 24.6-7.8 29.6-19.8s2.2-25.7-6.9-34.9l-128-128z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
<button
|
||||
disabled={disabled || value >= SharedConfig.CGLimits.max}
|
||||
className="absolute bottom-0 right-2 -mt-[.5px] border-b bg-zinc-700 text-white disabled:text-zinc-400"
|
||||
onClick={decrease}
|
||||
>
|
||||
{/* FIXME: FONTAWESOME IN EFB */}
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="caret-down"
|
||||
className="svg-inline--fa fa-caret-down "
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512"
|
||||
style={{
|
||||
height: '1em',
|
||||
verticalAlign: '-0.125em',
|
||||
display: 'inline-block',
|
||||
boxSizing: 'content-box',
|
||||
}}
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M137.4 374.6c12.5 12.5 32.8 12.5 45.3 0l128-128c9.2-9.2 11.9-22.9 6.9-34.9s-16.6-19.8-29.6-19.8L32 192c-12.9 0-24.6 7.8-29.6 19.8s-2.2 25.7 6.9 34.9l128 128z"
|
||||
></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CGSelect;
|
||||
294
PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx
Normal file
294
PackageSources/js-bundle/src/components/SBEntry/SBEntryPax.tsx
Normal file
@ -0,0 +1,294 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, SharedConfig } from '../../configs/shared';
|
||||
import { ImportFlightPlan } from '../../utils/TFDISBImport';
|
||||
import CGSelect from '../CGSelect/CGSelect';
|
||||
import ActionBar from '../actionbar/ActionBar';
|
||||
|
||||
interface StationEntryProps {
|
||||
unit: 'kg' | 'lbs';
|
||||
isER: boolean;
|
||||
initialPayload: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
payloadLive: PayloadPax;
|
||||
loadingState: 'preview' | 'accepted' | 'loaded';
|
||||
username: string;
|
||||
setLoadingState: (newState: StationEntryProps['loadingState']) => void;
|
||||
updateView: (payload: PayloadPax) => void;
|
||||
loadAircraft: () => void;
|
||||
}
|
||||
|
||||
const SBEntryPax: FC<StationEntryProps> = ({
|
||||
unit,
|
||||
isER,
|
||||
initialPayload,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
loadingState,
|
||||
username,
|
||||
setLoadingState,
|
||||
updateView,
|
||||
loadAircraft,
|
||||
}) => {
|
||||
const [targetZFWCG, setTargetZFWCG] = useState(SharedConfig.CGLimits.default);
|
||||
const [fuel, setFuel] = useState(
|
||||
Math.round(
|
||||
fuelLive.main1 +
|
||||
fuelLive.main1Tip +
|
||||
fuelLive.main2 +
|
||||
fuelLive.main3 +
|
||||
fuelLive.main3Tip +
|
||||
fuelLive.upperAux +
|
||||
fuelLive.lowerAux +
|
||||
fuelLive.tail +
|
||||
fuelLive.forwardAux1 +
|
||||
fuelLive.forwardAux2
|
||||
)
|
||||
);
|
||||
const [ZFW, setZFW] = useState(
|
||||
Math.round(
|
||||
PaxConfig.weights.base[unit].total +
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) +
|
||||
payloadLive.empty +
|
||||
initialPayload.business1Left +
|
||||
initialPayload.business1Center +
|
||||
initialPayload.business1Right +
|
||||
initialPayload.business2Left +
|
||||
initialPayload.business2Center +
|
||||
initialPayload.business2Right +
|
||||
initialPayload.economy1Left +
|
||||
initialPayload.economy1Center +
|
||||
initialPayload.economy1Right +
|
||||
initialPayload.economy2Left +
|
||||
initialPayload.economy2Center +
|
||||
initialPayload.economy2Right +
|
||||
initialPayload.forwardCargo +
|
||||
initialPayload.rearCargo
|
||||
)
|
||||
);
|
||||
const [SBPlan, setSBPlan] = useState<any>();
|
||||
const [SBInFlight, setSBInFlight] = useState(false);
|
||||
|
||||
const _ZFW = () => {
|
||||
if (loadingState !== 'loaded') return ZFW;
|
||||
|
||||
return Math.round(
|
||||
payloadLive.empty +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer +
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.business1Left +
|
||||
payloadLive.business1Center +
|
||||
payloadLive.business1Right +
|
||||
payloadLive.business2Left +
|
||||
payloadLive.business2Center +
|
||||
payloadLive.business2Right +
|
||||
payloadLive.economy1Left +
|
||||
payloadLive.economy1Center +
|
||||
payloadLive.economy1Right +
|
||||
payloadLive.economy2Left +
|
||||
payloadLive.economy2Center +
|
||||
payloadLive.economy2Right +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.forwardCargo +
|
||||
payloadLive.rearCargo +
|
||||
payloadLive.leftAuxPax +
|
||||
payloadLive.rightAuxPax
|
||||
);
|
||||
};
|
||||
const ZFWValid = () => {
|
||||
return _ZFW() <= PaxConfig.maxZWF[unit];
|
||||
};
|
||||
|
||||
const GW = () => {
|
||||
return fuel + _ZFW();
|
||||
};
|
||||
const GWValid = () => {
|
||||
return GW() <= (isER ? SharedConfig.maxTOW.er[unit] : SharedConfig.maxTOW.norm[unit]);
|
||||
};
|
||||
|
||||
const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => {
|
||||
if (!input) {
|
||||
setter(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < 0) setter(0);
|
||||
else if (converted > maxValue) setter(maxValue);
|
||||
else setter(converted);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSB = async () => {
|
||||
setSBInFlight(true);
|
||||
|
||||
const SBResponse = await ImportFlightPlan(username, PaxConfig, unit, isER);
|
||||
if (SBResponse.type === 'error') {
|
||||
console.error('TODO: ERROR', SBResponse.message);
|
||||
setSBInFlight(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const __ZFW = Math.round(
|
||||
PaxConfig.weights.base[unit].total +
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) +
|
||||
payloadLive.empty +
|
||||
SBResponse.message.pax * (PaxConfig.weights.pax[unit] + PaxConfig.weights.baggage[unit]) +
|
||||
SBResponse.message.cargo
|
||||
);
|
||||
const _fuel = SBResponse.message.fuel;
|
||||
|
||||
updateView(
|
||||
PaxConfig.distribute(__ZFW, targetZFWCG, payloadLive.empty, fuelLive, unit, isER, SBResponse.message.pax)
|
||||
);
|
||||
|
||||
setSBPlan(SBResponse.message);
|
||||
setZFW(__ZFW);
|
||||
setFuel(_fuel);
|
||||
setSBInFlight(false);
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setFuel((prev) =>
|
||||
prev > (isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit])
|
||||
? isER
|
||||
? SharedConfig.maxFuel.er[unit]
|
||||
: SharedConfig.maxFuel.norm[unit]
|
||||
: prev
|
||||
),
|
||||
[isER]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>Planned ZFW ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={SBPlan?.plannedZFW ?? 0}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||
<label>Planned ZFW ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={SBPlan?.plannedGW ?? 0}
|
||||
disabled
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-600 p-2 px-4">
|
||||
<label>
|
||||
Target ZFWCG ({SharedConfig.CGLimits.min} - {SharedConfig.CGLimits.max})
|
||||
</label>
|
||||
<CGSelect
|
||||
value={targetZFWCG}
|
||||
disabled={loadingState !== 'preview'}
|
||||
increase={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev + 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
decrease={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev - 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||
<label>Fuel ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||
value={fuel}
|
||||
onChange={(e) =>
|
||||
handleInput(
|
||||
e.target.value,
|
||||
isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit],
|
||||
setFuel
|
||||
)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_PAYLOAD_FUEL', 'lbs', unit === 'kg' ? fuel * 2.20462262185 : fuel);
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||
}}
|
||||
disabled={loadingState !== 'preview' || SBInFlight}
|
||||
>
|
||||
Load Fuel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} ZFW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={_ZFW()}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} GW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={GW()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ActionBar
|
||||
loadingState={loadingState}
|
||||
acceptDisabled={!GWValid() || SBInFlight}
|
||||
//TODO: Make GSX optional (accepted state for NON GSX)
|
||||
accept={() => setLoadingState('loaded')}
|
||||
reject={() => setLoadingState('preview')}
|
||||
importSB={handleSB}
|
||||
load={() => {
|
||||
setLoadingState('loaded');
|
||||
|
||||
loadAircraft();
|
||||
}}
|
||||
unload={() => {
|
||||
setLoadingState('preview');
|
||||
|
||||
PaxConfig.unload(unit, isER);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default SBEntryPax;
|
||||
@ -0,0 +1,73 @@
|
||||
import { FC } from 'react';
|
||||
|
||||
interface ActionBarProps {
|
||||
loadingState: 'preview' | 'accepted' | 'loaded';
|
||||
acceptDisabled: boolean;
|
||||
accept: () => void;
|
||||
reject: () => void;
|
||||
importSB?: () => void;
|
||||
load: () => void;
|
||||
unload: () => void;
|
||||
}
|
||||
|
||||
const ActionBar: FC<ActionBarProps> = ({ loadingState, acceptDisabled, accept, reject, importSB, load, unload }) => {
|
||||
return (
|
||||
<div className="relative flex w-full items-center justify-start gap-x-6">
|
||||
{loadingState === 'preview' && (
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={accept}
|
||||
disabled={acceptDisabled}
|
||||
>
|
||||
Accept
|
||||
</button>
|
||||
)}
|
||||
{/*TODO: Make GSX optional (accepted state for NON GSX) */}
|
||||
{loadingState === 'loaded' && (
|
||||
<button
|
||||
className="middle none center rounded-lg bg-red-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-red-500/20 transition-all hover:shadow-lg hover:shadow-red-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={reject}
|
||||
>
|
||||
Reject
|
||||
</button>
|
||||
)}
|
||||
|
||||
<div className="grow" />
|
||||
|
||||
{!!importSB && loadingState === 'preview' && (
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={importSB}
|
||||
>
|
||||
Import from SimBrief
|
||||
</button>
|
||||
)}
|
||||
{/*TODO: Make GSX optional */}
|
||||
{/*
|
||||
{loadingState === 'accepted' && (
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={load}
|
||||
>
|
||||
Load
|
||||
</button>
|
||||
)}
|
||||
{loadingState === 'loaded' && (
|
||||
<button
|
||||
className="middle none center rounded-lg bg-red-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-red-500/20 transition-all hover:shadow-lg hover:shadow-red-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={unload}
|
||||
>
|
||||
Unload
|
||||
</button>
|
||||
)}
|
||||
*/}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ActionBar;
|
||||
92
PackageSources/js-bundle/src/components/freight/Freight.tsx
Normal file
92
PackageSources/js-bundle/src/components/freight/Freight.tsx
Normal file
@ -0,0 +1,92 @@
|
||||
import { FC, useState } from 'react';
|
||||
import { PayloadFreight } from '../../configs/freighter';
|
||||
import { initialPayload, SharedConfig } from '../../configs/shared';
|
||||
import Profile from '../profile/Profile';
|
||||
import Tabbar from '../tabbar/Tabbar';
|
||||
|
||||
interface FreightProps {
|
||||
isER: boolean;
|
||||
unit: 'kg' | 'lbs';
|
||||
OEW: number;
|
||||
CGs: [number, number];
|
||||
}
|
||||
|
||||
const Freight: FC<FreightProps> = ({ isER, unit, OEW, CGs }) => {
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const [payload, setPayload] = useState<PayloadFreight>(initialPayload);
|
||||
const [inPreview, setInPreview] = useState(true);
|
||||
|
||||
const upper1 = () => {
|
||||
return Math.round(payload.upper1Left + payload.upper1Right);
|
||||
};
|
||||
const upper2 = () => {
|
||||
return Math.round(payload.upper2Left + payload.upper2Right);
|
||||
};
|
||||
const upper3 = () => {
|
||||
return Math.round(payload.upper3Left + payload.upper3Right);
|
||||
};
|
||||
const upper4 = () => {
|
||||
return Math.round(payload.upper4Left + payload.upper4Right);
|
||||
};
|
||||
const lower1 = () => {
|
||||
return Math.round(payload.lowerForward);
|
||||
};
|
||||
const lower2 = () => {
|
||||
return Math.round(payload.lowerRear);
|
||||
};
|
||||
const _OEW = () => {
|
||||
return Math.round(OEW + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 1));
|
||||
};
|
||||
const crew = () => {
|
||||
return Math.round(payload.pilot + payload.firstOfficer + payload.engineer);
|
||||
};
|
||||
const cgs = (): [string, string] => {
|
||||
return [CGs[0].toFixed(1), CGs[1].toFixed(1)];
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Profile
|
||||
type="F"
|
||||
isER={isER}
|
||||
upper1={`${upper1()}`}
|
||||
upper2={`${upper2()}`}
|
||||
upper3={`${upper3()}`}
|
||||
upper4={`${upper4()}`}
|
||||
lower1={`${lower1()}`}
|
||||
lower2={`${lower2()}`}
|
||||
OEW={`${_OEW()}`}
|
||||
crew={`${crew()}`}
|
||||
unit={unit.toUpperCase()}
|
||||
inPreview={inPreview}
|
||||
CGs={cgs()}
|
||||
/>
|
||||
<Tabbar tabs={['Simbrief', 'ZFW', 'Cargo']} selectedTab={selectedTab} setSelectedTab={setSelectedTab} />
|
||||
|
||||
<div className="relative flex w-full items-center justify-start gap-x-6">
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
console.log('TODO: SET PAYLOAD IN SIM');
|
||||
setInPreview(false);
|
||||
}}
|
||||
>
|
||||
Load
|
||||
</button>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-red-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-red-500/20 transition-all hover:shadow-lg hover:shadow-red-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
console.log('TODO: CLEAR PAYLOAD IN SIM');
|
||||
setInPreview(true);
|
||||
}}
|
||||
>
|
||||
Unload
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Freight;
|
||||
235
PackageSources/js-bundle/src/components/pax/Pax.tsx
Normal file
235
PackageSources/js-bundle/src/components/pax/Pax.tsx
Normal file
@ -0,0 +1,235 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, initialPayload, SharedConfig } from '../../configs/shared';
|
||||
import Profile from '../profile/Profile';
|
||||
import SBEntryPax from '../SBEntry/SBEntryPax';
|
||||
import StationEntryPax from '../stationEntry/StationEntryPax';
|
||||
import Tabbar from '../tabbar/Tabbar';
|
||||
import ZFWEntryPax from '../ZFWEntry/ZFWEntryPax';
|
||||
|
||||
interface PaxProps {
|
||||
isER: boolean;
|
||||
unit: 'kg' | 'lbs';
|
||||
CGs: [number, number];
|
||||
payloadLive: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
username?: string;
|
||||
GSXPaxNum: number;
|
||||
GSXCargoPercent: number;
|
||||
GSXState: 'boarding' | 'deboarding' | 'idle';
|
||||
}
|
||||
|
||||
const Pax: FC<PaxProps> = ({
|
||||
isER,
|
||||
unit,
|
||||
CGs,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
username,
|
||||
GSXPaxNum,
|
||||
GSXCargoPercent,
|
||||
GSXState,
|
||||
}) => {
|
||||
const [selectedTab, setSelectedTab] = useState(0);
|
||||
const [payload, setPayload] = useState<PayloadPax>(initialPayload);
|
||||
const [loadingState, setLoadingState] = useState<'preview' | 'accepted' | 'loaded'>('preview');
|
||||
|
||||
const upper1 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.business1Left + payload.business1Center + payload.business1Right, unit);
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.business1Left + payloadLive.business1Center + payloadLive.business1Right,
|
||||
unit
|
||||
);
|
||||
};
|
||||
const upper2 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.business2Left + payload.business2Center + payload.business2Right, unit);
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.business2Left + payloadLive.business2Center + payloadLive.business2Right,
|
||||
unit
|
||||
);
|
||||
};
|
||||
const upper3 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.economy1Left + payload.economy1Center + payload.economy1Right, unit);
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.economy1Left + payloadLive.economy1Center + payloadLive.economy1Right,
|
||||
unit
|
||||
);
|
||||
};
|
||||
const upper4 = (overrideState: 'preview' | 'accepted' | 'loaded' = loadingState) => {
|
||||
if (overrideState !== 'loaded')
|
||||
return PaxConfig.weightToPax(payload.economy2Left + payload.economy2Center + payload.economy2Right, unit);
|
||||
|
||||
return PaxConfig.weightToPax(
|
||||
payloadLive.economy2Left + payloadLive.economy2Center + payloadLive.economy2Right,
|
||||
unit
|
||||
);
|
||||
};
|
||||
const lower1 = () => {
|
||||
if (loadingState !== 'loaded') return Math.round(payload.forwardCargo);
|
||||
|
||||
return Math.round(payloadLive.forwardCargo);
|
||||
};
|
||||
const lower2 = () => {
|
||||
if (loadingState !== 'loaded') return Math.round(payload.rearCargo);
|
||||
|
||||
return Math.round(payloadLive.rearCargo);
|
||||
};
|
||||
const _OEW = () => {
|
||||
if (loadingState !== 'loaded')
|
||||
return Math.round(payloadLive.empty + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 1));
|
||||
|
||||
return Math.round(payloadLive.empty + payloadLive.leftAuxPax + payloadLive.rightAuxPax);
|
||||
};
|
||||
const crew = () => {
|
||||
if (loadingState !== 'loaded') return PaxConfig.weights.base[unit].total;
|
||||
|
||||
return Math.round(
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer
|
||||
);
|
||||
};
|
||||
|
||||
const _CGs = (): [string, boolean, string, boolean] => {
|
||||
if (loadingState !== 'loaded') {
|
||||
const __CGs = PaxConfig.calculateCGs(
|
||||
{
|
||||
...payload,
|
||||
empty: payloadLive.empty,
|
||||
cabinCrewFront: PaxConfig.weights.base[unit].cabinCrewFront,
|
||||
cabinCrewRear: PaxConfig.weights.base[unit].cabinCrewRear,
|
||||
pilot: PaxConfig.weights.base[unit].pilot,
|
||||
firstOfficer: PaxConfig.weights.base[unit].firstOfficer,
|
||||
engineer: PaxConfig.weights.base[unit].engineer,
|
||||
leftAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
rightAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
},
|
||||
fuelLive
|
||||
);
|
||||
return [
|
||||
__CGs[0].toFixed(1),
|
||||
__CGs[0] < SharedConfig.CGLimits.min || __CGs[0] > SharedConfig.CGLimits.max,
|
||||
__CGs[1].toFixed(1),
|
||||
__CGs[1] < SharedConfig.CGLimits.min || __CGs[1] > SharedConfig.CGLimits.max,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
CGs[0].toFixed(1),
|
||||
CGs[0] < SharedConfig.CGLimits.min || CGs[0] > SharedConfig.CGLimits.max,
|
||||
CGs[1].toFixed(1),
|
||||
CGs[1] < SharedConfig.CGLimits.min || CGs[1] > SharedConfig.CGLimits.max,
|
||||
];
|
||||
};
|
||||
|
||||
//TODO: Make GSX optional
|
||||
useEffect(() => {
|
||||
if (GSXState === 'idle') return;
|
||||
|
||||
PaxConfig.setWeightsProgressive(
|
||||
payload,
|
||||
GSXState === 'boarding' ? GSXPaxNum : payload.paxCount.total - GSXPaxNum,
|
||||
GSXCargoPercent,
|
||||
unit
|
||||
);
|
||||
}, [GSXPaxNum, GSXCargoPercent, GSXState]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Profile
|
||||
type="PAX"
|
||||
isER={isER}
|
||||
upper1={`${upper1()}`}
|
||||
upper1max={loadingState === 'loaded' ? `${upper1('preview')}` : `${PaxConfig.stationMax.business1}`}
|
||||
upper2={`${upper2()}`}
|
||||
upper2max={loadingState === 'loaded' ? `${upper2('preview')}` : `${PaxConfig.stationMax.business2}`}
|
||||
upper3={`${upper3()}`}
|
||||
upper3max={loadingState === 'loaded' ? `${upper3('preview')}` : `${PaxConfig.stationMax.economy1}`}
|
||||
upper4={`${upper4()}`}
|
||||
upper4max={loadingState === 'loaded' ? `${upper4('preview')}` : `${PaxConfig.stationMax.economy2}`}
|
||||
lower1={`${lower1()}`}
|
||||
lower2={`${lower2()}`}
|
||||
OEW={`${_OEW()}`}
|
||||
crew={`${crew()}`}
|
||||
unit={unit.toUpperCase()}
|
||||
inPreview={loadingState !== 'loaded'}
|
||||
CGs={_CGs()}
|
||||
/>
|
||||
<Tabbar
|
||||
tabs={
|
||||
username ? ['Simbrief', 'ZFW', 'Passengers & Cargo', 'Options'] : ['ZFW', 'Passengers & Cargo', 'Options']
|
||||
}
|
||||
selectedTab={selectedTab}
|
||||
setSelectedTab={setSelectedTab}
|
||||
/>
|
||||
|
||||
{username && selectedTab === 0 && (
|
||||
<SBEntryPax
|
||||
unit={unit}
|
||||
isER={isER}
|
||||
initialPayload={payload}
|
||||
fuelLive={fuelLive}
|
||||
payloadLive={payloadLive}
|
||||
loadingState={loadingState}
|
||||
username={username}
|
||||
setLoadingState={setLoadingState}
|
||||
updateView={(_payload) => {
|
||||
setPayload(_payload);
|
||||
}}
|
||||
loadAircraft={() => {
|
||||
PaxConfig.setBaseWeight(unit, isER);
|
||||
PaxConfig.setWeights(payload, unit);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{((username && selectedTab === 1) || (!username && selectedTab === 0)) && (
|
||||
<ZFWEntryPax
|
||||
unit={unit}
|
||||
isER={isER}
|
||||
initialPayload={payload}
|
||||
fuelLive={fuelLive}
|
||||
payloadLive={payloadLive}
|
||||
loadingState={loadingState}
|
||||
setLoadingState={setLoadingState}
|
||||
updateView={(_payload) => {
|
||||
setPayload(_payload);
|
||||
}}
|
||||
loadAircraft={() => {
|
||||
PaxConfig.setBaseWeight(unit, isER);
|
||||
PaxConfig.setWeights(payload, unit);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
{((username && selectedTab === 2) || (!username && selectedTab === 1)) && (
|
||||
<StationEntryPax
|
||||
unit={unit}
|
||||
isER={isER}
|
||||
initialPayload={payload}
|
||||
fuelLive={fuelLive}
|
||||
payloadLive={payloadLive}
|
||||
loadingState={loadingState}
|
||||
setLoadingState={setLoadingState}
|
||||
updateView={(_payload) => {
|
||||
setPayload(_payload);
|
||||
}}
|
||||
loadAircraft={() => {
|
||||
PaxConfig.setBaseWeight(unit, isER);
|
||||
PaxConfig.setWeights(payload, unit);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Pax;
|
||||
@ -0,0 +1,14 @@
|
||||
.stroke-zinc-600 {
|
||||
--tw-bg-opacity: 1;
|
||||
stroke: rgba(82, 82, 91, var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.fill-neutral-500 {
|
||||
--tw-text-opacity: 1;
|
||||
fill: rgba(115, 115, 115, var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.fill-red-500 {
|
||||
--tw-bg-opacity: 1;
|
||||
fill: rgba(239, 68, 68, var(--tw-bg-opacity));
|
||||
}
|
||||
143
PackageSources/js-bundle/src/components/profile/Profile.tsx
Normal file
143
PackageSources/js-bundle/src/components/profile/Profile.tsx
Normal file
@ -0,0 +1,143 @@
|
||||
import { FC } from 'react';
|
||||
|
||||
import styles from './Profile.module.scss';
|
||||
|
||||
interface ProfileProps {
|
||||
type: 'F' | 'PAX';
|
||||
isER: boolean;
|
||||
upper1: string;
|
||||
upper1max?: string;
|
||||
upper2: string;
|
||||
upper2max?: string;
|
||||
upper3: string;
|
||||
upper3max?: string;
|
||||
upper4: string;
|
||||
upper4max?: string;
|
||||
lower1: string;
|
||||
lower2: string;
|
||||
OEW: string;
|
||||
crew: string;
|
||||
CGs: [string, boolean, string, boolean];
|
||||
unit: string;
|
||||
inPreview: boolean;
|
||||
}
|
||||
|
||||
const Profile: FC<ProfileProps> = ({
|
||||
type,
|
||||
isER,
|
||||
upper1,
|
||||
upper1max,
|
||||
upper2,
|
||||
upper2max,
|
||||
upper3,
|
||||
upper3max,
|
||||
upper4,
|
||||
upper4max,
|
||||
lower1,
|
||||
lower2,
|
||||
OEW,
|
||||
crew,
|
||||
CGs,
|
||||
unit,
|
||||
inPreview,
|
||||
}) => {
|
||||
const previewClass = inPreview ? styles['fill-neutral-500'] : undefined;
|
||||
const ZFWCGClass = CGs[1] ? styles['fill-red-500'] : previewClass;
|
||||
const TOCGClass = CGs[3] ? styles['fill-red-500'] : previewClass;
|
||||
|
||||
return (
|
||||
<svg viewBox="0 0 4002 780" version="1.1" xmlns="http://www.w3.org/2000/svg" className="mb-4">
|
||||
<path
|
||||
style={{
|
||||
fill: 'none',
|
||||
strokeWidth: 4,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'miter',
|
||||
}}
|
||||
className={styles['stroke-zinc-600']}
|
||||
d="m 1748.2487,624.45529 v 83.5816 z m 653.1368,98.40409 v 43.08593 z"
|
||||
transform="matrix(1.0068517,0,0,1.0069072,-24.265193,-12.003831)"
|
||||
/>
|
||||
<path
|
||||
style={{
|
||||
fill: 'none',
|
||||
stroke: 'white',
|
||||
strokeWidth: 4,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'round',
|
||||
}}
|
||||
d="m 119.50997,573.71703 h 128.0729 v 29.07865 h 119.1481 M 1922.9882,624.6584 V 378.08519 Z M 1143.9838,378.54476 v 246.57126 z m 1556.0004,1.0854 3e-4,245.70686 0.01,-245.70686 z M 119.47872,507.3493 V 686.42638 Z M 681.8277,784.08016 C 550.68986,778.56008 459.37243,767.83734 325.24777,742.2102 247.12441,727.28325 163.85922,704.53832 115.68874,684.96689 65.272866,664.48337 30.640554,635.98924 26.748642,611.79065 c -3.768329,-23.42962 7.455828,-38.32595 50.49813,-67.01953 6.041298,-4.02691 12.708263,-9.27073 14.816577,-11.65295 2.108023,-2.3822 4.524361,-4.48001 4.524361,-4.48001 0,0 45.05507,-44.22564 69.74451,-58.59581 72.48275,-42.18783 238.75927,-76.44031 425.63149,-87.67895 14.00372,-0.84197 33.99829,-2.07064 44.43261,-2.72959 26.21726,-1.65646 1973.24248,-2.45294 2062.36198,-0.84445 156.7316,2.82998 269.5005,7.74134 530.5511,23.10724 47.1495,2.7752 85.8534,4.90642 86.012,4.73564 0.6463,-0.69433 3.18,-46.35302 2.6116,-47.00235 -0.3392,-0.38606 -8.4798,-1.63074 -18.0917,-2.7653 -35.3422,-4.17401 -67.399,-11.82474 -77.0779,-18.39697 -3.9158,-2.65808 -3.9645,-3.95085 -1.9416,-51.11949 2.108,-49.16104 3.1187,-81.48815 3.1285,-100.00521 0,-21.77363 -0.1657,-21.37816 11.1206,-24.94772 37.4058,-11.83133 117.8811,-11.06942 171.1122,1.62031 15.227,3.62986 19.589,3.51496 35.5372,-0.93615 21.7001,-6.05753 21.0601,-5.51568 96.6373,-82.052719 33.1386,-33.558758 68.757,-66.037569 68.757,-66.037569 0,0 83.3796,-1.079949 169.2388,-1.079949 136.9782,0 171.6165,0.253341 171.2179,1.25017 -4.4107,11.004128 -56.5812,125.499597 -58.6917,128.808777 -4.6101,7.22481 -3.2139,7.88313 16.7587,7.90201 9.0622,0.008 22.5343,1.10293 37.2289,3.0234 4.1187,0.5386 15.3536,1.65343 24.9606,2.47749 9.6122,0.82422 19.8325,1.75756 22.7175,2.07418 5.0681,0.55713 9.0514,198.40717 3.9934,198.38178 -3.6049,-0.0227 -31.7008,3.23584 -34.6991,4.01865 -1.9198,0.50162 -6.9752,1.19264 -11.2312,1.53478 -7.7386,0.62215 -7.7386,0.62215 -7.7386,8.4184 0,8.93284 0.045,8.97847 9.985,9.03089 7.595,0.034 9.8124,1.63453 3.4137,2.45321 -2.7018,0.34575 -6.0356,0.83238 -7.4075,1.08266 -1.3721,0.25018 -13.4624,0.89408 -26.8658,1.43238 -13.4009,0.53851 -28.9024,1.4418 -34.4462,2.00812 -15.6072,1.59497 -41.7208,3.01042 -55.6346,3.01554 -20.6343,0.008 -19.0304,-1.48851 -18.6619,17.4164 0.3714,19.01843 2.3134,23.86211 11.5516,28.7958 5.5848,2.98376 0.3035,2.54795 88.3399,7.28999 84.7141,4.56302 75.158,-2.81091 75.158,57.97778 0,54.09028 0.038,53.96894 -18.7912,59.84504 -20.4081,6.36957 -118.4497,34.30825 -182.9044,52.12181 -74.4105,20.56545 -152.6321,42.51798 -160.2541,44.9738 -10.5871,3.41069 -57.1162,16.38817 -105.4333,29.40502 -184.6228,49.73829 -402.0471,89.78228 -516.1218,95.05681 -19.1654,0.88577 -2300.07154,1.25614 -2320.9699,0.37695 z m 1714.3911,-15.93638 c 14.3101,-1.72862 35.0046,-5.59211 45.932,-8.57466 47.3734,-12.93067 34.3571,-20.57346 -70.3941,-41.33854 -9.3343,-1.85054 -21.9156,-4.53045 -27.9568,-5.955 -119.2244,-28.11802 -135.9358,-31.16723 -227.3866,-41.48667 -32.4779,-3.66487 -84.0049,-11.3955 -126.5748,-18.9901 -77.6003,-13.84405 -129.5471,-21.9553 -156.762,-24.47858 -178.2016,-16.52165 -260.2497,38.68714 -109.1224,73.42801 7.2586,1.66798 18.9422,5.29576 25.9629,8.06195 39.3007,15.48166 111.0211,26.35086 233.4296,35.37682 97.5092,7.1897 247.1876,10.13705 247.9345,4.88196 0.6641,-4.66361 1.511,-4.79998 36.7154,-5.88569 22.9808,-0.70847 26.3783,-0.21481 26.3783,3.83836 0,2.5877 2.9594,14.02473 3.8762,14.97665 0.4007,0.41452 15.6685,2.27843 33.9288,4.14116 18.264,1.86268 33.4272,3.60903 33.698,3.88056 0.7657,0.76635 16.5438,-0.20912 30.341,-1.87623 z m -2029.36746,-359.3222 -0.0248,215.97654 1275.64716,-4.1e-4 h 1275.1949 l 132.9522,-2.46652 132.952,-2.4665 147.9241,-11.4452 147.9243,-11.4452 1.0236,-90.88061 1.0235,-90.88061 -83.3015,-4.35422 -83.3014,-4.35424 m -2614.52231,217.81122 -5e-5,159.11801 z M 1748.1434,708.5565 v 75.45385 z m 1663.0399,-106.30033 -1e-4,113.31756 z m -1009.9445,22.54108 v 99.39317 z m -4e-4,143.38207 v 15.78331 z"
|
||||
transform="matrix(1.0068517,0,0,1.0069072,-24.265193,-12.003831)"
|
||||
/>
|
||||
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="725.61609" y="591.34473" textAnchor="middle">
|
||||
<tspan className={previewClass}>{upper1}</tspan>
|
||||
{upper1max && <tspan>/{upper1max}</tspan>}
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1509.024" y="591.34473" textAnchor="middle">
|
||||
<tspan className={previewClass}>{upper2}</tspan>
|
||||
{upper2max && <tspan>/{upper2max}</tspan>}
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="2292.3511" y="591.34473" textAnchor="middle">
|
||||
<tspan className={previewClass}>{upper3}</tspan>
|
||||
{upper3max && <tspan>/{upper3max}</tspan>}
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="3075.8955" y="591.34473" textAnchor="middle">
|
||||
<tspan className={previewClass}>{upper4}</tspan>
|
||||
{upper4max && <tspan>/{upper4max}</tspan>}
|
||||
</text>
|
||||
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1197.6641" y="754.35504" textAnchor="middle">
|
||||
<tspan className={previewClass}>{lower1}</tspan>
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="2891.1475" y="754.35504" textAnchor="middle">
|
||||
<tspan className={previewClass}>{lower2}</tspan>
|
||||
</text>
|
||||
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="0" y="280.10175">
|
||||
{type === 'F' ? 'Pilots:' : 'Pilots & FAs:'}
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1476.2501" y="280.10175" textAnchor="end">
|
||||
<tspan className={previewClass}>{crew}</tspan>
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="0" y="130.625">
|
||||
OEW:
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1476.2501" y="130.625" textAnchor="end">
|
||||
{OEW}
|
||||
</text>
|
||||
|
||||
<text style={{ fill: 'white', fontSize: '100px' }} x="4002" y="778.24402" textAnchor="end">
|
||||
<tspan style={{ fontSize: '70px' }}>all in </tspan>
|
||||
<tspan>{unit}</tspan>
|
||||
</text>
|
||||
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1730.4194" y="142.15625">
|
||||
ZFWCG:
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="2540.771" y="142.15625">
|
||||
<tspan className={ZFWCGClass}>{CGs[0]}</tspan>
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="1730.4194" y="288.875">
|
||||
TOCG:
|
||||
</text>
|
||||
<text style={{ fill: 'white', fontSize: '160px' }} x="2540.771" y="288.875">
|
||||
<tspan className={TOCGClass}>{CGs[2]}</tspan>
|
||||
</text>
|
||||
|
||||
<path
|
||||
style={{
|
||||
fill: 'none',
|
||||
stroke: 'white',
|
||||
strokeWidth: 8,
|
||||
strokeLinecap: 'butt',
|
||||
strokeLinejoin: 'round',
|
||||
opacity: isER ? 1 : 0,
|
||||
}}
|
||||
d="m 3616.1269,203.67131 -115.4682,116.32951 h 76.6132 l 13.6484,-13.75016 h -61.1499 l 42.8836,-43.20365 h 61.1499 l 13.6485,-13.75016 h -61.1499 l 31.6393,-31.87538 h 61.1499 l 13.6484,-13.75016 z m 101.1357,0 -115.4682,116.32951 h 15.4631 l 45.9082,-46.25055 h 21.7891 l -7.0158,46.25055 h 20.0709 l 6.7491,-50.85999 c 10.2365,-2.8646 20.2552,-7.10948 30.0559,-12.73452 9.8522,-5.67714 18.9402,-12.70852 27.2636,-21.09401 6.1521,-6.19797 10.0211,-11.30222 11.6068,-15.31268 1.6896,-4.06255 1.7441,-7.42197 0.1635,-10.07824 -1.4223,-2.34378 -4.0367,-3.95839 -7.8438,-4.84382 -3.7552,-0.93749 -9.1472,-1.40626 -16.176,-1.40625 z m 2.2801,13.2814 h 18.1967 c 4.165,0 7.4735,0.31252 9.9248,0.93751 2.5032,0.57292 4.1244,1.61462 4.8641,3.12503 0.9495,1.77087 0.7045,3.9584 -0.735,6.56258 -1.3356,2.55212 -3.6579,5.49487 -6.9666,8.82824 -4.3426,4.37505 -8.5084,7.9949 -12.4972,10.8595 -3.8849,2.81253 -8.0847,5.31258 -12.5989,7.50009 -4.8776,2.34378 -9.5781,3.95838 -14.1015,4.84381 -4.4716,0.83333 -9.1546,1.25002 -14.0487,1.25002 h -15.6194 z"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Profile;
|
||||
@ -0,0 +1,309 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, SharedConfig } from '../../configs/shared';
|
||||
import ActionBar from '../actionbar/ActionBar';
|
||||
|
||||
interface StationEntryProps {
|
||||
unit: 'kg' | 'lbs';
|
||||
isER: boolean;
|
||||
initialPayload: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
payloadLive: PayloadPax;
|
||||
loadingState: 'preview' | 'accepted' | 'loaded';
|
||||
setLoadingState: (newState: StationEntryProps['loadingState']) => void;
|
||||
updateView: (payload: PayloadPax) => void;
|
||||
loadAircraft: () => void;
|
||||
}
|
||||
|
||||
const StationEntryPax: FC<StationEntryProps> = ({
|
||||
unit,
|
||||
isER,
|
||||
initialPayload,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
loadingState,
|
||||
setLoadingState,
|
||||
updateView,
|
||||
loadAircraft,
|
||||
}) => {
|
||||
const [business1, setBusiness1] = useState(
|
||||
PaxConfig.weightToPax(
|
||||
initialPayload.business1Left + initialPayload.business1Center + initialPayload.business1Right,
|
||||
unit
|
||||
)
|
||||
);
|
||||
const [business2, setBusiness2] = useState(
|
||||
PaxConfig.weightToPax(
|
||||
initialPayload.business2Left + initialPayload.business2Center + initialPayload.business2Right,
|
||||
unit
|
||||
)
|
||||
);
|
||||
const [economy1, setEconomy1] = useState(
|
||||
PaxConfig.weightToPax(
|
||||
initialPayload.economy1Left + initialPayload.economy1Center + initialPayload.economy1Right,
|
||||
unit
|
||||
)
|
||||
);
|
||||
const [economy2, setEconomy2] = useState(
|
||||
PaxConfig.weightToPax(
|
||||
initialPayload.economy2Left + initialPayload.economy2Center + initialPayload.economy2Right,
|
||||
unit
|
||||
)
|
||||
);
|
||||
const [forwardCargo, setForwardCargo] = useState(initialPayload.forwardCargo);
|
||||
const [rearCargo, setRearCargo] = useState(initialPayload.rearCargo);
|
||||
const [fuel, setFuel] = useState(
|
||||
Math.round(
|
||||
fuelLive.main1 +
|
||||
fuelLive.main1Tip +
|
||||
fuelLive.main2 +
|
||||
fuelLive.main3 +
|
||||
fuelLive.main3Tip +
|
||||
fuelLive.upperAux +
|
||||
fuelLive.lowerAux +
|
||||
fuelLive.tail +
|
||||
fuelLive.forwardAux1 +
|
||||
fuelLive.forwardAux2
|
||||
)
|
||||
);
|
||||
|
||||
const ZFW = () => {
|
||||
if (loadingState !== 'loaded')
|
||||
return Math.round(
|
||||
(business1 + business2 + economy1 + economy2) * PaxConfig.weights.pax[unit] +
|
||||
forwardCargo +
|
||||
rearCargo +
|
||||
PaxConfig.weights.base[unit].total +
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) +
|
||||
payloadLive.empty
|
||||
);
|
||||
|
||||
return Math.round(
|
||||
payloadLive.empty +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer +
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.business1Left +
|
||||
payloadLive.business1Center +
|
||||
payloadLive.business1Right +
|
||||
payloadLive.business2Left +
|
||||
payloadLive.business2Center +
|
||||
payloadLive.business2Right +
|
||||
payloadLive.economy1Left +
|
||||
payloadLive.economy1Center +
|
||||
payloadLive.economy1Right +
|
||||
payloadLive.economy2Left +
|
||||
payloadLive.economy2Center +
|
||||
payloadLive.economy2Right +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.forwardCargo +
|
||||
payloadLive.rearCargo +
|
||||
payloadLive.leftAuxPax +
|
||||
payloadLive.rightAuxPax
|
||||
);
|
||||
};
|
||||
const ZFWValid = () => {
|
||||
return ZFW() <= PaxConfig.maxZWF[unit];
|
||||
};
|
||||
|
||||
const GW = () => {
|
||||
return fuel + ZFW();
|
||||
};
|
||||
const GWValid = () => {
|
||||
return GW() <= (isER ? SharedConfig.maxTOW.er[unit] : SharedConfig.maxTOW.norm[unit]);
|
||||
};
|
||||
|
||||
const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => {
|
||||
if (!input) {
|
||||
setter(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < 0) setter(0);
|
||||
else if (converted > maxValue) setter(maxValue);
|
||||
else setter(converted);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => _updateView(), [business1, business2, economy1, economy2, forwardCargo, rearCargo]);
|
||||
useEffect(
|
||||
() =>
|
||||
setFuel((prev) =>
|
||||
prev > (isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit])
|
||||
? isER
|
||||
? SharedConfig.maxFuel.er[unit]
|
||||
: SharedConfig.maxFuel.norm[unit]
|
||||
: prev
|
||||
),
|
||||
[isER]
|
||||
);
|
||||
|
||||
const _updateView = () => {
|
||||
const payload = PaxConfig.generateDistribution(
|
||||
payloadLive.empty,
|
||||
business1,
|
||||
business2,
|
||||
economy1,
|
||||
economy2,
|
||||
forwardCargo,
|
||||
rearCargo,
|
||||
unit,
|
||||
isER
|
||||
);
|
||||
|
||||
updateView(payload);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>Business</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={business1}
|
||||
onChange={(e) => handleInput(e.target.value, PaxConfig.stationMax.business1, setBusiness1)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||
<label>Premium Economy</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={business2}
|
||||
onChange={(e) => handleInput(e.target.value, PaxConfig.stationMax.business2, setBusiness2)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
|
||||
<label>Forward Economy</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={economy1}
|
||||
onChange={(e) => handleInput(e.target.value, PaxConfig.stationMax.economy1, setEconomy1)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between bg-zinc-700 p-2 px-4">
|
||||
<label>Aft Economy</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={economy2}
|
||||
onChange={(e) => handleInput(e.target.value, PaxConfig.stationMax.economy2, setEconomy2)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between bg-zinc-600 p-2 px-4">
|
||||
<label>Forward Cargo ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={forwardCargo}
|
||||
onChange={(e) => handleInput(e.target.value, SharedConfig.stationMax.forward[unit], setForwardCargo)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>Aft Cargo ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={rearCargo}
|
||||
onChange={(e) => handleInput(e.target.value, SharedConfig.stationMax.rear[unit], setRearCargo)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||
<label>Fuel ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||
value={fuel}
|
||||
onChange={(e) =>
|
||||
handleInput(
|
||||
e.target.value,
|
||||
isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit],
|
||||
setFuel
|
||||
)
|
||||
}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_PAYLOAD_FUEL', 'lbs', unit === 'kg' ? fuel * 2.20462262185 : fuel);
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||
}}
|
||||
disabled={loadingState !== 'preview'}
|
||||
>
|
||||
Load Fuel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} ZFW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={ZFW()}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} GW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={GW()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ActionBar
|
||||
loadingState={loadingState}
|
||||
acceptDisabled={!ZFWValid() || !GWValid()}
|
||||
accept={() => setLoadingState('accepted')}
|
||||
reject={() => setLoadingState('preview')}
|
||||
load={() => {
|
||||
setLoadingState('loaded');
|
||||
|
||||
loadAircraft();
|
||||
}}
|
||||
unload={() => {
|
||||
setLoadingState('preview');
|
||||
|
||||
PaxConfig.unload(unit, isER);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default StationEntryPax;
|
||||
27
PackageSources/js-bundle/src/components/tabbar/Tabbar.tsx
Normal file
27
PackageSources/js-bundle/src/components/tabbar/Tabbar.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { FC } from 'react';
|
||||
|
||||
interface TabbarProps {
|
||||
tabs: string[];
|
||||
selectedTab: number;
|
||||
setSelectedTab: (tab: number) => void;
|
||||
}
|
||||
|
||||
const Tabbar: FC<TabbarProps> = ({ tabs, selectedTab, setSelectedTab }) => {
|
||||
return (
|
||||
<ul className="mb-4 flex list-none flex-row flex-wrap border-b-0 pl-0">
|
||||
{tabs.map((tab, i) => (
|
||||
<li key={`${tab}-${i}`}>
|
||||
<button
|
||||
key={i}
|
||||
className={`${selectedTab === i ? 'text-white underline' : 'text-neutral-500'} my-2 block border-x-0 border-b-2 border-t-0 border-slate-100 bg-zinc-900 px-7 text-sm font-medium uppercase`}
|
||||
onClick={() => setSelectedTab(i)}
|
||||
>
|
||||
{tab}
|
||||
</button>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
};
|
||||
|
||||
export default Tabbar;
|
||||
284
PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx
Normal file
284
PackageSources/js-bundle/src/components/zfwEntry/ZFWEntryPax.tsx
Normal file
@ -0,0 +1,284 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { PaxConfig, PayloadPax } from '../../configs/pax';
|
||||
import { Fuel, SharedConfig } from '../../configs/shared';
|
||||
import CGSelect from '../CGSelect/CGSelect';
|
||||
import ActionBar from '../actionbar/ActionBar';
|
||||
|
||||
interface StationEntryProps {
|
||||
unit: 'kg' | 'lbs';
|
||||
isER: boolean;
|
||||
initialPayload: PayloadPax;
|
||||
fuelLive: Fuel;
|
||||
payloadLive: PayloadPax;
|
||||
loadingState: 'preview' | 'accepted' | 'loaded';
|
||||
setLoadingState: (newState: StationEntryProps['loadingState']) => void;
|
||||
updateView: (payload: PayloadPax) => void;
|
||||
loadAircraft: () => void;
|
||||
}
|
||||
|
||||
const ZFWEntryPax: FC<StationEntryProps> = ({
|
||||
unit,
|
||||
isER,
|
||||
initialPayload,
|
||||
fuelLive,
|
||||
payloadLive,
|
||||
loadingState,
|
||||
setLoadingState,
|
||||
updateView,
|
||||
loadAircraft,
|
||||
}) => {
|
||||
const [targetZFWCG, setTargetZFWCG] = useState(SharedConfig.CGLimits.default);
|
||||
const [fuel, setFuel] = useState(
|
||||
Math.round(
|
||||
fuelLive.main1 +
|
||||
fuelLive.main1Tip +
|
||||
fuelLive.main2 +
|
||||
fuelLive.main3 +
|
||||
fuelLive.main3Tip +
|
||||
fuelLive.upperAux +
|
||||
fuelLive.lowerAux +
|
||||
fuelLive.tail +
|
||||
fuelLive.forwardAux1 +
|
||||
fuelLive.forwardAux2
|
||||
)
|
||||
);
|
||||
const [ZFW, setZFW] = useState(
|
||||
Math.round(
|
||||
PaxConfig.weights.base[unit].total +
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) +
|
||||
payloadLive.empty +
|
||||
initialPayload.business1Left +
|
||||
initialPayload.business1Center +
|
||||
initialPayload.business1Right +
|
||||
initialPayload.business2Left +
|
||||
initialPayload.business2Center +
|
||||
initialPayload.business2Right +
|
||||
initialPayload.economy1Left +
|
||||
initialPayload.economy1Center +
|
||||
initialPayload.economy1Right +
|
||||
initialPayload.economy2Left +
|
||||
initialPayload.economy2Center +
|
||||
initialPayload.economy2Right +
|
||||
initialPayload.forwardCargo +
|
||||
initialPayload.rearCargo
|
||||
)
|
||||
);
|
||||
|
||||
const _ZFW = () => {
|
||||
if (loadingState !== 'loaded') return ZFW;
|
||||
|
||||
return Math.round(
|
||||
payloadLive.empty +
|
||||
payloadLive.pilot +
|
||||
payloadLive.firstOfficer +
|
||||
payloadLive.engineer +
|
||||
payloadLive.cabinCrewFront +
|
||||
payloadLive.business1Left +
|
||||
payloadLive.business1Center +
|
||||
payloadLive.business1Right +
|
||||
payloadLive.business2Left +
|
||||
payloadLive.business2Center +
|
||||
payloadLive.business2Right +
|
||||
payloadLive.economy1Left +
|
||||
payloadLive.economy1Center +
|
||||
payloadLive.economy1Right +
|
||||
payloadLive.economy2Left +
|
||||
payloadLive.economy2Center +
|
||||
payloadLive.economy2Right +
|
||||
payloadLive.cabinCrewRear +
|
||||
payloadLive.forwardCargo +
|
||||
payloadLive.rearCargo +
|
||||
payloadLive.leftAuxPax +
|
||||
payloadLive.rightAuxPax
|
||||
);
|
||||
};
|
||||
const ZFWValid = () => {
|
||||
return _ZFW() <= PaxConfig.maxZWF[unit];
|
||||
};
|
||||
|
||||
const GW = () => {
|
||||
return fuel + _ZFW();
|
||||
};
|
||||
const GWValid = () => {
|
||||
return GW() <= (isER ? SharedConfig.maxTOW.er[unit] : SharedConfig.maxTOW.norm[unit]);
|
||||
};
|
||||
|
||||
const handleInput = (input: string, maxValue: number, setter: (value: number) => void) => {
|
||||
if (!input) {
|
||||
setter(0);
|
||||
return;
|
||||
}
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < 0) setter(0);
|
||||
else if (converted > maxValue) setter(maxValue);
|
||||
else setter(converted);
|
||||
}
|
||||
};
|
||||
const handleInputZFW = (input: string) => {
|
||||
if (!input) return;
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < 0)
|
||||
setZFW(
|
||||
Math.round(
|
||||
PaxConfig.weights.base[unit].total + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) + payloadLive.empty
|
||||
)
|
||||
);
|
||||
else if (converted > PaxConfig.maxZWF[unit]) setZFW(PaxConfig.maxZWF[unit]);
|
||||
else setZFW(converted);
|
||||
}
|
||||
};
|
||||
const handleBlur = (input: string) => {
|
||||
const minZFW = Math.round(
|
||||
PaxConfig.weights.base[unit].total + (isER ? SharedConfig.erExtraWeight[unit] * 2 : 0) + payloadLive.empty
|
||||
);
|
||||
|
||||
if (!input) {
|
||||
setZFW(minZFW);
|
||||
return;
|
||||
}
|
||||
|
||||
const converted = parseInt(input);
|
||||
if (converted) {
|
||||
if (converted < minZFW) setZFW(minZFW);
|
||||
else if (converted > PaxConfig.maxZWF[unit]) setZFW(PaxConfig.maxZWF[unit]);
|
||||
else setZFW(converted);
|
||||
}
|
||||
|
||||
updateView(PaxConfig.distribute(converted, targetZFWCG, payloadLive.empty, fuelLive, unit, isER));
|
||||
};
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setFuel((prev) =>
|
||||
prev > (isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit])
|
||||
? isER
|
||||
? SharedConfig.maxFuel.er[unit]
|
||||
: SharedConfig.maxFuel.norm[unit]
|
||||
: prev
|
||||
),
|
||||
[isER]
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>Target ZFW ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className="w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right focus:border-blue-600 focus:ring-blue-600"
|
||||
value={ZFW}
|
||||
onChange={(e) => handleInputZFW(e.target.value)}
|
||||
onBlur={(e) => handleBlur(e.target.value)}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>
|
||||
Target ZFWCG ({SharedConfig.CGLimits.min} - {SharedConfig.CGLimits.max})
|
||||
</label>
|
||||
<CGSelect
|
||||
value={targetZFWCG}
|
||||
disabled={loadingState !== 'preview'}
|
||||
increase={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev + 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
decrease={() =>
|
||||
setTargetZFWCG((prev) => {
|
||||
const _new = prev - 0.1;
|
||||
updateView(PaxConfig.distribute(ZFW, _new, payloadLive.empty, fuelLive, unit, isER));
|
||||
return _new;
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-md bg-zinc-600 p-2 px-4">
|
||||
<label>Fuel ({unit})</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border border-white bg-zinc-700 px-3 py-2 text-right`}
|
||||
value={fuel}
|
||||
onChange={(e) =>
|
||||
handleInput(
|
||||
e.target.value,
|
||||
isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit],
|
||||
setFuel
|
||||
)
|
||||
}
|
||||
disabled={loadingState !== 'preview'}
|
||||
/>
|
||||
<button
|
||||
className="middle none center rounded-lg bg-green-600 px-6 py-3 font-sans text-xs font-bold uppercase text-white shadow-md shadow-green-500/20 transition-all hover:shadow-lg hover:shadow-green-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none"
|
||||
data-ripple-light="true"
|
||||
onClick={() => {
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_PAYLOAD_FUEL', 'lbs', unit === 'kg' ? fuel * 2.20462262185 : fuel);
|
||||
SimVar.SetSimVarValue('L:MD11_EFB_READ_READY', 'bool', true);
|
||||
}}
|
||||
disabled={loadingState !== 'preview'}
|
||||
>
|
||||
Load Fuel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="block flex w-full flex-col opacity-100 transition-opacity duration-150 ease-linear mb-4">
|
||||
<div className="relative flex w-full items-center justify-between rounded-t-md bg-zinc-600 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} ZFW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${ZFWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={_ZFW()}
|
||||
/>
|
||||
</div>
|
||||
<div className="relative flex w-full items-center justify-between rounded-b-md bg-zinc-700 p-2 px-4">
|
||||
<label>
|
||||
{loadingState !== 'loaded' ? 'Expected' : 'Actual'} GW ({unit})
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder=""
|
||||
className={`w-1/2 rounded-lg border ${GWValid() ? 'border-white' : 'border-red-500 text-red-500'} bg-zinc-700 px-3 py-2 text-right`}
|
||||
disabled
|
||||
value={GW()}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ActionBar
|
||||
loadingState={loadingState}
|
||||
acceptDisabled={!GWValid()}
|
||||
accept={() => setLoadingState('accepted')}
|
||||
reject={() => setLoadingState('preview')}
|
||||
load={() => {
|
||||
setLoadingState('loaded');
|
||||
|
||||
loadAircraft();
|
||||
}}
|
||||
unload={() => {
|
||||
setLoadingState('preview');
|
||||
|
||||
PaxConfig.unload(unit, isER);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default ZFWEntryPax;
|
||||
153
PackageSources/js-bundle/src/configs/freighter.ts
Normal file
153
PackageSources/js-bundle/src/configs/freighter.ts
Normal file
@ -0,0 +1,153 @@
|
||||
import { ArmsFuel, Fuel, toPercentMAC } from './shared';
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
const ArmsFreight = {
|
||||
empty: -159.6,
|
||||
pilot: 984,
|
||||
firstOfficer: 984,
|
||||
engineer: 960,
|
||||
upper1Left: 660,
|
||||
upper1Right: 660,
|
||||
upper2Left: 240,
|
||||
upper2Right: 240,
|
||||
upper3Left: -240,
|
||||
upper3Right: -240,
|
||||
upper4Left: -600,
|
||||
upper4Right: -600,
|
||||
lowerForward: 360,
|
||||
lowerRear: -360,
|
||||
leftAuxF: 60,
|
||||
rightAuxF: 60,
|
||||
};
|
||||
|
||||
export interface PayloadFreight {
|
||||
empty: number;
|
||||
pilot: number;
|
||||
firstOfficer: number;
|
||||
engineer: number;
|
||||
upper1Left: number;
|
||||
upper1Right: number;
|
||||
upper2Left: number;
|
||||
upper2Right: number;
|
||||
upper3Left: number;
|
||||
upper3Right: number;
|
||||
upper4Left: number;
|
||||
upper4Right: number;
|
||||
lowerForward: number;
|
||||
lowerRear: number;
|
||||
leftAuxF: number;
|
||||
rightAuxF: number;
|
||||
}
|
||||
|
||||
//PMC pallet
|
||||
export const maxUpperStationWeight = {
|
||||
lbs: (26 / 8) * 15000,
|
||||
kg: (26 / 8) * 6804,
|
||||
};
|
||||
|
||||
export const baseWeightFreight = {
|
||||
pilot: {
|
||||
lbs: 190,
|
||||
kg: 86,
|
||||
},
|
||||
firstOfficer: {
|
||||
lbs: 190,
|
||||
kg: 86,
|
||||
},
|
||||
};
|
||||
|
||||
export const maxZFWFreight = {
|
||||
lbs: 451300,
|
||||
kg: 204706,
|
||||
};
|
||||
|
||||
export const calculateCGsFreight = (payload: PayloadFreight, fuel: Fuel): [number, number] => {
|
||||
let totalMoment =
|
||||
payload.empty * ArmsFreight.empty +
|
||||
payload.pilot * ArmsFreight.pilot +
|
||||
payload.firstOfficer * ArmsFreight.firstOfficer +
|
||||
payload.engineer * ArmsFreight.engineer +
|
||||
payload.upper1Left * ArmsFreight.upper1Left +
|
||||
payload.upper1Right * ArmsFreight.upper1Right +
|
||||
payload.upper2Left * ArmsFreight.upper2Left +
|
||||
payload.upper2Right * ArmsFreight.upper2Right +
|
||||
payload.upper3Left * ArmsFreight.upper3Left +
|
||||
payload.upper3Right * ArmsFreight.upper3Right +
|
||||
payload.upper4Left * ArmsFreight.upper4Left +
|
||||
payload.upper4Right * ArmsFreight.upper4Right +
|
||||
payload.lowerForward * ArmsFreight.lowerForward +
|
||||
payload.lowerRear * ArmsFreight.lowerRear +
|
||||
payload.leftAuxF * ArmsFreight.leftAuxF +
|
||||
payload.rightAuxF * ArmsFreight.rightAuxF;
|
||||
|
||||
let totalWeight =
|
||||
payload.empty +
|
||||
payload.pilot +
|
||||
payload.firstOfficer +
|
||||
payload.engineer +
|
||||
payload.upper1Left +
|
||||
payload.upper1Right +
|
||||
payload.upper2Left +
|
||||
payload.upper2Right +
|
||||
payload.upper3Left +
|
||||
payload.upper3Right +
|
||||
payload.upper4Left +
|
||||
payload.upper4Right +
|
||||
payload.lowerForward +
|
||||
payload.lowerRear +
|
||||
payload.leftAuxF +
|
||||
payload.rightAuxF;
|
||||
|
||||
const ZFWCG = toPercentMAC(totalMoment / totalWeight);
|
||||
|
||||
totalMoment +=
|
||||
fuel.main1 * ArmsFuel.main1 +
|
||||
fuel.main3 * ArmsFuel.main3 +
|
||||
fuel.main2 * ArmsFuel.main2 +
|
||||
fuel.upperAux * ArmsFuel.upperAux +
|
||||
fuel.lowerAux * ArmsFuel.lowerAux +
|
||||
fuel.main1Tip * ArmsFuel.main1Tip +
|
||||
fuel.main3Tip * ArmsFuel.main3Tip +
|
||||
fuel.tail * ArmsFuel.tail +
|
||||
fuel.forwardAux1 * ArmsFuel.forwardAux1 +
|
||||
fuel.forwardAux2 * ArmsFuel.forwardAux2;
|
||||
|
||||
totalWeight +=
|
||||
fuel.main1 +
|
||||
fuel.main3 +
|
||||
fuel.main2 +
|
||||
fuel.upperAux +
|
||||
fuel.lowerAux +
|
||||
fuel.main1Tip +
|
||||
fuel.main3Tip +
|
||||
fuel.tail +
|
||||
fuel.forwardAux1 +
|
||||
fuel.forwardAux2;
|
||||
|
||||
const TOCG = toPercentMAC(totalMoment / totalWeight);
|
||||
|
||||
return [ZFWCG, TOCG];
|
||||
};
|
||||
|
||||
export const getWeightsFreight = (unit: 'kg' | 'lbs') => {
|
||||
const payload: PayloadFreight = {
|
||||
empty: SimVar.GetSimVarValue('EMPTY WEIGHT', unit),
|
||||
pilot: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:1', unit),
|
||||
firstOfficer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:2', unit),
|
||||
engineer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:3', unit),
|
||||
upper1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:4', unit),
|
||||
upper1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:5', unit),
|
||||
upper2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:6', unit),
|
||||
upper2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:7', unit),
|
||||
upper3Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:8', unit),
|
||||
upper3Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:9', unit),
|
||||
upper4Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:10', unit),
|
||||
upper4Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:11', unit),
|
||||
lowerForward: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:12', unit),
|
||||
lowerRear: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:13', unit),
|
||||
leftAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:14', unit),
|
||||
rightAuxF: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:15', unit),
|
||||
};
|
||||
|
||||
return payload;
|
||||
};
|
||||
598
PackageSources/js-bundle/src/configs/pax.ts
Normal file
598
PackageSources/js-bundle/src/configs/pax.ts
Normal file
@ -0,0 +1,598 @@
|
||||
import { ArmsFuel, Fuel, SharedConfig, toPercentMAC } from './shared';
|
||||
|
||||
export interface PayloadPax {
|
||||
empty: number;
|
||||
pilot: number;
|
||||
firstOfficer: number;
|
||||
engineer: number;
|
||||
cabinCrewFront: number;
|
||||
business1Left: number;
|
||||
business1Center: number;
|
||||
business1Right: number;
|
||||
business2Left: number;
|
||||
business2Center: number;
|
||||
business2Right: number;
|
||||
economy1Left: number;
|
||||
economy1Center: number;
|
||||
economy1Right: number;
|
||||
economy2Left: number;
|
||||
economy2Center: number;
|
||||
economy2Right: number;
|
||||
cabinCrewRear: number;
|
||||
forwardCargo: number;
|
||||
rearCargo: number;
|
||||
leftAuxPax: number;
|
||||
rightAuxPax: number;
|
||||
|
||||
paxCount: {
|
||||
business1: number;
|
||||
business2: number;
|
||||
economy1: number;
|
||||
economy2: number;
|
||||
total: number;
|
||||
};
|
||||
}
|
||||
|
||||
export const PaxConfig = {
|
||||
// TODO: Extract from CFG at runtime.
|
||||
arms: {
|
||||
empty: -159.6,
|
||||
pilot: 984,
|
||||
firstOfficer: 984,
|
||||
engineer: 960,
|
||||
cabinCrewFront: 792,
|
||||
business1Left: 540,
|
||||
business1Center: 540,
|
||||
business1Right: 540,
|
||||
business2Left: 300,
|
||||
business2Center: 300,
|
||||
business2Right: 300,
|
||||
economy1Left: -240,
|
||||
economy1Center: -240,
|
||||
economy1Right: -240,
|
||||
economy2Left: -600,
|
||||
economy2Center: -600,
|
||||
economy2Right: -600,
|
||||
cabinCrewRear: -660,
|
||||
forwardCargo: 360,
|
||||
rearCargo: -360,
|
||||
leftAuxPax: 60,
|
||||
rightAuxPax: 60,
|
||||
},
|
||||
// TODO: Make user adjustable
|
||||
weights: {
|
||||
pax: {
|
||||
lbs: 190,
|
||||
kg: 86,
|
||||
},
|
||||
baggage: {
|
||||
lbs: 50,
|
||||
kg: 23,
|
||||
},
|
||||
base: {
|
||||
lbs: {
|
||||
pilot: 190,
|
||||
firstOfficer: 190,
|
||||
engineer: 190,
|
||||
cabinCrewFront: 380,
|
||||
cabinCrewRear: 950,
|
||||
total: 190 + 190 + 190 + 380 + 950,
|
||||
},
|
||||
kg: {
|
||||
pilot: 86,
|
||||
firstOfficer: 86,
|
||||
engineer: 86,
|
||||
cabinCrewFront: 172,
|
||||
cabinCrewRear: 430,
|
||||
total: 86 + 86 + 86 + 172 + 430,
|
||||
},
|
||||
},
|
||||
},
|
||||
stationMax: {
|
||||
business1: 30,
|
||||
business2: 45,
|
||||
economy1: 86,
|
||||
economy2: 137,
|
||||
total: 30 + 45 + 86 + 137,
|
||||
},
|
||||
maxZWF: {
|
||||
lbs: 400000,
|
||||
kg: 181437,
|
||||
},
|
||||
weightToPax: (weight: number, unit: 'kg' | 'lbs') => {
|
||||
return Math.round(weight / PaxConfig.weights.pax[unit]);
|
||||
},
|
||||
calculateCGs: (payload: PayloadPax, fuel: Fuel): [number, number] => {
|
||||
let totalMoment =
|
||||
payload.empty * PaxConfig.arms.empty +
|
||||
payload.pilot * PaxConfig.arms.pilot +
|
||||
payload.firstOfficer * PaxConfig.arms.firstOfficer +
|
||||
payload.engineer * PaxConfig.arms.engineer +
|
||||
payload.cabinCrewFront * PaxConfig.arms.cabinCrewFront +
|
||||
payload.business1Left * PaxConfig.arms.business1Left +
|
||||
payload.business1Center * PaxConfig.arms.business1Center +
|
||||
payload.business1Right * PaxConfig.arms.business1Right +
|
||||
payload.business2Left * PaxConfig.arms.business2Left +
|
||||
payload.business2Center * PaxConfig.arms.business2Center +
|
||||
payload.business2Right * PaxConfig.arms.business2Right +
|
||||
payload.economy1Left * PaxConfig.arms.economy1Left +
|
||||
payload.economy1Center * PaxConfig.arms.economy1Center +
|
||||
payload.economy1Right * PaxConfig.arms.economy1Right +
|
||||
payload.economy2Left * PaxConfig.arms.economy2Left +
|
||||
payload.economy2Center * PaxConfig.arms.economy2Center +
|
||||
payload.economy2Right * PaxConfig.arms.economy2Right +
|
||||
payload.cabinCrewRear * PaxConfig.arms.cabinCrewRear +
|
||||
payload.forwardCargo * PaxConfig.arms.forwardCargo +
|
||||
payload.rearCargo * PaxConfig.arms.rearCargo +
|
||||
payload.leftAuxPax * PaxConfig.arms.leftAuxPax +
|
||||
payload.rightAuxPax * PaxConfig.arms.rightAuxPax;
|
||||
|
||||
let totalWeight =
|
||||
payload.empty +
|
||||
payload.pilot +
|
||||
payload.firstOfficer +
|
||||
payload.engineer +
|
||||
payload.cabinCrewFront +
|
||||
payload.business1Left +
|
||||
payload.business1Center +
|
||||
payload.business1Right +
|
||||
payload.business2Left +
|
||||
payload.business2Center +
|
||||
payload.business2Right +
|
||||
payload.economy1Left +
|
||||
payload.economy1Center +
|
||||
payload.economy1Right +
|
||||
payload.economy2Left +
|
||||
payload.economy2Center +
|
||||
payload.economy2Right +
|
||||
payload.cabinCrewRear +
|
||||
payload.forwardCargo +
|
||||
payload.rearCargo +
|
||||
payload.leftAuxPax +
|
||||
payload.rightAuxPax;
|
||||
|
||||
const ZFWCG = toPercentMAC(totalMoment / totalWeight);
|
||||
|
||||
totalMoment +=
|
||||
fuel.main1 * ArmsFuel.main1 +
|
||||
fuel.main3 * ArmsFuel.main3 +
|
||||
fuel.main2 * ArmsFuel.main2 +
|
||||
fuel.upperAux * ArmsFuel.upperAux +
|
||||
fuel.lowerAux * ArmsFuel.lowerAux +
|
||||
fuel.main1Tip * ArmsFuel.main1Tip +
|
||||
fuel.main3Tip * ArmsFuel.main3Tip +
|
||||
fuel.tail * ArmsFuel.tail +
|
||||
fuel.forwardAux1 * ArmsFuel.forwardAux1 +
|
||||
fuel.forwardAux2 * ArmsFuel.forwardAux2;
|
||||
|
||||
totalWeight +=
|
||||
fuel.main1 +
|
||||
fuel.main3 +
|
||||
fuel.main2 +
|
||||
fuel.upperAux +
|
||||
fuel.lowerAux +
|
||||
fuel.main1Tip +
|
||||
fuel.main3Tip +
|
||||
fuel.tail +
|
||||
fuel.forwardAux1 +
|
||||
fuel.forwardAux2;
|
||||
|
||||
const toCG = toPercentMAC(totalMoment / totalWeight);
|
||||
|
||||
return [ZFWCG, toCG];
|
||||
},
|
||||
generateDistribution: (
|
||||
OEW: number,
|
||||
business1: number,
|
||||
business2: number,
|
||||
economy1: number,
|
||||
economy2: number,
|
||||
forwardCargo: number,
|
||||
rearCargo: number,
|
||||
unit: 'kg' | 'lbs',
|
||||
isER: boolean
|
||||
): PayloadPax => {
|
||||
const distribution: PayloadPax = {
|
||||
empty: OEW,
|
||||
|
||||
...PaxConfig.weights.base[unit],
|
||||
|
||||
business1Left: (business1 / 3) * PaxConfig.weights.pax[unit],
|
||||
business1Center: (business1 / 3) * PaxConfig.weights.pax[unit],
|
||||
business1Right: (business1 / 3) * PaxConfig.weights.pax[unit],
|
||||
business2Left: (business2 / 3) * PaxConfig.weights.pax[unit],
|
||||
business2Center: (business2 / 3) * PaxConfig.weights.pax[unit],
|
||||
business2Right: (business2 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy1Left: (economy1 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy1Center: (economy1 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy1Right: (economy1 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy2Left: (economy2 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy2Center: (economy2 / 3) * PaxConfig.weights.pax[unit],
|
||||
economy2Right: (economy2 / 3) * PaxConfig.weights.pax[unit],
|
||||
|
||||
forwardCargo: forwardCargo,
|
||||
rearCargo: rearCargo,
|
||||
|
||||
leftAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
rightAuxPax: isER ? SharedConfig.erExtraWeight[unit] : 0,
|
||||
|
||||
paxCount: {
|
||||
business1,
|
||||
business2,
|
||||
economy1,
|
||||
economy2,
|
||||
total: business1 + business2 + economy1 + economy2,
|
||||
},
|
||||
};
|
||||
|
||||
return distribution;
|
||||
},
|
||||
distribute: (
|
||||
ZFWTarget: number,
|
||||
CGTarget: number,
|
||||
OEW: number,
|
||||
fuelLive: Fuel,
|
||||
unit: 'kg' | 'lbs',
|
||||
isER: boolean,
|
||||
numPax?: number
|
||||
) => {
|
||||
const payload =
|
||||
ZFWTarget -
|
||||
OEW -
|
||||
PaxConfig.weights.base[unit].pilot -
|
||||
PaxConfig.weights.base[unit].firstOfficer -
|
||||
PaxConfig.weights.base[unit].engineer -
|
||||
PaxConfig.weights.base[unit].cabinCrewFront -
|
||||
PaxConfig.weights.base[unit].cabinCrewRear -
|
||||
(isER ? SharedConfig.erExtraWeight[unit] * 2 : 0);
|
||||
|
||||
let _numPax =
|
||||
numPax ??
|
||||
Math.max(
|
||||
0,
|
||||
Math.min(
|
||||
PaxConfig.stationMax.total,
|
||||
Math.floor(payload / (PaxConfig.weights.pax[unit] + PaxConfig.weights.baggage[unit]))
|
||||
)
|
||||
);
|
||||
let cargo = Math.round(payload - _numPax * PaxConfig.weights.pax[unit] - _numPax * PaxConfig.weights.baggage[unit]);
|
||||
|
||||
let business1 = 0;
|
||||
let business2 = 0;
|
||||
let economy1 = 0;
|
||||
let economy2 = 0;
|
||||
let forwardCargo = 0;
|
||||
let rearCargo = 0;
|
||||
let __numPax = 0;
|
||||
let count = PaxConfig.stationMax.economy2;
|
||||
// initial distribution
|
||||
while (_numPax > 0 && count > 0) {
|
||||
if (_numPax >= 4) {
|
||||
if (business1 < PaxConfig.stationMax.business1) {
|
||||
business1++;
|
||||
__numPax++;
|
||||
}
|
||||
if (business2 < PaxConfig.stationMax.business2) {
|
||||
business2++;
|
||||
__numPax++;
|
||||
}
|
||||
if (economy1 < PaxConfig.stationMax.economy1) {
|
||||
economy1++;
|
||||
__numPax++;
|
||||
}
|
||||
if (economy2 < PaxConfig.stationMax.economy2) {
|
||||
economy2++;
|
||||
__numPax++;
|
||||
}
|
||||
} else if (_numPax === 3) {
|
||||
if (business2 < PaxConfig.stationMax.business2) {
|
||||
business2++;
|
||||
__numPax++;
|
||||
}
|
||||
if (economy1 < PaxConfig.stationMax.economy1) {
|
||||
economy1++;
|
||||
__numPax++;
|
||||
}
|
||||
if (economy2 < PaxConfig.stationMax.economy2) {
|
||||
economy2++;
|
||||
__numPax++;
|
||||
}
|
||||
} else if (_numPax === 2) {
|
||||
if (economy1 < PaxConfig.stationMax.economy1) {
|
||||
economy1++;
|
||||
__numPax++;
|
||||
}
|
||||
if (economy2 < PaxConfig.stationMax.economy2) {
|
||||
economy2++;
|
||||
__numPax++;
|
||||
}
|
||||
} else if (_numPax === 1) {
|
||||
if (economy2 < PaxConfig.stationMax.economy2) {
|
||||
economy2++;
|
||||
__numPax++;
|
||||
}
|
||||
}
|
||||
_numPax -= __numPax;
|
||||
|
||||
if (__numPax % 2 === 0) {
|
||||
forwardCargo += (__numPax / 2) * PaxConfig.weights.baggage[unit];
|
||||
rearCargo += (__numPax / 2) * PaxConfig.weights.baggage[unit];
|
||||
} else {
|
||||
__numPax--;
|
||||
forwardCargo += (__numPax / 2 + 1) * PaxConfig.weights.baggage[unit];
|
||||
rearCargo += (__numPax / 2) * PaxConfig.weights.baggage[unit];
|
||||
}
|
||||
|
||||
__numPax = 0;
|
||||
|
||||
count--;
|
||||
}
|
||||
count = SharedConfig.stationMax.forward[unit];
|
||||
while (cargo > 0 && count > 0) {
|
||||
if (forwardCargo < SharedConfig.stationMax.forward[unit]) {
|
||||
forwardCargo++;
|
||||
cargo--;
|
||||
}
|
||||
if (rearCargo < SharedConfig.stationMax.rear[unit]) {
|
||||
rearCargo++;
|
||||
cargo--;
|
||||
}
|
||||
|
||||
count--;
|
||||
}
|
||||
// Refinement pax
|
||||
count = PaxConfig.stationMax.total;
|
||||
while (count > 0) {
|
||||
const distribution = PaxConfig.generateDistribution(
|
||||
OEW,
|
||||
business1,
|
||||
business2,
|
||||
economy1,
|
||||
economy2,
|
||||
forwardCargo,
|
||||
rearCargo,
|
||||
unit,
|
||||
isER
|
||||
);
|
||||
const _CGs = PaxConfig.calculateCGs(distribution, fuelLive);
|
||||
|
||||
// in front of target
|
||||
if (_CGs[0] < CGTarget - SharedConfig.CGLimits.tolerance) {
|
||||
if (business1 > 0) {
|
||||
business1--;
|
||||
} else if (business2 > 0) {
|
||||
business2--;
|
||||
} else if (economy1 > 0) {
|
||||
economy1--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (economy2 < PaxConfig.stationMax.economy2) {
|
||||
economy2++;
|
||||
} else if (economy1 < PaxConfig.stationMax.economy1) {
|
||||
economy1++;
|
||||
} else if (business2 < PaxConfig.stationMax.business2) {
|
||||
business2++;
|
||||
} else {
|
||||
business1++;
|
||||
}
|
||||
}
|
||||
// behind target
|
||||
else if (_CGs[0] > CGTarget + SharedConfig.CGLimits.tolerance) {
|
||||
if (economy2 > 0) {
|
||||
economy2--;
|
||||
} else if (economy1 > 0) {
|
||||
economy1--;
|
||||
} else if (business2 > 0) {
|
||||
business2--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (business1 < PaxConfig.stationMax.business1) {
|
||||
business1++;
|
||||
} else if (business2 < PaxConfig.stationMax.business2) {
|
||||
business2++;
|
||||
} else if (economy1 < PaxConfig.stationMax.economy1) {
|
||||
economy1++;
|
||||
} else {
|
||||
economy2++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
count--;
|
||||
}
|
||||
// Refinement cargo
|
||||
count = SharedConfig.stationMax.forward[unit] + SharedConfig.stationMax.rear[unit];
|
||||
while (count > 0) {
|
||||
const distribution = PaxConfig.generateDistribution(
|
||||
OEW,
|
||||
business1,
|
||||
business2,
|
||||
economy1,
|
||||
economy2,
|
||||
forwardCargo,
|
||||
rearCargo,
|
||||
unit,
|
||||
isER
|
||||
);
|
||||
const _CGs = PaxConfig.calculateCGs(distribution, fuelLive);
|
||||
|
||||
// in front of target
|
||||
if (_CGs[0] < CGTarget - SharedConfig.CGLimits.tolerance) {
|
||||
if (forwardCargo > 0 && rearCargo < SharedConfig.stationMax.rear[unit]) {
|
||||
if (
|
||||
forwardCargo > PaxConfig.weights.baggage[unit] &&
|
||||
rearCargo < SharedConfig.stationMax.forward[unit] - PaxConfig.weights.baggage[unit]
|
||||
) {
|
||||
forwardCargo -= PaxConfig.weights.baggage[unit];
|
||||
rearCargo += PaxConfig.weights.baggage[unit];
|
||||
} else {
|
||||
forwardCargo--;
|
||||
rearCargo++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// behind target
|
||||
else if (_CGs[0] > CGTarget + SharedConfig.CGLimits.tolerance) {
|
||||
if (rearCargo > 0 && forwardCargo < SharedConfig.stationMax.forward[unit]) {
|
||||
if (
|
||||
rearCargo > PaxConfig.weights.baggage[unit] &&
|
||||
forwardCargo < SharedConfig.stationMax.rear[unit] - PaxConfig.weights.baggage[unit]
|
||||
) {
|
||||
rearCargo -= PaxConfig.weights.baggage[unit];
|
||||
forwardCargo += PaxConfig.weights.baggage[unit];
|
||||
} else {
|
||||
rearCargo--;
|
||||
forwardCargo++;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
count--;
|
||||
}
|
||||
|
||||
const distribution = PaxConfig.generateDistribution(
|
||||
OEW,
|
||||
business1,
|
||||
business2,
|
||||
economy1,
|
||||
economy2,
|
||||
forwardCargo,
|
||||
rearCargo,
|
||||
unit,
|
||||
isER
|
||||
);
|
||||
|
||||
return distribution;
|
||||
},
|
||||
// SIM access
|
||||
getWeights: (unit: 'kg' | 'lbs') => {
|
||||
const payload: PayloadPax = {
|
||||
empty: SimVar.GetSimVarValue('EMPTY WEIGHT', unit),
|
||||
pilot: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:1', unit),
|
||||
firstOfficer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:2', unit),
|
||||
engineer: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:3', unit),
|
||||
cabinCrewFront: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:4', unit),
|
||||
business1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:5', unit),
|
||||
business1Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:6', unit),
|
||||
business1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:7', unit),
|
||||
business2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:8', unit),
|
||||
business2Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:9', unit),
|
||||
business2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:10', unit),
|
||||
economy1Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:11', unit),
|
||||
economy1Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:12', unit),
|
||||
economy1Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:13', unit),
|
||||
economy2Left: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:14', unit),
|
||||
economy2Center: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:15', unit),
|
||||
economy2Right: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:16', unit),
|
||||
cabinCrewRear: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:17', unit),
|
||||
forwardCargo: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:18', unit),
|
||||
rearCargo: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:19', unit),
|
||||
leftAuxPax: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:20', unit),
|
||||
rightAuxPax: SimVar.GetSimVarValue('PAYLOAD STATION WEIGHT:21', unit),
|
||||
|
||||
paxCount: {
|
||||
business1: 0,
|
||||
business2: 0,
|
||||
economy1: 0,
|
||||
economy2: 0,
|
||||
total: 0,
|
||||
},
|
||||
};
|
||||
|
||||
return payload;
|
||||
},
|
||||
setBaseWeight: (unit: 'kg' | 'lbs', isER: boolean) => {
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:1', unit, PaxConfig.weights.base[unit].pilot); // Pilot
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:2', unit, PaxConfig.weights.base[unit].firstOfficer); // First officer
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:3', unit, PaxConfig.weights.base[unit].engineer); // Engineer
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:4', unit, PaxConfig.weights.base[unit].cabinCrewFront); // Cabin Crew front
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:17', unit, PaxConfig.weights.base[unit].cabinCrewRear); // Cabin Crew rear
|
||||
if (isER) {
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:20', unit, SharedConfig.erExtraWeight[unit]); // Forward Aux 1
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:21', unit, SharedConfig.erExtraWeight[unit]); // Forward Aux 2
|
||||
}
|
||||
},
|
||||
setWeights: (payload: PayloadPax, unit: 'kg' | 'lbs') => {
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:4', unit, payload.cabinCrewFront); // Cabin Crew front
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:5', unit, payload.business1Left); // Business 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:6', unit, payload.business1Center); // Business 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:7', unit, payload.business1Right); // Business 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:8', unit, payload.business2Left); // Business 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:9', unit, payload.business2Center); // Business 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:10', unit, payload.business2Right); // Business 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:11', unit, payload.economy1Left); // Economy 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:12', unit, payload.economy1Center); // Economy 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:13', unit, payload.economy1Right); // Economy 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:14', unit, payload.economy2Left); // Economy 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:15', unit, payload.economy2Center); // Economy 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:16', unit, payload.economy2Right); // Economy 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:17', unit, payload.cabinCrewRear); //Cabin Crew rear
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:18', unit, payload.forwardCargo); // Forward Cargo
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:19', unit, payload.rearCargo); // Rear Cargo
|
||||
},
|
||||
setWeightsProgressive: (payload: PayloadPax, paxNum: number, cargoPercent: number, unit: 'kg' | 'lbs') => {
|
||||
const business1Scalar = Math.min(1, paxNum / payload.paxCount.business1);
|
||||
paxNum -= payload.paxCount.business1 * business1Scalar;
|
||||
const business2Scalar = Math.min(1, paxNum / payload.paxCount.business2);
|
||||
paxNum -= payload.paxCount.business2 * business2Scalar;
|
||||
const economy1Scalar = Math.min(1, paxNum / payload.paxCount.economy1);
|
||||
paxNum -= payload.paxCount.economy1 * economy1Scalar;
|
||||
const economy2Scalar = Math.min(1, paxNum / payload.paxCount.economy2);
|
||||
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:4', unit, payload.cabinCrewFront); // Cabin Crew front
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:5', unit, payload.business1Left * business1Scalar); // Business 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:6', unit, payload.business1Center * business1Scalar); // Business 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:7', unit, payload.business1Right * business1Scalar); // Business 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:8', unit, payload.business2Left * business2Scalar); // Business 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:9', unit, payload.business2Center * business2Scalar); // Business 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:10', unit, payload.business2Right * business2Scalar); // Business 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:11', unit, payload.economy1Left * economy1Scalar); // Economy 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:12', unit, payload.economy1Center * economy1Scalar); // Economy 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:13', unit, payload.economy1Right * economy1Scalar); // Economy 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:14', unit, payload.economy2Left * economy2Scalar); // Economy 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:15', unit, payload.economy2Center * economy2Scalar); // Economy 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:16', unit, payload.economy2Right * economy2Scalar); // Economy 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:17', unit, payload.cabinCrewRear); //Cabin Crew rear
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:18', unit, payload.forwardCargo * (cargoPercent / 100)); // Forward Cargo
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:19', unit, payload.rearCargo * (cargoPercent / 100)); // Rear Cargo
|
||||
},
|
||||
unload: (unit: 'kg' | 'lbs', isER: boolean) => {
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:1', unit, 0); // Pilot
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:2', unit, 0); // First officer
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:3', unit, 0); // Engineer
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:4', unit, 0); // Cabin Crew front
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:17', unit, 0); // Cabin Crew rear
|
||||
if (!isER) {
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:20', unit, 0); // Forward Aux 1
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:21', unit, 0); // Forward Aux 2
|
||||
}
|
||||
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:4', unit, 0); // Cabin Crew front
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:5', unit, 0); // Business 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:6', unit, 0); // Business 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:7', unit, 0); // Business 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:8', unit, 0); // Business 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:9', unit, 0); // Business 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:10', unit, 0); // Business 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:11', unit, 0); // Economy 1L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:12', unit, 0); // Economy 1C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:13', unit, 0); // Economy 1R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:14', unit, 0); // Economy 2L
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:15', unit, 0); // Economy 2C
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:16', unit, 0); // Economy 2R
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:17', unit, 0); //Cabin Crew rear
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:18', unit, 0); // Forward Cargo
|
||||
SimVar.SetSimVarValue('PAYLOAD STATION WEIGHT:19', unit, 0); // Rear Cargo
|
||||
},
|
||||
};
|
||||
166
PackageSources/js-bundle/src/configs/shared.ts
Normal file
166
PackageSources/js-bundle/src/configs/shared.ts
Normal file
@ -0,0 +1,166 @@
|
||||
export interface Fuel {
|
||||
main1: number;
|
||||
main3: number;
|
||||
main2: number;
|
||||
upperAux: number;
|
||||
lowerAux: number;
|
||||
main1Tip: number;
|
||||
main3Tip: number;
|
||||
tail: number;
|
||||
forwardAux1: number;
|
||||
forwardAux2: number;
|
||||
}
|
||||
|
||||
// TODO: Extract from CFG at runtime.
|
||||
export const ArmsFuel = {
|
||||
main1: -240,
|
||||
main3: -240,
|
||||
main2: 120,
|
||||
upperAux: 0,
|
||||
lowerAux: 0,
|
||||
main1Tip: -468,
|
||||
main3Tip: -468,
|
||||
tail: -840,
|
||||
forwardAux1: 60,
|
||||
forwardAux2: 60,
|
||||
};
|
||||
|
||||
// TODO: Extract following four from CFG at runtime
|
||||
const rootChord = 34.68;
|
||||
const wingSpan = 170.5;
|
||||
const wingArea = 3648;
|
||||
const quarterMAC = -165; //aero_center
|
||||
|
||||
const tipChord = (2 * wingArea) / wingSpan - rootChord;
|
||||
const taperRatio = tipChord / rootChord;
|
||||
|
||||
const MAC = (2 / 3) * rootChord * ((1 + taperRatio + taperRatio ** 2) / (1 + taperRatio)) * 12;
|
||||
const LEMAC = quarterMAC + (1 / 4) * MAC;
|
||||
|
||||
export const toPercentMAC = (positionInInches: number) => {
|
||||
return ((positionInInches - LEMAC) / MAC) * -100;
|
||||
};
|
||||
|
||||
export const SharedConfig = {
|
||||
stationMax: {
|
||||
//PMC pallet due to 104in door
|
||||
forward: {
|
||||
lbs: 6 * 15000,
|
||||
kg: 6 * 6804,
|
||||
},
|
||||
//LD3s due to 70in door
|
||||
rear: {
|
||||
lbs: 14 * 3500,
|
||||
kg: 14 * 1588,
|
||||
},
|
||||
},
|
||||
maxTOW: {
|
||||
er: {
|
||||
lbs: 630500,
|
||||
kg: 285990,
|
||||
},
|
||||
norm: {
|
||||
lbs: 625500,
|
||||
kg: 283722,
|
||||
},
|
||||
},
|
||||
maxFuel: {
|
||||
er: {
|
||||
lbs: 282619,
|
||||
kg: 128193,
|
||||
},
|
||||
norm: {
|
||||
lbs: 256207,
|
||||
kg: 116213,
|
||||
},
|
||||
},
|
||||
erExtraWeight: {
|
||||
lbs: 200,
|
||||
kg: 91,
|
||||
},
|
||||
CGLimits: {
|
||||
min: 12,
|
||||
default: 20.5,
|
||||
max: 34,
|
||||
tolerance: 0.05,
|
||||
},
|
||||
};
|
||||
|
||||
export const initialPayload = {
|
||||
empty: 0,
|
||||
pilot: 0,
|
||||
firstOfficer: 0,
|
||||
engineer: 0,
|
||||
cabinCrewFront: 0,
|
||||
business1Left: 0,
|
||||
business1Center: 0,
|
||||
business1Right: 0,
|
||||
business2Left: 0,
|
||||
business2Center: 0,
|
||||
business2Right: 0,
|
||||
economy1Left: 0,
|
||||
economy1Center: 0,
|
||||
economy1Right: 0,
|
||||
economy2Left: 0,
|
||||
economy2Center: 0,
|
||||
economy2Right: 0,
|
||||
cabinCrewRear: 0,
|
||||
forwardCargo: 0,
|
||||
rearCargo: 0,
|
||||
leftAuxPax: 0,
|
||||
rightAuxPax: 0,
|
||||
upper1Left: 0,
|
||||
upper1Right: 0,
|
||||
upper2Left: 0,
|
||||
upper2Right: 0,
|
||||
upper3Left: 0,
|
||||
upper3Right: 0,
|
||||
upper4Left: 0,
|
||||
upper4Right: 0,
|
||||
lowerForward: 0,
|
||||
lowerRear: 0,
|
||||
leftAuxF: 0,
|
||||
rightAuxF: 0,
|
||||
|
||||
paxCount: {
|
||||
business1: 0,
|
||||
business2: 0,
|
||||
economy1: 0,
|
||||
economy2: 0,
|
||||
total: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export const initialFuel = {
|
||||
main1: 0,
|
||||
main3: 0,
|
||||
main2: 0,
|
||||
upperAux: 0,
|
||||
lowerAux: 0,
|
||||
main1Tip: 0,
|
||||
main3Tip: 0,
|
||||
tail: 0,
|
||||
forwardAux1: 0,
|
||||
forwardAux2: 0,
|
||||
};
|
||||
|
||||
// SIM access
|
||||
|
||||
export const getFuel = (unit: 'kg' | 'lbs') => {
|
||||
const conversion = SimVar.GetSimVarValue('FUEL WEIGHT PER GALLON', unit);
|
||||
|
||||
const fuel = {
|
||||
main1: SimVar.GetSimVarValue('FUEL TANK LEFT MAIN QUANTITY', 'gal') * conversion,
|
||||
main3: SimVar.GetSimVarValue('FUEL TANK RIGHT MAIN QUANTITY', 'gal') * conversion,
|
||||
main2: SimVar.GetSimVarValue('FUEL TANK CENTER QUANTITY', 'gal') * conversion,
|
||||
upperAux: SimVar.GetSimVarValue('FUEL TANK CENTER2 QUANTITY', 'gal') * conversion,
|
||||
lowerAux: SimVar.GetSimVarValue('FUEL TANK CENTER3 QUANTITY', 'gal') * conversion,
|
||||
main1Tip: SimVar.GetSimVarValue('FUEL TANK LEFT TIP QUANTITY', 'gal') * conversion,
|
||||
main3Tip: SimVar.GetSimVarValue('FUEL TANK RIGHT TIP QUANTITY', 'gal') * conversion,
|
||||
tail: SimVar.GetSimVarValue('FUEL TANK EXTERNAL1 QUANTITY', 'gal') * conversion,
|
||||
forwardAux1: SimVar.GetSimVarValue('FUEL TANK LEFT AUX QUANTITY', 'gal') * conversion,
|
||||
forwardAux2: SimVar.GetSimVarValue('FUEL TANK RIGHT AUX QUANTITY', 'gal') * conversion,
|
||||
};
|
||||
|
||||
return fuel;
|
||||
};
|
||||
6
PackageSources/js-bundle/src/constants.ts
Normal file
6
PackageSources/js-bundle/src/constants.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export const COMMANDS = 'KHOFMANN_PDF_READER_COMMANDS';
|
||||
export const DATA = 'KHOFMANN_PDF_READER_DATA';
|
||||
export const LIST = 'LIST';
|
||||
export const LOAD = 'LOAD';
|
||||
export const SAVE = 'SAVE';
|
||||
export const MAX_LIST = 10;
|
||||
15
PackageSources/js-bundle/src/fonts/300.css
Normal file
15
PackageSources/js-bundle/src/fonts/300.css
Normal file
@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 300;
|
||||
src: url(assets/fonts/Roboto-Light.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 300;
|
||||
src: url(assets/fonts/Roboto-LightItalic.ttf) format('truetype');
|
||||
}
|
||||
15
PackageSources/js-bundle/src/fonts/400.css
Normal file
15
PackageSources/js-bundle/src/fonts/400.css
Normal file
@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url(assets/fonts/Roboto-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 400;
|
||||
src: url(assets/fonts/Roboto-Italic.ttf) format('truetype');
|
||||
}
|
||||
15
PackageSources/js-bundle/src/fonts/500.css
Normal file
15
PackageSources/js-bundle/src/fonts/500.css
Normal file
@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 500;
|
||||
src: url(assets/fonts/Roboto-Medium.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 500;
|
||||
src: url(assets/fonts/Roboto-MediumItalic.ttf) format('truetype');
|
||||
}
|
||||
15
PackageSources/js-bundle/src/fonts/700.css
Normal file
15
PackageSources/js-bundle/src/fonts/700.css
Normal file
@ -0,0 +1,15 @@
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: 700;
|
||||
src: url(assets/fonts/Roboto-Bold.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: italic;
|
||||
font-display: swap;
|
||||
font-weight: 700;
|
||||
src: url(assets/fonts/Roboto-BoldItalic.ttf) format('truetype');
|
||||
}
|
||||
42
PackageSources/js-bundle/src/index.html
Normal file
42
PackageSources/js-bundle/src/index.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<!-- prettier-ignore -->
|
||||
<head>
|
||||
<title></title>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
|
||||
<link rel="stylesheet" href="/SCSS/common.css" />
|
||||
<link rel="stylesheet" href="assets/efb.css" />
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
|
||||
<script type="text/javascript" src="/JS/coherent.js"></script>
|
||||
<script type="text/javascript" src="/JS/common.js"></script>
|
||||
<script type="text/javascript" src="/Pages/VCockpit/Instruments/Shared/BaseInstrument.js"></script>
|
||||
<script type="text/javascript" src="/JS/dataStorage.js"></script>
|
||||
<script type="text/javascript" src="/JS/buttons.js"></script>
|
||||
<script type="text/javascript" src="/JS/Services/ToolBarPanels.js"></script>
|
||||
<script type="text/javascript" src="/JS/simvar.js"></script>
|
||||
|
||||
<link rel="import" href="/templates/NewPushButton/NewPushButton.html" />
|
||||
<link rel="import" href="/templates/ingameUi/ingameUi.html" />
|
||||
<link rel="import" href="/templates/ingameUiHeader/ingameUiHeader.html" />
|
||||
<link rel="import" href="/templates/virtualScroll/virtualScroll.html" />
|
||||
</head>
|
||||
<body class="border-box">
|
||||
<tfdidesign-md11-load-manager-panel>
|
||||
<ingame-ui
|
||||
id="tfdidesign-md11-load-manager"
|
||||
panel-id="TFDIDESIGN_MD11_LOAD_MANAGER_PANEL"
|
||||
title="TFDi Design MD-11 Load Manager"
|
||||
class="ingameUiFrame panelInvisible"
|
||||
content-fit="true"
|
||||
>
|
||||
<virtual-scroll direction="y">
|
||||
<div id="react" style="display: flex"></div>
|
||||
</virtual-scroll>
|
||||
</ingame-ui>
|
||||
</tfdidesign-md11-load-manager-panel>
|
||||
<script src="index.js" type="text/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
32
PackageSources/js-bundle/src/index.ts
Normal file
32
PackageSources/js-bundle/src/index.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { createElement } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import App from './App';
|
||||
|
||||
class TFDiDesignMD11LoadManagerPanel extends TemplateElement {
|
||||
private commBus: ViewListener.ViewListener | undefined;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
|
||||
this.commBus = RegisterViewListener('JS_LISTENER_COMM_BUS');
|
||||
|
||||
const container = document.getElementById('react');
|
||||
if (container) {
|
||||
const root = createRoot(container);
|
||||
root.render(createElement(App, { commBus: this.commBus }));
|
||||
}
|
||||
}
|
||||
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
|
||||
this.commBus?.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('tfdidesign-md11-load-manager-panel', TFDiDesignMD11LoadManagerPanel);
|
||||
checkAutoload();
|
||||
10
PackageSources/js-bundle/src/types/theme.d.ts
vendored
Normal file
10
PackageSources/js-bundle/src/types/theme.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
import '@mui/material';
|
||||
|
||||
declare module '@mui/material/styles' {
|
||||
interface Theme {
|
||||
screenHeight: number;
|
||||
}
|
||||
interface ThemeOptions {
|
||||
screenHeight: number;
|
||||
}
|
||||
}
|
||||
11
PackageSources/js-bundle/src/types/virtual-scroll.d.ts
vendored
Normal file
11
PackageSources/js-bundle/src/types/virtual-scroll.d.ts
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
import { CSSProperties, DOMAttributes, ReactNode } from 'react';
|
||||
|
||||
type CustomElement<T> = Partial<T & DOMAttributes<T> & { children: ReactNode }>;
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface IntrinsicElements {
|
||||
['virtual-scroll']: CustomElement<{ class?: string; direction: 'x' | 'y'; style?: CSSProperties }>;
|
||||
}
|
||||
}
|
||||
}
|
||||
63
PackageSources/js-bundle/src/utils/TFDISBImport.ts
Normal file
63
PackageSources/js-bundle/src/utils/TFDISBImport.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import { PaxConfig } from '../configs/pax';
|
||||
import { SharedConfig } from '../configs/shared';
|
||||
|
||||
const getSimBriefFlightPlan = async (simBriefUsername: string) => {
|
||||
const flightPlanURL = `https://www.simbrief.com/api/xml.fetcher.php?username=${simBriefUsername}&json=1`;
|
||||
let response: Response;
|
||||
let success = false;
|
||||
try {
|
||||
response = await fetch(flightPlanURL);
|
||||
success = true;
|
||||
} catch (e: any) {
|
||||
response = e.response;
|
||||
}
|
||||
return {
|
||||
success,
|
||||
data: await response.json(),
|
||||
};
|
||||
};
|
||||
|
||||
export const ImportFlightPlan = async (
|
||||
username: string,
|
||||
config: typeof PaxConfig,
|
||||
unit: 'kg' | 'lbs',
|
||||
isER: boolean
|
||||
) => {
|
||||
const flightPlan = await getSimBriefFlightPlan(username);
|
||||
if (!flightPlan.success) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: flightPlan.data.status,
|
||||
};
|
||||
}
|
||||
|
||||
const data = flightPlan.data;
|
||||
|
||||
if (!['MD11', 'MD1F'].includes(data.aircraft.icao_code)) {
|
||||
return {
|
||||
type: 'error',
|
||||
message: `Your SimBrief plan is not for a MD-11`,
|
||||
};
|
||||
}
|
||||
|
||||
let convFactor = 1;
|
||||
if (data.params.units === 'kgs' && unit === 'lbs') convFactor = 2.20462262185;
|
||||
if (data.params.units === 'lbs' && unit === 'kg') convFactor = 1 / 2.20462262185;
|
||||
|
||||
return {
|
||||
type: 'data',
|
||||
message: {
|
||||
plannedZFW: Math.min(config.maxZWF[unit], Math.round(data.weights.est_zfw * convFactor)),
|
||||
plannedGW: Math.min(
|
||||
isER ? SharedConfig.maxTOW.er[unit] : SharedConfig.maxTOW.norm[unit],
|
||||
Math.round(data.weights.est_ramp * convFactor)
|
||||
),
|
||||
pax: data.weights.pax_count_actual,
|
||||
cargo: Math.round(data.weights.freight_added * convFactor),
|
||||
fuel: Math.min(
|
||||
isER ? SharedConfig.maxFuel.er[unit] : SharedConfig.maxFuel.norm[unit],
|
||||
Math.round(data.fuel.plan_ramp * convFactor)
|
||||
),
|
||||
},
|
||||
};
|
||||
};
|
||||
124
PackageSources/js-bundle/tsconfig.json
Normal file
124
PackageSources/js-bundle/tsconfig.json
Normal file
@ -0,0 +1,124 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Visit https://aka.ms/tsconfig to read more about this file */
|
||||
|
||||
/* Projects */
|
||||
"incremental": true,
|
||||
/* Save .tsbuildinfo files to allow for incremental compilation of projects. */
|
||||
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
|
||||
// "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */
|
||||
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */
|
||||
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
|
||||
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
||||
|
||||
/* Language and Environment */
|
||||
"target": "es6",
|
||||
/* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
|
||||
"lib": ["es2017", "dom"],
|
||||
/* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
||||
"jsx": "react-jsx",
|
||||
/* Specify what JSX code is generated. */
|
||||
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
|
||||
// "jsxFactory": "FSComponent.buildComponent", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
|
||||
// "jsxFragmentFactory": "FSComponent.Fragment", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
|
||||
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
|
||||
// "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
|
||||
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
|
||||
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
|
||||
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
||||
|
||||
/* Modules */
|
||||
"module": "es6",
|
||||
/* Specify what module code is generated. */
|
||||
// "rootDir": "./", /* Specify the root folder within your source files. */
|
||||
"moduleResolution": "node",
|
||||
/* Specify how TypeScript looks up a file from a given module specifier. */
|
||||
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
||||
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
||||
"rootDirs": [".", "__generated__"],
|
||||
/* Allow multiple folders to be treated as one when resolving modules. */
|
||||
// "typeRoots": [],
|
||||
/* Specify multiple folders that act like './node_modules/@types'. */
|
||||
//"types": [],
|
||||
/* Specify type package names to be included without being referenced in a source file. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
// "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */
|
||||
// "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
|
||||
// "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */
|
||||
// "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */
|
||||
// "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
|
||||
"resolveJsonModule": true,
|
||||
/* Enable importing .json files. */
|
||||
// "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */
|
||||
// "noResolve": true, /* Disallow 'import's, 'require's or '<reference>'s from expanding the number of files TypeScript should add to a project. */
|
||||
|
||||
/* JavaScript Support */
|
||||
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
|
||||
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
|
||||
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
|
||||
"outDir": "../html_ui/InGamePanels/tfdidesign-md11-load-manager-panel",
|
||||
/* Specify an output folder for all emitted files. */
|
||||
// "removeComments": true, /* Disable emitting comments. */
|
||||
// "noEmit": true, /* Disable emitting files from a compilation. */
|
||||
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
|
||||
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */
|
||||
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
|
||||
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
|
||||
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
|
||||
// "newLine": "crlf", /* Set the newline character for emitting files. */
|
||||
// "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
|
||||
// "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */
|
||||
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
|
||||
// "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */
|
||||
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
|
||||
// "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */
|
||||
|
||||
/* Interop Constraints */
|
||||
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
|
||||
// "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
|
||||
"esModuleInterop": true,
|
||||
/* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
|
||||
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
/* Ensure that casing is correct in imports. */
|
||||
|
||||
/* Type Checking */
|
||||
"strict": true,
|
||||
/* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */
|
||||
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
|
||||
// "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
|
||||
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
|
||||
// "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */
|
||||
// "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */
|
||||
"alwaysStrict": true,
|
||||
/* Ensure 'use strict' is always emitted. */
|
||||
// "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */
|
||||
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */
|
||||
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
|
||||
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
|
||||
// "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */
|
||||
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
|
||||
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */
|
||||
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
|
||||
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
|
||||
|
||||
/* Completeness */
|
||||
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
|
||||
"skipLibCheck": true /* Skip type checking all .d.ts files. */
|
||||
}
|
||||
}
|
||||
6015
PackageSources/js-bundle/yarn.lock
Normal file
6015
PackageSources/js-bundle/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,17 @@
|
||||
<SimBase.Document Type="InGamePanels" version="1,0">
|
||||
<Filename>tfdidesign-md11-load-manager.spb</Filename>
|
||||
<InGamePanels.InGamePanelDefinition
|
||||
id="TFDIDESIGN_MD11_LOAD_MANAGER_PANEL"
|
||||
Name="tfdidesign-md11-load-manager"
|
||||
url="html_UI/InGamePanels/tfdidesign-md11-load-manager-panel/index.html"
|
||||
resizeDirections="both"
|
||||
minWidth="100"
|
||||
minHeight="70"
|
||||
defaultWidth="100"
|
||||
defaultHeight="70"
|
||||
defaultTop="10"
|
||||
defaultLeft="10"
|
||||
icon="ICON_TFDIDESIGN_MD11_LOAD_MANAGER"
|
||||
buttonVisible="true">
|
||||
</InGamePanels.InGamePanelDefinition>
|
||||
</SimBase.Document>
|
||||
6
README.md
Normal file
6
README.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Sources
|
||||
|
||||
- https://www.boeing.com/content/dam/boeing/boeingdotcom/company/about_bca/startup/pdf/freighters/MD11BCF.pdf
|
||||
- LAMM
|
||||
- https://www.satco-inc.com/product-pallet/?part_number=31086-595
|
||||
- https://www.satco-inc.com/product-container/?part_number=34124-901
|
||||
65
WB MD-11 calc.txt
Normal file
65
WB MD-11 calc.txt
Normal file
@ -0,0 +1,65 @@
|
||||
F
|
||||
|
||||
MAC Pos as found in DEBUG: 24.16ft
|
||||
LEMAC Pos as found in DEBUG: -7.71ft
|
||||
|
||||
Empty weight
|
||||
Arm: -13.3ft
|
||||
Weight: 112748kg
|
||||
Moment: Arm * Weight = -1499548.4 kg*ft
|
||||
|
||||
77kg in Pilot station
|
||||
Arm: 82ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6314 kg*ft
|
||||
77kg in FO station
|
||||
Arm: 82ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6314 kg*ft
|
||||
77kg in FE station
|
||||
Arm: 80ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6160 kg*ft
|
||||
|
||||
Total:
|
||||
Weight: Sum = 112979kg
|
||||
Moment: Sum = -1480760.4 kg*ft
|
||||
CG: Moment / Weight = -13.11ft (-13.1065065189)
|
||||
|
||||
As %MAC
|
||||
abs(((CG - LEMAC) / MAC) * 100)
|
||||
abs(((-13.11 - -7.71) / 24.16) * 100)
|
||||
22.35
|
||||
|
||||
PAX
|
||||
|
||||
MAC Pos as found in DEBUG: 24.16ft
|
||||
LEMAC Pos as found in DEBUG: -7.71ft
|
||||
|
||||
Empty weight
|
||||
Arm: -13.3ft
|
||||
Weight: 128809kg
|
||||
Moment: Arm * Weight = -1713159.7 kg*ft
|
||||
|
||||
77kg in Pilot station
|
||||
Arm: 82ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6314 kg*ft
|
||||
77kg in FO station
|
||||
Arm: 82ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6314 kg*ft
|
||||
77kg in FE station
|
||||
Arm: 80ft
|
||||
Weight: 77kg
|
||||
Moment: Arm * Weight = 6160 kg*ft
|
||||
|
||||
Total:
|
||||
Weight: Sum = 129040kg
|
||||
Moment: Sum = -1694371.7 kg*ft
|
||||
CG: Moment / Weight = -13.13ft (-13.1305928394)
|
||||
|
||||
As %MAC
|
||||
abs(((CG - LEMAC) / MAC) * 100)
|
||||
abs(((-13.13 - -7.71) / 24.16) * 100)
|
||||
22.35
|
||||
8
xkhofmann-tfdidesign-md11-load-manager.code-workspace
Normal file
8
xkhofmann-tfdidesign-md11-load-manager.code-workspace
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"folders": [
|
||||
{
|
||||
"path": "."
|
||||
}
|
||||
],
|
||||
"settings": {}
|
||||
}
|
||||
11
xkhofmann-tfdidesign-md11-load-manager.xml
Normal file
11
xkhofmann-tfdidesign-md11-load-manager.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project Version="2" Name="xkhofmann-tfdidesign-md11-load-manager" FolderName="Packages" PublishingGroupFolderName="PublishingGroupsContent" MetadataFolderName="PackagesMetadata" PublishingGroupMetadataFolderName="PublishingGroupsMetadata">
|
||||
<OutputDirectory>.</OutputDirectory>
|
||||
<TemporaryOutputDirectory>_PackageInt</TemporaryOutputDirectory>
|
||||
<PublishingGroupTemporaryOutputDirectory>_PublishingGroupInt</PublishingGroupTemporaryOutputDirectory>
|
||||
<Packages>
|
||||
<Package>PackageDefinitions\xkhofmann-tfdidesign-md11-load-manager.xml</Package>
|
||||
</Packages>
|
||||
<PublishingGroups/>
|
||||
</Project>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user