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