From addb39022091f2fff16a5353a1809a5c26826aa1 Mon Sep 17 00:00:00 2001 From: ShiinaKuroko <208154746+ShiinaKuroko@users.noreply.github.com> Date: Sun, 2 Aug 2026 18:07:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(fleet):=20=E6=96=B0=E5=A2=9E=E5=8F=AF?= =?UTF-8?q?=E8=A7=86=E5=8C=96=E8=88=B0=E9=98=9F=E8=A7=84=E5=88=92=E4=B8=8E?= =?UTF-8?q?=E8=88=B0=E8=88=B9=E8=B5=84=E6=96=99=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main.ts | 711 +- electron/preload.ts | 33 + package.json | 7 + .../assets/backgrounds/rarity-1.webp | Bin 0 -> 13186 bytes .../assets/backgrounds/rarity-2.webp | Bin 0 -> 28136 bytes .../assets/backgrounds/rarity-3.webp | Bin 0 -> 28126 bytes .../assets/backgrounds/rarity-4.webp | Bin 0 -> 28236 bytes .../assets/backgrounds/rarity-5.webp | Bin 0 -> 31944 bytes .../assets/backgrounds/rarity-6.webp | Bin 0 -> 31358 bytes .../ship-library/assets/frames/rarity-1.webp | Bin 0 -> 5852 bytes .../ship-library/assets/frames/rarity-2.webp | Bin 0 -> 13590 bytes .../ship-library/assets/frames/rarity-3.webp | Bin 0 -> 14034 bytes .../ship-library/assets/frames/rarity-4.webp | Bin 0 -> 13652 bytes .../ship-library/assets/frames/rarity-5.webp | Bin 0 -> 15068 bytes .../ship-library/assets/frames/rarity-6.webp | Bin 0 -> 13474 bytes resource/ship-library/assets/portraits/1.webp | Bin 0 -> 30208 bytes .../ship-library/assets/portraits/10.webp | Bin 0 -> 20616 bytes .../ship-library/assets/portraits/100.webp | Bin 0 -> 25528 bytes .../ship-library/assets/portraits/1001.webp | Bin 0 -> 41054 bytes .../ship-library/assets/portraits/1002.webp | Bin 0 -> 30008 bytes .../ship-library/assets/portraits/1003.webp | Bin 0 -> 33626 bytes .../ship-library/assets/portraits/1004.webp | Bin 0 -> 27768 bytes .../ship-library/assets/portraits/1005.webp | Bin 0 -> 24502 bytes .../ship-library/assets/portraits/1006.webp | Bin 0 -> 38586 bytes .../ship-library/assets/portraits/1007.webp | Bin 0 -> 32936 bytes .../ship-library/assets/portraits/1008.webp | Bin 0 -> 33780 bytes .../ship-library/assets/portraits/1009.webp | Bin 0 -> 32110 bytes .../ship-library/assets/portraits/101.webp | Bin 0 -> 24162 bytes .../ship-library/assets/portraits/1010.webp | Bin 0 -> 24710 bytes .../ship-library/assets/portraits/1011.webp | Bin 0 -> 35786 bytes .../ship-library/assets/portraits/1012.webp | Bin 0 -> 34668 bytes .../ship-library/assets/portraits/1013.webp | Bin 0 -> 34082 bytes .../ship-library/assets/portraits/1014.webp | Bin 0 -> 24818 bytes .../ship-library/assets/portraits/1018.webp | Bin 0 -> 26016 bytes .../ship-library/assets/portraits/1019.webp | Bin 0 -> 20094 bytes .../ship-library/assets/portraits/102.webp | Bin 0 -> 25156 bytes .../ship-library/assets/portraits/1020.webp | Bin 0 -> 33184 bytes .../ship-library/assets/portraits/1021.webp | Bin 0 -> 35264 bytes .../ship-library/assets/portraits/1022.webp | Bin 0 -> 31228 bytes .../ship-library/assets/portraits/1023.webp | Bin 0 -> 30350 bytes .../ship-library/assets/portraits/1024.webp | Bin 0 -> 22992 bytes .../ship-library/assets/portraits/1025.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/1026.webp | Bin 0 -> 21028 bytes .../ship-library/assets/portraits/1027.webp | Bin 0 -> 31060 bytes .../ship-library/assets/portraits/1028.webp | Bin 0 -> 35960 bytes .../ship-library/assets/portraits/1029.webp | Bin 0 -> 20202 bytes .../ship-library/assets/portraits/103.webp | Bin 0 -> 30872 bytes .../ship-library/assets/portraits/1030.webp | Bin 0 -> 22694 bytes .../ship-library/assets/portraits/1031.webp | Bin 0 -> 30554 bytes .../ship-library/assets/portraits/1032.webp | Bin 0 -> 31634 bytes .../ship-library/assets/portraits/1033.webp | Bin 0 -> 29076 bytes .../ship-library/assets/portraits/1034.webp | Bin 0 -> 25408 bytes .../ship-library/assets/portraits/1035.webp | Bin 0 -> 24294 bytes .../ship-library/assets/portraits/1036.webp | Bin 0 -> 35808 bytes .../ship-library/assets/portraits/1037.webp | Bin 0 -> 33058 bytes .../ship-library/assets/portraits/1038.webp | Bin 0 -> 33310 bytes .../ship-library/assets/portraits/1039.webp | Bin 0 -> 25936 bytes .../ship-library/assets/portraits/104.webp | Bin 0 -> 24882 bytes .../ship-library/assets/portraits/1040.webp | Bin 0 -> 30464 bytes .../ship-library/assets/portraits/1041.webp | Bin 0 -> 27362 bytes .../ship-library/assets/portraits/1042.webp | Bin 0 -> 24184 bytes .../ship-library/assets/portraits/1043.webp | Bin 0 -> 31512 bytes .../ship-library/assets/portraits/1044.webp | Bin 0 -> 29472 bytes .../ship-library/assets/portraits/1045.webp | Bin 0 -> 21952 bytes .../ship-library/assets/portraits/1046.webp | Bin 0 -> 30054 bytes .../ship-library/assets/portraits/1047.webp | Bin 0 -> 26358 bytes .../ship-library/assets/portraits/1048.webp | Bin 0 -> 29064 bytes .../ship-library/assets/portraits/1049.webp | Bin 0 -> 31160 bytes .../ship-library/assets/portraits/105.webp | Bin 0 -> 32284 bytes .../ship-library/assets/portraits/1050.webp | Bin 0 -> 41794 bytes .../ship-library/assets/portraits/1054.webp | Bin 0 -> 46128 bytes .../ship-library/assets/portraits/1055.webp | Bin 0 -> 37704 bytes .../ship-library/assets/portraits/1056.webp | Bin 0 -> 38272 bytes .../ship-library/assets/portraits/1057.webp | Bin 0 -> 37668 bytes .../ship-library/assets/portraits/1058.webp | Bin 0 -> 32488 bytes .../ship-library/assets/portraits/1059.webp | Bin 0 -> 30884 bytes .../ship-library/assets/portraits/106.webp | Bin 0 -> 19910 bytes .../ship-library/assets/portraits/1060.webp | Bin 0 -> 33188 bytes .../ship-library/assets/portraits/1061.webp | Bin 0 -> 28348 bytes .../ship-library/assets/portraits/1062.webp | Bin 0 -> 28910 bytes .../ship-library/assets/portraits/1063.webp | Bin 0 -> 24522 bytes .../ship-library/assets/portraits/1064.webp | Bin 0 -> 26914 bytes .../ship-library/assets/portraits/1065.webp | Bin 0 -> 24672 bytes .../ship-library/assets/portraits/1066.webp | Bin 0 -> 21208 bytes .../ship-library/assets/portraits/1067.webp | Bin 0 -> 30274 bytes .../ship-library/assets/portraits/1068.webp | Bin 0 -> 24162 bytes .../ship-library/assets/portraits/1069.webp | Bin 0 -> 23582 bytes .../ship-library/assets/portraits/107.webp | Bin 0 -> 33430 bytes .../ship-library/assets/portraits/1070.webp | Bin 0 -> 26922 bytes .../ship-library/assets/portraits/1071.webp | Bin 0 -> 24228 bytes .../ship-library/assets/portraits/1072.webp | Bin 0 -> 23690 bytes .../ship-library/assets/portraits/1073.webp | Bin 0 -> 25878 bytes .../ship-library/assets/portraits/1074.webp | Bin 0 -> 34940 bytes .../ship-library/assets/portraits/1075.webp | Bin 0 -> 31070 bytes .../ship-library/assets/portraits/1076.webp | Bin 0 -> 28952 bytes .../ship-library/assets/portraits/1077.webp | Bin 0 -> 28578 bytes .../ship-library/assets/portraits/1079.webp | Bin 0 -> 24264 bytes .../ship-library/assets/portraits/108.webp | Bin 0 -> 28360 bytes .../ship-library/assets/portraits/1080.webp | Bin 0 -> 36064 bytes .../ship-library/assets/portraits/1081.webp | Bin 0 -> 27946 bytes .../ship-library/assets/portraits/1082.webp | Bin 0 -> 33558 bytes .../ship-library/assets/portraits/1083.webp | Bin 0 -> 32404 bytes .../ship-library/assets/portraits/1084.webp | Bin 0 -> 43242 bytes .../ship-library/assets/portraits/1085.webp | Bin 0 -> 35508 bytes .../ship-library/assets/portraits/1086.webp | Bin 0 -> 26842 bytes .../ship-library/assets/portraits/1087.webp | Bin 0 -> 24008 bytes .../ship-library/assets/portraits/1088.webp | Bin 0 -> 27006 bytes .../ship-library/assets/portraits/1089.webp | Bin 0 -> 26968 bytes .../ship-library/assets/portraits/109.webp | Bin 0 -> 28162 bytes .../ship-library/assets/portraits/1092.webp | Bin 0 -> 27104 bytes .../ship-library/assets/portraits/1093.webp | Bin 0 -> 33218 bytes .../ship-library/assets/portraits/1094.webp | Bin 0 -> 25014 bytes .../ship-library/assets/portraits/1097.webp | Bin 0 -> 28874 bytes .../ship-library/assets/portraits/1098.webp | Bin 0 -> 29776 bytes .../ship-library/assets/portraits/1099.webp | Bin 0 -> 29774 bytes .../ship-library/assets/portraits/11.webp | Bin 0 -> 34272 bytes .../ship-library/assets/portraits/110.webp | Bin 0 -> 30530 bytes .../ship-library/assets/portraits/1100.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/1101.webp | Bin 0 -> 28072 bytes .../ship-library/assets/portraits/1102.webp | Bin 0 -> 28510 bytes .../ship-library/assets/portraits/1105.webp | Bin 0 -> 32838 bytes .../ship-library/assets/portraits/1106.webp | Bin 0 -> 31562 bytes .../ship-library/assets/portraits/1107.webp | Bin 0 -> 33222 bytes .../ship-library/assets/portraits/1108.webp | Bin 0 -> 32634 bytes .../ship-library/assets/portraits/1109.webp | Bin 0 -> 36838 bytes .../ship-library/assets/portraits/111.webp | Bin 0 -> 28396 bytes .../ship-library/assets/portraits/1110.webp | Bin 0 -> 32010 bytes .../ship-library/assets/portraits/1111.webp | Bin 0 -> 36414 bytes .../ship-library/assets/portraits/1112.webp | Bin 0 -> 24310 bytes .../ship-library/assets/portraits/1113.webp | Bin 0 -> 41544 bytes .../ship-library/assets/portraits/1117.webp | Bin 0 -> 36682 bytes .../ship-library/assets/portraits/1118.webp | Bin 0 -> 33566 bytes .../ship-library/assets/portraits/112.webp | Bin 0 -> 31514 bytes .../ship-library/assets/portraits/1120.webp | Bin 0 -> 28996 bytes .../ship-library/assets/portraits/1121.webp | Bin 0 -> 31928 bytes .../ship-library/assets/portraits/1123.webp | Bin 0 -> 31476 bytes .../ship-library/assets/portraits/1124.webp | Bin 0 -> 26692 bytes .../ship-library/assets/portraits/1125.webp | Bin 0 -> 29882 bytes .../ship-library/assets/portraits/1126.webp | Bin 0 -> 26150 bytes .../ship-library/assets/portraits/113.webp | Bin 0 -> 46724 bytes .../ship-library/assets/portraits/1130.webp | Bin 0 -> 25876 bytes .../ship-library/assets/portraits/1131.webp | Bin 0 -> 27638 bytes .../ship-library/assets/portraits/1132.webp | Bin 0 -> 28670 bytes .../ship-library/assets/portraits/1133.webp | Bin 0 -> 26164 bytes .../ship-library/assets/portraits/1135.webp | Bin 0 -> 22660 bytes .../ship-library/assets/portraits/1136.webp | Bin 0 -> 22984 bytes .../ship-library/assets/portraits/1137.webp | Bin 0 -> 24820 bytes .../ship-library/assets/portraits/1139.webp | Bin 0 -> 23210 bytes .../ship-library/assets/portraits/114.webp | Bin 0 -> 32260 bytes .../ship-library/assets/portraits/1141.webp | Bin 0 -> 27196 bytes .../ship-library/assets/portraits/1142.webp | Bin 0 -> 25324 bytes .../ship-library/assets/portraits/1143.webp | Bin 0 -> 27820 bytes .../ship-library/assets/portraits/1145.webp | Bin 0 -> 29846 bytes .../ship-library/assets/portraits/1149.webp | Bin 0 -> 26296 bytes .../ship-library/assets/portraits/115.webp | Bin 0 -> 27100 bytes .../ship-library/assets/portraits/1150.webp | Bin 0 -> 30424 bytes .../ship-library/assets/portraits/1151.webp | Bin 0 -> 31774 bytes .../ship-library/assets/portraits/1158.webp | Bin 0 -> 38448 bytes .../ship-library/assets/portraits/1160.webp | Bin 0 -> 29064 bytes .../ship-library/assets/portraits/1162.webp | Bin 0 -> 24008 bytes .../ship-library/assets/portraits/1164.webp | Bin 0 -> 23296 bytes .../ship-library/assets/portraits/1165.webp | Bin 0 -> 22782 bytes .../ship-library/assets/portraits/1166.webp | Bin 0 -> 29536 bytes .../ship-library/assets/portraits/1167.webp | Bin 0 -> 33454 bytes .../ship-library/assets/portraits/1168.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/1169.webp | Bin 0 -> 25326 bytes .../ship-library/assets/portraits/117.webp | Bin 0 -> 34894 bytes .../ship-library/assets/portraits/1171.webp | Bin 0 -> 27564 bytes .../ship-library/assets/portraits/1175.webp | Bin 0 -> 36304 bytes .../ship-library/assets/portraits/1178.webp | Bin 0 -> 26838 bytes .../ship-library/assets/portraits/118.webp | Bin 0 -> 28902 bytes .../ship-library/assets/portraits/1181.webp | Bin 0 -> 31558 bytes .../ship-library/assets/portraits/1182.webp | Bin 0 -> 27414 bytes .../ship-library/assets/portraits/1183.webp | Bin 0 -> 22308 bytes .../ship-library/assets/portraits/1185.webp | Bin 0 -> 25756 bytes .../ship-library/assets/portraits/1187.webp | Bin 0 -> 32188 bytes .../ship-library/assets/portraits/1188.webp | Bin 0 -> 30856 bytes .../ship-library/assets/portraits/119.webp | Bin 0 -> 32408 bytes .../ship-library/assets/portraits/1192.webp | Bin 0 -> 26960 bytes .../ship-library/assets/portraits/1194.webp | Bin 0 -> 31256 bytes .../ship-library/assets/portraits/1195.webp | Bin 0 -> 29754 bytes .../ship-library/assets/portraits/1197.webp | Bin 0 -> 24928 bytes .../ship-library/assets/portraits/1198.webp | Bin 0 -> 24208 bytes .../ship-library/assets/portraits/1199.webp | Bin 0 -> 20344 bytes .../ship-library/assets/portraits/12.webp | Bin 0 -> 34658 bytes .../ship-library/assets/portraits/120.webp | Bin 0 -> 30704 bytes .../ship-library/assets/portraits/1205.webp | Bin 0 -> 26634 bytes .../ship-library/assets/portraits/1206.webp | Bin 0 -> 37438 bytes .../ship-library/assets/portraits/1207.webp | Bin 0 -> 26830 bytes .../ship-library/assets/portraits/1209.webp | Bin 0 -> 25176 bytes .../ship-library/assets/portraits/121.webp | Bin 0 -> 28992 bytes .../ship-library/assets/portraits/1211.webp | Bin 0 -> 35202 bytes .../ship-library/assets/portraits/1215.webp | Bin 0 -> 35168 bytes .../ship-library/assets/portraits/1219.webp | Bin 0 -> 30604 bytes .../ship-library/assets/portraits/122.webp | Bin 0 -> 29476 bytes .../ship-library/assets/portraits/1220.webp | Bin 0 -> 26766 bytes .../ship-library/assets/portraits/1221.webp | Bin 0 -> 30842 bytes .../ship-library/assets/portraits/1222.webp | Bin 0 -> 23038 bytes .../ship-library/assets/portraits/1223.webp | Bin 0 -> 30394 bytes .../ship-library/assets/portraits/1224.webp | Bin 0 -> 24046 bytes .../ship-library/assets/portraits/1225.webp | Bin 0 -> 28780 bytes .../ship-library/assets/portraits/1227.webp | Bin 0 -> 28808 bytes .../ship-library/assets/portraits/1228.webp | Bin 0 -> 31496 bytes .../ship-library/assets/portraits/123.webp | Bin 0 -> 22582 bytes .../ship-library/assets/portraits/1232.webp | Bin 0 -> 23152 bytes .../ship-library/assets/portraits/1233.webp | Bin 0 -> 27814 bytes .../ship-library/assets/portraits/1238.webp | Bin 0 -> 26166 bytes .../ship-library/assets/portraits/1239.webp | Bin 0 -> 28168 bytes .../ship-library/assets/portraits/124.webp | Bin 0 -> 25342 bytes .../ship-library/assets/portraits/1240.webp | Bin 0 -> 32494 bytes .../ship-library/assets/portraits/1241.webp | Bin 0 -> 34318 bytes .../ship-library/assets/portraits/1244.webp | Bin 0 -> 33450 bytes .../ship-library/assets/portraits/1247.webp | Bin 0 -> 30696 bytes .../ship-library/assets/portraits/1248.webp | Bin 0 -> 31468 bytes .../ship-library/assets/portraits/1249.webp | Bin 0 -> 26698 bytes .../ship-library/assets/portraits/125.webp | Bin 0 -> 28490 bytes .../ship-library/assets/portraits/1258.webp | Bin 0 -> 16656 bytes .../ship-library/assets/portraits/126.webp | Bin 0 -> 26022 bytes .../ship-library/assets/portraits/1265.webp | Bin 0 -> 29170 bytes .../ship-library/assets/portraits/1266.webp | Bin 0 -> 38296 bytes .../ship-library/assets/portraits/1267.webp | Bin 0 -> 35082 bytes .../ship-library/assets/portraits/1269.webp | Bin 0 -> 27256 bytes .../ship-library/assets/portraits/127.webp | Bin 0 -> 61178 bytes .../ship-library/assets/portraits/1270.webp | Bin 0 -> 26360 bytes .../ship-library/assets/portraits/1273.webp | Bin 0 -> 36416 bytes .../ship-library/assets/portraits/1275.webp | Bin 0 -> 25824 bytes .../ship-library/assets/portraits/1277.webp | Bin 0 -> 25872 bytes .../ship-library/assets/portraits/1278.webp | Bin 0 -> 32886 bytes .../ship-library/assets/portraits/1279.webp | Bin 0 -> 24278 bytes .../ship-library/assets/portraits/128.webp | Bin 0 -> 25288 bytes .../ship-library/assets/portraits/1280.webp | Bin 0 -> 29844 bytes .../ship-library/assets/portraits/1289.webp | Bin 0 -> 31412 bytes .../ship-library/assets/portraits/129.webp | Bin 0 -> 26448 bytes .../ship-library/assets/portraits/1290.webp | Bin 0 -> 32944 bytes .../ship-library/assets/portraits/1291.webp | Bin 0 -> 23606 bytes .../ship-library/assets/portraits/1293.webp | Bin 0 -> 27040 bytes .../ship-library/assets/portraits/1299.webp | Bin 0 -> 25088 bytes .../ship-library/assets/portraits/13.webp | Bin 0 -> 30448 bytes .../ship-library/assets/portraits/130.webp | Bin 0 -> 26966 bytes .../ship-library/assets/portraits/1301.webp | Bin 0 -> 30034 bytes .../ship-library/assets/portraits/1306.webp | Bin 0 -> 28374 bytes .../ship-library/assets/portraits/131.webp | Bin 0 -> 23212 bytes .../ship-library/assets/portraits/1311.webp | Bin 0 -> 31874 bytes .../ship-library/assets/portraits/1316.webp | Bin 0 -> 24794 bytes .../ship-library/assets/portraits/132.webp | Bin 0 -> 23228 bytes .../ship-library/assets/portraits/1323.webp | Bin 0 -> 32294 bytes .../ship-library/assets/portraits/1325.webp | Bin 0 -> 28528 bytes .../ship-library/assets/portraits/133.webp | Bin 0 -> 22446 bytes .../ship-library/assets/portraits/1332.webp | Bin 0 -> 23124 bytes .../ship-library/assets/portraits/1335.webp | Bin 0 -> 37438 bytes .../ship-library/assets/portraits/1339.webp | Bin 0 -> 30710 bytes .../ship-library/assets/portraits/134.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/1340.webp | Bin 0 -> 37824 bytes .../ship-library/assets/portraits/1342.webp | Bin 0 -> 25718 bytes .../ship-library/assets/portraits/1343.webp | Bin 0 -> 28280 bytes .../ship-library/assets/portraits/1344.webp | Bin 0 -> 24804 bytes .../ship-library/assets/portraits/135.webp | Bin 0 -> 20276 bytes .../ship-library/assets/portraits/1351.webp | Bin 0 -> 25034 bytes .../ship-library/assets/portraits/136.webp | Bin 0 -> 22682 bytes .../ship-library/assets/portraits/1362.webp | Bin 0 -> 36610 bytes .../ship-library/assets/portraits/1363.webp | Bin 0 -> 30176 bytes .../ship-library/assets/portraits/1366.webp | Bin 0 -> 28036 bytes .../ship-library/assets/portraits/137.webp | Bin 0 -> 23528 bytes .../ship-library/assets/portraits/1372.webp | Bin 0 -> 24082 bytes .../ship-library/assets/portraits/138.webp | Bin 0 -> 24318 bytes .../ship-library/assets/portraits/1380.webp | Bin 0 -> 29144 bytes .../ship-library/assets/portraits/139.webp | Bin 0 -> 25534 bytes .../ship-library/assets/portraits/14.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/140.webp | Bin 0 -> 25788 bytes .../ship-library/assets/portraits/1400.webp | Bin 0 -> 34502 bytes .../ship-library/assets/portraits/1408.webp | Bin 0 -> 34336 bytes .../ship-library/assets/portraits/141.webp | Bin 0 -> 25676 bytes .../ship-library/assets/portraits/1413.webp | Bin 0 -> 29660 bytes .../ship-library/assets/portraits/1414.webp | Bin 0 -> 33298 bytes .../ship-library/assets/portraits/1416.webp | Bin 0 -> 22106 bytes .../ship-library/assets/portraits/142.webp | Bin 0 -> 24832 bytes .../ship-library/assets/portraits/1425.webp | Bin 0 -> 25146 bytes .../ship-library/assets/portraits/1426.webp | Bin 0 -> 26452 bytes .../ship-library/assets/portraits/1429.webp | Bin 0 -> 47076 bytes .../ship-library/assets/portraits/143.webp | Bin 0 -> 24328 bytes .../ship-library/assets/portraits/1430.webp | Bin 0 -> 28578 bytes .../ship-library/assets/portraits/1431.webp | Bin 0 -> 30022 bytes .../ship-library/assets/portraits/144.webp | Bin 0 -> 32326 bytes .../ship-library/assets/portraits/145.webp | Bin 0 -> 22322 bytes .../ship-library/assets/portraits/1456.webp | Bin 0 -> 25460 bytes .../ship-library/assets/portraits/146.webp | Bin 0 -> 22308 bytes .../ship-library/assets/portraits/1467.webp | Bin 0 -> 23778 bytes .../ship-library/assets/portraits/147.webp | Bin 0 -> 24618 bytes .../ship-library/assets/portraits/148.webp | Bin 0 -> 22712 bytes .../ship-library/assets/portraits/1483.webp | Bin 0 -> 26266 bytes .../ship-library/assets/portraits/149.webp | Bin 0 -> 28102 bytes .../ship-library/assets/portraits/1490.webp | Bin 0 -> 25028 bytes .../ship-library/assets/portraits/1496.webp | Bin 0 -> 21638 bytes .../ship-library/assets/portraits/15.webp | Bin 0 -> 22540 bytes .../ship-library/assets/portraits/150.webp | Bin 0 -> 24686 bytes .../ship-library/assets/portraits/1503.webp | Bin 0 -> 25498 bytes .../ship-library/assets/portraits/1509.webp | Bin 0 -> 30930 bytes .../ship-library/assets/portraits/151.webp | Bin 0 -> 23620 bytes .../ship-library/assets/portraits/1516.webp | Bin 0 -> 39356 bytes .../ship-library/assets/portraits/1517.webp | Bin 0 -> 19560 bytes .../ship-library/assets/portraits/1519.webp | Bin 0 -> 28506 bytes .../ship-library/assets/portraits/152.webp | Bin 0 -> 29482 bytes .../ship-library/assets/portraits/1527.webp | Bin 0 -> 30416 bytes .../ship-library/assets/portraits/1528.webp | Bin 0 -> 30000 bytes .../ship-library/assets/portraits/153.webp | Bin 0 -> 34826 bytes .../ship-library/assets/portraits/1530.webp | Bin 0 -> 21030 bytes .../ship-library/assets/portraits/1532.webp | Bin 0 -> 42718 bytes .../ship-library/assets/portraits/1538.webp | Bin 0 -> 25218 bytes .../ship-library/assets/portraits/154.webp | Bin 0 -> 32200 bytes .../ship-library/assets/portraits/1545.webp | Bin 0 -> 20288 bytes .../ship-library/assets/portraits/155.webp | Bin 0 -> 36554 bytes .../ship-library/assets/portraits/156.webp | Bin 0 -> 31868 bytes .../ship-library/assets/portraits/1560.webp | Bin 0 -> 24616 bytes .../ship-library/assets/portraits/157.webp | Bin 0 -> 34990 bytes .../ship-library/assets/portraits/1575.webp | Bin 0 -> 35670 bytes .../ship-library/assets/portraits/158.webp | Bin 0 -> 36320 bytes .../ship-library/assets/portraits/1583.webp | Bin 0 -> 38250 bytes .../ship-library/assets/portraits/1589.webp | Bin 0 -> 29764 bytes .../ship-library/assets/portraits/159.webp | Bin 0 -> 31428 bytes .../ship-library/assets/portraits/1590.webp | Bin 0 -> 43408 bytes .../ship-library/assets/portraits/16.webp | Bin 0 -> 24616 bytes .../ship-library/assets/portraits/160.webp | Bin 0 -> 23116 bytes .../ship-library/assets/portraits/1606.webp | Bin 0 -> 25636 bytes .../ship-library/assets/portraits/161.webp | Bin 0 -> 21816 bytes .../ship-library/assets/portraits/1618.webp | Bin 0 -> 31544 bytes .../ship-library/assets/portraits/162.webp | Bin 0 -> 20100 bytes .../ship-library/assets/portraits/163.webp | Bin 0 -> 28618 bytes .../ship-library/assets/portraits/164.webp | Bin 0 -> 25700 bytes .../ship-library/assets/portraits/165.webp | Bin 0 -> 22600 bytes .../ship-library/assets/portraits/166.webp | Bin 0 -> 23484 bytes .../ship-library/assets/portraits/167.webp | Bin 0 -> 22106 bytes .../ship-library/assets/portraits/168.webp | Bin 0 -> 21904 bytes .../ship-library/assets/portraits/169.webp | Bin 0 -> 21182 bytes .../ship-library/assets/portraits/17.webp | Bin 0 -> 22674 bytes .../ship-library/assets/portraits/170.webp | Bin 0 -> 30146 bytes .../ship-library/assets/portraits/171.webp | Bin 0 -> 23076 bytes .../ship-library/assets/portraits/172.webp | Bin 0 -> 27840 bytes .../ship-library/assets/portraits/173.webp | Bin 0 -> 28798 bytes .../ship-library/assets/portraits/174.webp | Bin 0 -> 27120 bytes .../ship-library/assets/portraits/175.webp | Bin 0 -> 30088 bytes .../ship-library/assets/portraits/176.webp | Bin 0 -> 31104 bytes .../ship-library/assets/portraits/177.webp | Bin 0 -> 30750 bytes .../ship-library/assets/portraits/178.webp | Bin 0 -> 28314 bytes .../ship-library/assets/portraits/179.webp | Bin 0 -> 22772 bytes .../ship-library/assets/portraits/18.webp | Bin 0 -> 23884 bytes .../ship-library/assets/portraits/180.webp | Bin 0 -> 29206 bytes .../ship-library/assets/portraits/181.webp | Bin 0 -> 26394 bytes .../ship-library/assets/portraits/182.webp | Bin 0 -> 25256 bytes .../ship-library/assets/portraits/183.webp | Bin 0 -> 27652 bytes .../ship-library/assets/portraits/184.webp | Bin 0 -> 24572 bytes .../ship-library/assets/portraits/185.webp | Bin 0 -> 24252 bytes .../ship-library/assets/portraits/186.webp | Bin 0 -> 31960 bytes .../ship-library/assets/portraits/187.webp | Bin 0 -> 26042 bytes .../ship-library/assets/portraits/188.webp | Bin 0 -> 25290 bytes .../ship-library/assets/portraits/189.webp | Bin 0 -> 27468 bytes .../ship-library/assets/portraits/19.webp | Bin 0 -> 22000 bytes .../ship-library/assets/portraits/190.webp | Bin 0 -> 34090 bytes .../ship-library/assets/portraits/191.webp | Bin 0 -> 34996 bytes .../ship-library/assets/portraits/192.webp | Bin 0 -> 25026 bytes .../ship-library/assets/portraits/193.webp | Bin 0 -> 34028 bytes .../ship-library/assets/portraits/194.webp | Bin 0 -> 21148 bytes .../ship-library/assets/portraits/195.webp | Bin 0 -> 23788 bytes .../ship-library/assets/portraits/196.webp | Bin 0 -> 25322 bytes .../ship-library/assets/portraits/197.webp | Bin 0 -> 18314 bytes .../ship-library/assets/portraits/198.webp | Bin 0 -> 21760 bytes .../ship-library/assets/portraits/199.webp | Bin 0 -> 19268 bytes resource/ship-library/assets/portraits/2.webp | Bin 0 -> 23282 bytes .../ship-library/assets/portraits/20.webp | Bin 0 -> 37880 bytes .../ship-library/assets/portraits/200.webp | Bin 0 -> 26934 bytes .../ship-library/assets/portraits/201.webp | Bin 0 -> 34036 bytes .../ship-library/assets/portraits/202.webp | Bin 0 -> 20510 bytes .../ship-library/assets/portraits/203.webp | Bin 0 -> 21168 bytes .../ship-library/assets/portraits/205.webp | Bin 0 -> 21140 bytes .../ship-library/assets/portraits/206.webp | Bin 0 -> 28856 bytes .../ship-library/assets/portraits/207.webp | Bin 0 -> 35774 bytes .../ship-library/assets/portraits/208.webp | Bin 0 -> 33672 bytes .../ship-library/assets/portraits/209.webp | Bin 0 -> 26488 bytes .../ship-library/assets/portraits/21.webp | Bin 0 -> 32570 bytes .../ship-library/assets/portraits/210.webp | Bin 0 -> 21936 bytes .../ship-library/assets/portraits/211.webp | Bin 0 -> 30330 bytes .../ship-library/assets/portraits/212.webp | Bin 0 -> 25222 bytes .../ship-library/assets/portraits/213.webp | Bin 0 -> 25558 bytes .../ship-library/assets/portraits/214.webp | Bin 0 -> 29678 bytes .../ship-library/assets/portraits/215.webp | Bin 0 -> 32790 bytes .../ship-library/assets/portraits/216.webp | Bin 0 -> 33126 bytes .../ship-library/assets/portraits/217.webp | Bin 0 -> 30116 bytes .../ship-library/assets/portraits/218.webp | Bin 0 -> 24898 bytes .../ship-library/assets/portraits/219.webp | Bin 0 -> 30010 bytes .../ship-library/assets/portraits/22.webp | Bin 0 -> 26700 bytes .../ship-library/assets/portraits/220.webp | Bin 0 -> 29974 bytes .../ship-library/assets/portraits/221.webp | Bin 0 -> 24678 bytes .../ship-library/assets/portraits/222.webp | Bin 0 -> 21390 bytes .../ship-library/assets/portraits/223.webp | Bin 0 -> 26644 bytes .../ship-library/assets/portraits/224.webp | Bin 0 -> 27114 bytes .../ship-library/assets/portraits/225.webp | Bin 0 -> 31056 bytes .../ship-library/assets/portraits/226.webp | Bin 0 -> 35372 bytes .../ship-library/assets/portraits/227.webp | Bin 0 -> 25466 bytes .../ship-library/assets/portraits/228.webp | Bin 0 -> 30510 bytes .../ship-library/assets/portraits/229.webp | Bin 0 -> 24642 bytes .../ship-library/assets/portraits/23.webp | Bin 0 -> 26432 bytes .../ship-library/assets/portraits/230.webp | Bin 0 -> 23346 bytes .../ship-library/assets/portraits/231.webp | Bin 0 -> 18044 bytes .../ship-library/assets/portraits/232.webp | Bin 0 -> 30072 bytes .../ship-library/assets/portraits/233.webp | Bin 0 -> 26016 bytes .../ship-library/assets/portraits/234.webp | Bin 0 -> 22390 bytes .../ship-library/assets/portraits/235.webp | Bin 0 -> 25522 bytes .../ship-library/assets/portraits/236.webp | Bin 0 -> 21698 bytes .../ship-library/assets/portraits/237.webp | Bin 0 -> 25240 bytes .../ship-library/assets/portraits/238.webp | Bin 0 -> 29008 bytes .../ship-library/assets/portraits/239.webp | Bin 0 -> 27464 bytes .../ship-library/assets/portraits/24.webp | Bin 0 -> 27790 bytes .../ship-library/assets/portraits/240.webp | Bin 0 -> 29122 bytes .../ship-library/assets/portraits/241.webp | Bin 0 -> 30164 bytes .../ship-library/assets/portraits/242.webp | Bin 0 -> 18376 bytes .../ship-library/assets/portraits/243.webp | Bin 0 -> 26148 bytes .../ship-library/assets/portraits/244.webp | Bin 0 -> 35594 bytes .../ship-library/assets/portraits/245.webp | Bin 0 -> 29414 bytes .../ship-library/assets/portraits/246.webp | Bin 0 -> 26192 bytes .../ship-library/assets/portraits/247.webp | Bin 0 -> 26064 bytes .../ship-library/assets/portraits/248.webp | Bin 0 -> 32382 bytes .../ship-library/assets/portraits/249.webp | Bin 0 -> 25652 bytes .../ship-library/assets/portraits/25.webp | Bin 0 -> 30744 bytes .../ship-library/assets/portraits/250.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/251.webp | Bin 0 -> 30772 bytes .../ship-library/assets/portraits/252.webp | Bin 0 -> 25184 bytes .../ship-library/assets/portraits/253.webp | Bin 0 -> 29164 bytes .../ship-library/assets/portraits/254.webp | Bin 0 -> 28280 bytes .../ship-library/assets/portraits/255.webp | Bin 0 -> 32734 bytes .../ship-library/assets/portraits/256.webp | Bin 0 -> 29692 bytes .../ship-library/assets/portraits/257.webp | Bin 0 -> 34380 bytes .../ship-library/assets/portraits/258.webp | Bin 0 -> 20208 bytes .../ship-library/assets/portraits/259.webp | Bin 0 -> 31536 bytes .../ship-library/assets/portraits/26.webp | Bin 0 -> 24500 bytes .../ship-library/assets/portraits/260.webp | Bin 0 -> 30830 bytes .../ship-library/assets/portraits/261.webp | Bin 0 -> 25900 bytes .../ship-library/assets/portraits/262.webp | Bin 0 -> 25664 bytes .../ship-library/assets/portraits/263.webp | Bin 0 -> 27084 bytes .../ship-library/assets/portraits/264.webp | Bin 0 -> 30832 bytes .../ship-library/assets/portraits/265.webp | Bin 0 -> 28240 bytes .../ship-library/assets/portraits/266.webp | Bin 0 -> 28376 bytes .../ship-library/assets/portraits/267.webp | Bin 0 -> 28616 bytes .../ship-library/assets/portraits/268.webp | Bin 0 -> 17980 bytes .../ship-library/assets/portraits/269.webp | Bin 0 -> 21612 bytes .../ship-library/assets/portraits/27.webp | Bin 0 -> 23764 bytes .../ship-library/assets/portraits/270.webp | Bin 0 -> 23670 bytes .../ship-library/assets/portraits/271.webp | Bin 0 -> 28700 bytes .../ship-library/assets/portraits/272.webp | Bin 0 -> 26720 bytes .../ship-library/assets/portraits/273.webp | Bin 0 -> 29504 bytes .../ship-library/assets/portraits/274.webp | Bin 0 -> 35520 bytes .../ship-library/assets/portraits/275.webp | Bin 0 -> 29870 bytes .../ship-library/assets/portraits/276.webp | Bin 0 -> 30420 bytes .../ship-library/assets/portraits/277.webp | Bin 0 -> 31798 bytes .../ship-library/assets/portraits/278.webp | Bin 0 -> 28128 bytes .../ship-library/assets/portraits/279.webp | Bin 0 -> 22102 bytes .../ship-library/assets/portraits/28.webp | Bin 0 -> 37056 bytes .../ship-library/assets/portraits/280.webp | Bin 0 -> 28022 bytes .../ship-library/assets/portraits/281.webp | Bin 0 -> 24818 bytes .../ship-library/assets/portraits/282.webp | Bin 0 -> 24538 bytes .../ship-library/assets/portraits/283.webp | Bin 0 -> 25454 bytes .../ship-library/assets/portraits/284.webp | Bin 0 -> 26818 bytes .../ship-library/assets/portraits/285.webp | Bin 0 -> 32096 bytes .../ship-library/assets/portraits/286.webp | Bin 0 -> 36774 bytes .../ship-library/assets/portraits/287.webp | Bin 0 -> 35064 bytes .../ship-library/assets/portraits/288.webp | Bin 0 -> 30304 bytes .../ship-library/assets/portraits/289.webp | Bin 0 -> 20652 bytes .../ship-library/assets/portraits/29.webp | Bin 0 -> 22794 bytes .../ship-library/assets/portraits/290.webp | Bin 0 -> 28388 bytes .../ship-library/assets/portraits/291.webp | Bin 0 -> 27288 bytes .../ship-library/assets/portraits/292.webp | Bin 0 -> 25336 bytes .../ship-library/assets/portraits/293.webp | Bin 0 -> 16798 bytes .../ship-library/assets/portraits/294.webp | Bin 0 -> 24932 bytes .../ship-library/assets/portraits/295.webp | Bin 0 -> 26046 bytes .../ship-library/assets/portraits/296.webp | Bin 0 -> 20966 bytes .../ship-library/assets/portraits/297.webp | Bin 0 -> 35692 bytes .../ship-library/assets/portraits/298.webp | Bin 0 -> 30110 bytes .../ship-library/assets/portraits/299.webp | Bin 0 -> 24818 bytes resource/ship-library/assets/portraits/3.webp | Bin 0 -> 22694 bytes .../ship-library/assets/portraits/30.webp | Bin 0 -> 22546 bytes .../ship-library/assets/portraits/300.webp | Bin 0 -> 32252 bytes .../ship-library/assets/portraits/301.webp | Bin 0 -> 29390 bytes .../ship-library/assets/portraits/302.webp | Bin 0 -> 32802 bytes .../ship-library/assets/portraits/303.webp | Bin 0 -> 20022 bytes .../ship-library/assets/portraits/304.webp | Bin 0 -> 31212 bytes .../ship-library/assets/portraits/305.webp | Bin 0 -> 19560 bytes .../ship-library/assets/portraits/306.webp | Bin 0 -> 27464 bytes .../ship-library/assets/portraits/307.webp | Bin 0 -> 24932 bytes .../ship-library/assets/portraits/308.webp | Bin 0 -> 30164 bytes .../ship-library/assets/portraits/309.webp | Bin 0 -> 26800 bytes .../ship-library/assets/portraits/31.webp | Bin 0 -> 27862 bytes .../ship-library/assets/portraits/310.webp | Bin 0 -> 37930 bytes .../ship-library/assets/portraits/311.webp | Bin 0 -> 26074 bytes .../ship-library/assets/portraits/312.webp | Bin 0 -> 24340 bytes .../ship-library/assets/portraits/313.webp | Bin 0 -> 25816 bytes .../ship-library/assets/portraits/314.webp | Bin 0 -> 28268 bytes .../ship-library/assets/portraits/315.webp | Bin 0 -> 24726 bytes .../ship-library/assets/portraits/316.webp | Bin 0 -> 28636 bytes .../ship-library/assets/portraits/317.webp | Bin 0 -> 24538 bytes .../ship-library/assets/portraits/318.webp | Bin 0 -> 26082 bytes .../ship-library/assets/portraits/319.webp | Bin 0 -> 28908 bytes .../ship-library/assets/portraits/32.webp | Bin 0 -> 31790 bytes .../ship-library/assets/portraits/320.webp | Bin 0 -> 30090 bytes .../ship-library/assets/portraits/321.webp | Bin 0 -> 26432 bytes .../ship-library/assets/portraits/322.webp | Bin 0 -> 27198 bytes .../ship-library/assets/portraits/323.webp | Bin 0 -> 28630 bytes .../ship-library/assets/portraits/324.webp | Bin 0 -> 30048 bytes .../ship-library/assets/portraits/325.webp | Bin 0 -> 21786 bytes .../ship-library/assets/portraits/326.webp | Bin 0 -> 23168 bytes .../ship-library/assets/portraits/327.webp | Bin 0 -> 31076 bytes .../ship-library/assets/portraits/328.webp | Bin 0 -> 22162 bytes .../ship-library/assets/portraits/329.webp | Bin 0 -> 24912 bytes .../ship-library/assets/portraits/33.webp | Bin 0 -> 27896 bytes .../ship-library/assets/portraits/330.webp | Bin 0 -> 32966 bytes .../ship-library/assets/portraits/331.webp | Bin 0 -> 25308 bytes .../ship-library/assets/portraits/332.webp | Bin 0 -> 30428 bytes .../ship-library/assets/portraits/333.webp | Bin 0 -> 31378 bytes .../ship-library/assets/portraits/334.webp | Bin 0 -> 32860 bytes .../ship-library/assets/portraits/335.webp | Bin 0 -> 32870 bytes .../ship-library/assets/portraits/336.webp | Bin 0 -> 25262 bytes .../ship-library/assets/portraits/337.webp | Bin 0 -> 23844 bytes .../ship-library/assets/portraits/338.webp | Bin 0 -> 32346 bytes .../ship-library/assets/portraits/339.webp | Bin 0 -> 24902 bytes .../ship-library/assets/portraits/34.webp | Bin 0 -> 26068 bytes .../ship-library/assets/portraits/340.webp | Bin 0 -> 27870 bytes .../ship-library/assets/portraits/341.webp | Bin 0 -> 34736 bytes .../ship-library/assets/portraits/342.webp | Bin 0 -> 27126 bytes .../ship-library/assets/portraits/343.webp | Bin 0 -> 32386 bytes .../ship-library/assets/portraits/344.webp | Bin 0 -> 27560 bytes .../ship-library/assets/portraits/345.webp | Bin 0 -> 22148 bytes .../ship-library/assets/portraits/346.webp | Bin 0 -> 30886 bytes .../ship-library/assets/portraits/347.webp | Bin 0 -> 25042 bytes .../ship-library/assets/portraits/348.webp | Bin 0 -> 30608 bytes .../ship-library/assets/portraits/349.webp | Bin 0 -> 26136 bytes .../ship-library/assets/portraits/35.webp | Bin 0 -> 24498 bytes .../ship-library/assets/portraits/350.webp | Bin 0 -> 25216 bytes .../ship-library/assets/portraits/351.webp | Bin 0 -> 26874 bytes .../ship-library/assets/portraits/352.webp | Bin 0 -> 25798 bytes .../ship-library/assets/portraits/353.webp | Bin 0 -> 26884 bytes .../ship-library/assets/portraits/354.webp | Bin 0 -> 27292 bytes .../ship-library/assets/portraits/355.webp | Bin 0 -> 30216 bytes .../ship-library/assets/portraits/356.webp | Bin 0 -> 37276 bytes .../ship-library/assets/portraits/357.webp | Bin 0 -> 24652 bytes .../ship-library/assets/portraits/358.webp | Bin 0 -> 29576 bytes .../ship-library/assets/portraits/359.webp | Bin 0 -> 25474 bytes .../ship-library/assets/portraits/36.webp | Bin 0 -> 24378 bytes .../ship-library/assets/portraits/360.webp | Bin 0 -> 24286 bytes .../ship-library/assets/portraits/361.webp | Bin 0 -> 24062 bytes .../ship-library/assets/portraits/362.webp | Bin 0 -> 29342 bytes .../ship-library/assets/portraits/363.webp | Bin 0 -> 23172 bytes .../ship-library/assets/portraits/364.webp | Bin 0 -> 25330 bytes .../ship-library/assets/portraits/365.webp | Bin 0 -> 28558 bytes .../ship-library/assets/portraits/366.webp | Bin 0 -> 26502 bytes .../ship-library/assets/portraits/367.webp | Bin 0 -> 21154 bytes .../ship-library/assets/portraits/368.webp | Bin 0 -> 35742 bytes .../ship-library/assets/portraits/369.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/37.webp | Bin 0 -> 28122 bytes .../ship-library/assets/portraits/370.webp | Bin 0 -> 24588 bytes .../ship-library/assets/portraits/371.webp | Bin 0 -> 24412 bytes .../ship-library/assets/portraits/372.webp | Bin 0 -> 29384 bytes .../ship-library/assets/portraits/373.webp | Bin 0 -> 27952 bytes .../ship-library/assets/portraits/374.webp | Bin 0 -> 21736 bytes .../ship-library/assets/portraits/375.webp | Bin 0 -> 24496 bytes .../ship-library/assets/portraits/376.webp | Bin 0 -> 27986 bytes .../ship-library/assets/portraits/377.webp | Bin 0 -> 30650 bytes .../ship-library/assets/portraits/378.webp | Bin 0 -> 30706 bytes .../ship-library/assets/portraits/379.webp | Bin 0 -> 28314 bytes .../ship-library/assets/portraits/38.webp | Bin 0 -> 26138 bytes .../ship-library/assets/portraits/380.webp | Bin 0 -> 27962 bytes .../ship-library/assets/portraits/381.webp | Bin 0 -> 29078 bytes .../ship-library/assets/portraits/382.webp | Bin 0 -> 29698 bytes .../ship-library/assets/portraits/383.webp | Bin 0 -> 28012 bytes .../ship-library/assets/portraits/384.webp | Bin 0 -> 25374 bytes .../ship-library/assets/portraits/385.webp | Bin 0 -> 29528 bytes .../ship-library/assets/portraits/386.webp | Bin 0 -> 28996 bytes .../ship-library/assets/portraits/387.webp | Bin 0 -> 31964 bytes .../ship-library/assets/portraits/388.webp | Bin 0 -> 28302 bytes .../ship-library/assets/portraits/389.webp | Bin 0 -> 30570 bytes .../ship-library/assets/portraits/39.webp | Bin 0 -> 26136 bytes .../ship-library/assets/portraits/390.webp | Bin 0 -> 27122 bytes .../ship-library/assets/portraits/391.webp | Bin 0 -> 23376 bytes .../ship-library/assets/portraits/392.webp | Bin 0 -> 32852 bytes .../ship-library/assets/portraits/393.webp | Bin 0 -> 24876 bytes .../ship-library/assets/portraits/394.webp | Bin 0 -> 35284 bytes .../ship-library/assets/portraits/395.webp | Bin 0 -> 28764 bytes .../ship-library/assets/portraits/396.webp | Bin 0 -> 24406 bytes .../ship-library/assets/portraits/397.webp | Bin 0 -> 23722 bytes .../ship-library/assets/portraits/398.webp | Bin 0 -> 32656 bytes .../ship-library/assets/portraits/399.webp | Bin 0 -> 25018 bytes resource/ship-library/assets/portraits/4.webp | Bin 0 -> 26932 bytes .../ship-library/assets/portraits/40.webp | Bin 0 -> 33582 bytes .../ship-library/assets/portraits/400.webp | Bin 0 -> 25846 bytes .../ship-library/assets/portraits/401.webp | Bin 0 -> 23986 bytes .../ship-library/assets/portraits/402.webp | Bin 0 -> 23166 bytes .../ship-library/assets/portraits/403.webp | Bin 0 -> 36522 bytes .../ship-library/assets/portraits/404.webp | Bin 0 -> 26866 bytes .../ship-library/assets/portraits/405.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/406.webp | Bin 0 -> 27378 bytes .../ship-library/assets/portraits/407.webp | Bin 0 -> 20218 bytes .../ship-library/assets/portraits/408.webp | Bin 0 -> 32128 bytes .../ship-library/assets/portraits/409.webp | Bin 0 -> 23390 bytes .../ship-library/assets/portraits/41.webp | Bin 0 -> 25008 bytes .../ship-library/assets/portraits/410.webp | Bin 0 -> 32090 bytes .../ship-library/assets/portraits/411.webp | Bin 0 -> 23320 bytes .../ship-library/assets/portraits/412.webp | Bin 0 -> 25160 bytes .../ship-library/assets/portraits/413.webp | Bin 0 -> 31812 bytes .../ship-library/assets/portraits/414.webp | Bin 0 -> 30080 bytes .../ship-library/assets/portraits/415.webp | Bin 0 -> 29210 bytes .../ship-library/assets/portraits/416.webp | Bin 0 -> 26704 bytes .../ship-library/assets/portraits/417.webp | Bin 0 -> 34176 bytes .../ship-library/assets/portraits/418.webp | Bin 0 -> 31398 bytes .../ship-library/assets/portraits/419.webp | Bin 0 -> 21242 bytes .../ship-library/assets/portraits/42.webp | Bin 0 -> 23498 bytes .../ship-library/assets/portraits/420.webp | Bin 0 -> 20842 bytes .../ship-library/assets/portraits/421.webp | Bin 0 -> 23866 bytes .../ship-library/assets/portraits/422.webp | Bin 0 -> 44568 bytes .../ship-library/assets/portraits/423.webp | Bin 0 -> 25284 bytes .../ship-library/assets/portraits/424.webp | Bin 0 -> 28918 bytes .../ship-library/assets/portraits/425.webp | Bin 0 -> 24960 bytes .../ship-library/assets/portraits/426.webp | Bin 0 -> 27946 bytes .../ship-library/assets/portraits/427.webp | Bin 0 -> 26800 bytes .../ship-library/assets/portraits/428.webp | Bin 0 -> 23434 bytes .../ship-library/assets/portraits/429.webp | Bin 0 -> 26978 bytes .../ship-library/assets/portraits/43.webp | Bin 0 -> 32106 bytes .../ship-library/assets/portraits/430.webp | Bin 0 -> 23952 bytes .../ship-library/assets/portraits/431.webp | Bin 0 -> 31730 bytes .../ship-library/assets/portraits/432.webp | Bin 0 -> 25982 bytes .../ship-library/assets/portraits/433.webp | Bin 0 -> 23500 bytes .../ship-library/assets/portraits/434.webp | Bin 0 -> 34382 bytes .../ship-library/assets/portraits/435.webp | Bin 0 -> 36034 bytes .../ship-library/assets/portraits/436.webp | Bin 0 -> 24180 bytes .../ship-library/assets/portraits/437.webp | Bin 0 -> 28078 bytes .../ship-library/assets/portraits/438.webp | Bin 0 -> 23810 bytes .../ship-library/assets/portraits/439.webp | Bin 0 -> 21790 bytes .../ship-library/assets/portraits/44.webp | Bin 0 -> 29618 bytes .../ship-library/assets/portraits/440.webp | Bin 0 -> 30026 bytes .../ship-library/assets/portraits/441.webp | Bin 0 -> 37398 bytes .../ship-library/assets/portraits/442.webp | Bin 0 -> 25080 bytes .../ship-library/assets/portraits/443.webp | Bin 0 -> 21638 bytes .../ship-library/assets/portraits/444.webp | Bin 0 -> 25090 bytes .../ship-library/assets/portraits/445.webp | Bin 0 -> 28474 bytes .../ship-library/assets/portraits/446.webp | Bin 0 -> 37192 bytes .../ship-library/assets/portraits/447.webp | Bin 0 -> 27344 bytes .../ship-library/assets/portraits/448.webp | Bin 0 -> 31044 bytes .../ship-library/assets/portraits/449.webp | Bin 0 -> 30430 bytes .../ship-library/assets/portraits/45.webp | Bin 0 -> 21870 bytes .../ship-library/assets/portraits/450.webp | Bin 0 -> 28762 bytes .../ship-library/assets/portraits/451.webp | Bin 0 -> 26612 bytes .../ship-library/assets/portraits/452.webp | Bin 0 -> 27798 bytes .../ship-library/assets/portraits/453.webp | Bin 0 -> 22840 bytes .../ship-library/assets/portraits/454.webp | Bin 0 -> 33464 bytes .../ship-library/assets/portraits/455.webp | Bin 0 -> 32192 bytes .../ship-library/assets/portraits/456.webp | Bin 0 -> 28576 bytes .../ship-library/assets/portraits/457.webp | Bin 0 -> 28188 bytes .../ship-library/assets/portraits/458.webp | Bin 0 -> 26368 bytes .../ship-library/assets/portraits/459.webp | Bin 0 -> 27138 bytes .../ship-library/assets/portraits/46.webp | Bin 0 -> 28326 bytes .../ship-library/assets/portraits/460.webp | Bin 0 -> 22520 bytes .../ship-library/assets/portraits/461.webp | Bin 0 -> 21376 bytes .../ship-library/assets/portraits/462.webp | Bin 0 -> 29496 bytes .../ship-library/assets/portraits/463.webp | Bin 0 -> 27844 bytes .../ship-library/assets/portraits/464.webp | Bin 0 -> 28918 bytes .../ship-library/assets/portraits/465.webp | Bin 0 -> 22356 bytes .../ship-library/assets/portraits/466.webp | Bin 0 -> 42452 bytes .../ship-library/assets/portraits/467.webp | Bin 0 -> 31368 bytes .../ship-library/assets/portraits/468.webp | Bin 0 -> 26764 bytes .../ship-library/assets/portraits/469.webp | Bin 0 -> 21820 bytes .../ship-library/assets/portraits/47.webp | Bin 0 -> 23986 bytes .../ship-library/assets/portraits/470.webp | Bin 0 -> 29878 bytes .../ship-library/assets/portraits/471.webp | Bin 0 -> 27320 bytes .../ship-library/assets/portraits/472.webp | Bin 0 -> 20214 bytes .../ship-library/assets/portraits/473.webp | Bin 0 -> 28632 bytes .../ship-library/assets/portraits/474.webp | Bin 0 -> 25960 bytes .../ship-library/assets/portraits/475.webp | Bin 0 -> 25622 bytes .../ship-library/assets/portraits/476.webp | Bin 0 -> 31550 bytes .../ship-library/assets/portraits/477.webp | Bin 0 -> 26088 bytes .../ship-library/assets/portraits/478.webp | Bin 0 -> 25226 bytes .../ship-library/assets/portraits/479.webp | Bin 0 -> 25288 bytes .../ship-library/assets/portraits/48.webp | Bin 0 -> 23930 bytes .../ship-library/assets/portraits/480.webp | Bin 0 -> 30432 bytes .../ship-library/assets/portraits/481.webp | Bin 0 -> 36094 bytes .../ship-library/assets/portraits/482.webp | Bin 0 -> 31274 bytes .../ship-library/assets/portraits/483.webp | Bin 0 -> 20248 bytes .../ship-library/assets/portraits/484.webp | Bin 0 -> 34368 bytes .../ship-library/assets/portraits/485.webp | Bin 0 -> 27672 bytes .../ship-library/assets/portraits/486.webp | Bin 0 -> 34964 bytes .../ship-library/assets/portraits/487.webp | Bin 0 -> 24584 bytes .../ship-library/assets/portraits/488.webp | Bin 0 -> 27482 bytes .../ship-library/assets/portraits/489.webp | Bin 0 -> 22930 bytes .../ship-library/assets/portraits/49.webp | Bin 0 -> 27852 bytes .../ship-library/assets/portraits/490.webp | Bin 0 -> 21884 bytes .../ship-library/assets/portraits/491.webp | Bin 0 -> 29002 bytes .../ship-library/assets/portraits/492.webp | Bin 0 -> 30466 bytes .../ship-library/assets/portraits/493.webp | Bin 0 -> 22612 bytes .../ship-library/assets/portraits/494.webp | Bin 0 -> 39468 bytes .../ship-library/assets/portraits/495.webp | Bin 0 -> 28182 bytes .../ship-library/assets/portraits/496.webp | Bin 0 -> 22744 bytes .../ship-library/assets/portraits/497.webp | Bin 0 -> 25392 bytes .../ship-library/assets/portraits/498.webp | Bin 0 -> 22922 bytes .../ship-library/assets/portraits/499.webp | Bin 0 -> 30946 bytes resource/ship-library/assets/portraits/5.webp | Bin 0 -> 25872 bytes .../ship-library/assets/portraits/50.webp | Bin 0 -> 34618 bytes .../ship-library/assets/portraits/500.webp | Bin 0 -> 23246 bytes .../ship-library/assets/portraits/501.webp | Bin 0 -> 31396 bytes .../ship-library/assets/portraits/502.webp | Bin 0 -> 29866 bytes .../ship-library/assets/portraits/503.webp | Bin 0 -> 26034 bytes .../ship-library/assets/portraits/504.webp | Bin 0 -> 23254 bytes .../ship-library/assets/portraits/505.webp | Bin 0 -> 24948 bytes .../ship-library/assets/portraits/506.webp | Bin 0 -> 26762 bytes .../ship-library/assets/portraits/507.webp | Bin 0 -> 31442 bytes .../ship-library/assets/portraits/508.webp | Bin 0 -> 21622 bytes .../ship-library/assets/portraits/509.webp | Bin 0 -> 31002 bytes .../ship-library/assets/portraits/51.webp | Bin 0 -> 24680 bytes .../ship-library/assets/portraits/510.webp | Bin 0 -> 27458 bytes .../ship-library/assets/portraits/511.webp | Bin 0 -> 43710 bytes .../ship-library/assets/portraits/512.webp | Bin 0 -> 26964 bytes .../ship-library/assets/portraits/513.webp | Bin 0 -> 21436 bytes .../ship-library/assets/portraits/514.webp | Bin 0 -> 27456 bytes .../ship-library/assets/portraits/515.webp | Bin 0 -> 26392 bytes .../ship-library/assets/portraits/516.webp | Bin 0 -> 24254 bytes .../ship-library/assets/portraits/517.webp | Bin 0 -> 22312 bytes .../ship-library/assets/portraits/518.webp | Bin 0 -> 20750 bytes .../ship-library/assets/portraits/519.webp | Bin 0 -> 23264 bytes .../ship-library/assets/portraits/52.webp | Bin 0 -> 22140 bytes .../ship-library/assets/portraits/520.webp | Bin 0 -> 24468 bytes .../ship-library/assets/portraits/521.webp | Bin 0 -> 28268 bytes .../ship-library/assets/portraits/522.webp | Bin 0 -> 27630 bytes .../ship-library/assets/portraits/523.webp | Bin 0 -> 28032 bytes .../ship-library/assets/portraits/524.webp | Bin 0 -> 27420 bytes .../ship-library/assets/portraits/525.webp | Bin 0 -> 26868 bytes .../ship-library/assets/portraits/526.webp | Bin 0 -> 25622 bytes .../ship-library/assets/portraits/527.webp | Bin 0 -> 23680 bytes .../ship-library/assets/portraits/528.webp | Bin 0 -> 24810 bytes .../ship-library/assets/portraits/529.webp | Bin 0 -> 44324 bytes .../ship-library/assets/portraits/53.webp | Bin 0 -> 23978 bytes .../ship-library/assets/portraits/530.webp | Bin 0 -> 24034 bytes .../ship-library/assets/portraits/531.webp | Bin 0 -> 28776 bytes .../ship-library/assets/portraits/532.webp | Bin 0 -> 42432 bytes .../ship-library/assets/portraits/533.webp | Bin 0 -> 22546 bytes .../ship-library/assets/portraits/534.webp | Bin 0 -> 20226 bytes .../ship-library/assets/portraits/535.webp | Bin 0 -> 26296 bytes .../ship-library/assets/portraits/536.webp | Bin 0 -> 28310 bytes .../ship-library/assets/portraits/537.webp | Bin 0 -> 27700 bytes .../ship-library/assets/portraits/538.webp | Bin 0 -> 24104 bytes .../ship-library/assets/portraits/539.webp | Bin 0 -> 23318 bytes .../ship-library/assets/portraits/54.webp | Bin 0 -> 28038 bytes .../ship-library/assets/portraits/540.webp | Bin 0 -> 21152 bytes .../ship-library/assets/portraits/541.webp | Bin 0 -> 27772 bytes .../ship-library/assets/portraits/542.webp | Bin 0 -> 22584 bytes .../ship-library/assets/portraits/543.webp | Bin 0 -> 25596 bytes .../ship-library/assets/portraits/544.webp | Bin 0 -> 37336 bytes .../ship-library/assets/portraits/545.webp | Bin 0 -> 22276 bytes .../ship-library/assets/portraits/546.webp | Bin 0 -> 19084 bytes .../ship-library/assets/portraits/547.webp | Bin 0 -> 22712 bytes .../ship-library/assets/portraits/548.webp | Bin 0 -> 25520 bytes .../ship-library/assets/portraits/549.webp | Bin 0 -> 36898 bytes .../ship-library/assets/portraits/55.webp | Bin 0 -> 27390 bytes .../ship-library/assets/portraits/550.webp | Bin 0 -> 32320 bytes .../ship-library/assets/portraits/551.webp | Bin 0 -> 21832 bytes .../ship-library/assets/portraits/552.webp | Bin 0 -> 31106 bytes .../ship-library/assets/portraits/553.webp | Bin 0 -> 26000 bytes .../ship-library/assets/portraits/554.webp | Bin 0 -> 27126 bytes .../ship-library/assets/portraits/555.webp | Bin 0 -> 26008 bytes .../ship-library/assets/portraits/556.webp | Bin 0 -> 27860 bytes .../ship-library/assets/portraits/557.webp | Bin 0 -> 22808 bytes .../ship-library/assets/portraits/558.webp | Bin 0 -> 30576 bytes .../ship-library/assets/portraits/559.webp | Bin 0 -> 28696 bytes .../ship-library/assets/portraits/56.webp | Bin 0 -> 50450 bytes .../ship-library/assets/portraits/560.webp | Bin 0 -> 23172 bytes .../ship-library/assets/portraits/561.webp | Bin 0 -> 17094 bytes .../ship-library/assets/portraits/562.webp | Bin 0 -> 26750 bytes .../ship-library/assets/portraits/563.webp | Bin 0 -> 17706 bytes .../ship-library/assets/portraits/564.webp | Bin 0 -> 33336 bytes .../ship-library/assets/portraits/565.webp | Bin 0 -> 25912 bytes .../ship-library/assets/portraits/566.webp | Bin 0 -> 33850 bytes .../ship-library/assets/portraits/567.webp | Bin 0 -> 23296 bytes .../ship-library/assets/portraits/568.webp | Bin 0 -> 26086 bytes .../ship-library/assets/portraits/569.webp | Bin 0 -> 36840 bytes .../ship-library/assets/portraits/57.webp | Bin 0 -> 30828 bytes .../ship-library/assets/portraits/570.webp | Bin 0 -> 28182 bytes .../ship-library/assets/portraits/571.webp | Bin 0 -> 27998 bytes .../ship-library/assets/portraits/572.webp | Bin 0 -> 31886 bytes .../ship-library/assets/portraits/573.webp | Bin 0 -> 33154 bytes .../ship-library/assets/portraits/574.webp | Bin 0 -> 23038 bytes .../ship-library/assets/portraits/575.webp | Bin 0 -> 30414 bytes .../ship-library/assets/portraits/576.webp | Bin 0 -> 28682 bytes .../ship-library/assets/portraits/577.webp | Bin 0 -> 39244 bytes .../ship-library/assets/portraits/578.webp | Bin 0 -> 24314 bytes .../ship-library/assets/portraits/579.webp | Bin 0 -> 35716 bytes .../ship-library/assets/portraits/58.webp | Bin 0 -> 27534 bytes .../ship-library/assets/portraits/580.webp | Bin 0 -> 26690 bytes .../ship-library/assets/portraits/581.webp | Bin 0 -> 30094 bytes .../ship-library/assets/portraits/582.webp | Bin 0 -> 38840 bytes .../ship-library/assets/portraits/583.webp | Bin 0 -> 46704 bytes .../ship-library/assets/portraits/584.webp | Bin 0 -> 34422 bytes .../ship-library/assets/portraits/585.webp | Bin 0 -> 34798 bytes .../ship-library/assets/portraits/586.webp | Bin 0 -> 25130 bytes .../ship-library/assets/portraits/587.webp | Bin 0 -> 31274 bytes .../ship-library/assets/portraits/588.webp | Bin 0 -> 28470 bytes .../ship-library/assets/portraits/589.webp | Bin 0 -> 27626 bytes .../ship-library/assets/portraits/59.webp | Bin 0 -> 22924 bytes .../ship-library/assets/portraits/590.webp | Bin 0 -> 30690 bytes .../ship-library/assets/portraits/591.webp | Bin 0 -> 24992 bytes .../ship-library/assets/portraits/592.webp | Bin 0 -> 25540 bytes .../ship-library/assets/portraits/593.webp | Bin 0 -> 22276 bytes .../ship-library/assets/portraits/594.webp | Bin 0 -> 29772 bytes .../ship-library/assets/portraits/595.webp | Bin 0 -> 27062 bytes .../ship-library/assets/portraits/596.webp | Bin 0 -> 39148 bytes .../ship-library/assets/portraits/597.webp | Bin 0 -> 30294 bytes .../ship-library/assets/portraits/598.webp | Bin 0 -> 24104 bytes .../ship-library/assets/portraits/599.webp | Bin 0 -> 33272 bytes resource/ship-library/assets/portraits/6.webp | Bin 0 -> 27070 bytes .../ship-library/assets/portraits/60.webp | Bin 0 -> 26838 bytes .../ship-library/assets/portraits/600.webp | Bin 0 -> 27898 bytes .../ship-library/assets/portraits/601.webp | Bin 0 -> 35742 bytes .../ship-library/assets/portraits/602.webp | Bin 0 -> 32948 bytes .../ship-library/assets/portraits/603.webp | Bin 0 -> 32888 bytes .../ship-library/assets/portraits/604.webp | Bin 0 -> 30902 bytes .../ship-library/assets/portraits/605.webp | Bin 0 -> 29760 bytes .../ship-library/assets/portraits/606.webp | Bin 0 -> 26654 bytes .../ship-library/assets/portraits/607.webp | Bin 0 -> 33024 bytes .../ship-library/assets/portraits/608.webp | Bin 0 -> 28424 bytes .../ship-library/assets/portraits/609.webp | Bin 0 -> 34610 bytes .../ship-library/assets/portraits/61.webp | Bin 0 -> 28176 bytes .../ship-library/assets/portraits/610.webp | Bin 0 -> 30726 bytes .../ship-library/assets/portraits/611.webp | Bin 0 -> 31462 bytes .../ship-library/assets/portraits/612.webp | Bin 0 -> 25868 bytes .../ship-library/assets/portraits/613.webp | Bin 0 -> 39128 bytes .../ship-library/assets/portraits/614.webp | Bin 0 -> 31616 bytes .../ship-library/assets/portraits/615.webp | Bin 0 -> 38612 bytes .../ship-library/assets/portraits/616.webp | Bin 0 -> 27424 bytes .../ship-library/assets/portraits/617.webp | Bin 0 -> 30592 bytes .../ship-library/assets/portraits/618.webp | Bin 0 -> 42478 bytes .../ship-library/assets/portraits/619.webp | Bin 0 -> 35188 bytes .../ship-library/assets/portraits/62.webp | Bin 0 -> 25720 bytes .../ship-library/assets/portraits/620.webp | Bin 0 -> 36220 bytes .../ship-library/assets/portraits/621.webp | Bin 0 -> 32154 bytes .../ship-library/assets/portraits/622.webp | Bin 0 -> 33556 bytes .../ship-library/assets/portraits/623.webp | Bin 0 -> 30674 bytes .../ship-library/assets/portraits/624.webp | Bin 0 -> 28862 bytes .../ship-library/assets/portraits/625.webp | Bin 0 -> 27718 bytes .../ship-library/assets/portraits/626.webp | Bin 0 -> 27678 bytes .../ship-library/assets/portraits/627.webp | Bin 0 -> 33330 bytes .../ship-library/assets/portraits/628.webp | Bin 0 -> 29658 bytes .../ship-library/assets/portraits/629.webp | Bin 0 -> 21292 bytes .../ship-library/assets/portraits/63.webp | Bin 0 -> 23992 bytes .../ship-library/assets/portraits/630.webp | Bin 0 -> 39530 bytes .../ship-library/assets/portraits/631.webp | Bin 0 -> 25594 bytes .../ship-library/assets/portraits/632.webp | Bin 0 -> 29774 bytes .../ship-library/assets/portraits/633.webp | Bin 0 -> 29048 bytes .../ship-library/assets/portraits/634.webp | Bin 0 -> 28464 bytes .../ship-library/assets/portraits/635.webp | Bin 0 -> 32166 bytes .../ship-library/assets/portraits/636.webp | Bin 0 -> 30730 bytes .../ship-library/assets/portraits/637.webp | Bin 0 -> 18560 bytes .../ship-library/assets/portraits/638.webp | Bin 0 -> 33298 bytes .../ship-library/assets/portraits/639.webp | Bin 0 -> 26848 bytes .../ship-library/assets/portraits/64.webp | Bin 0 -> 26282 bytes .../ship-library/assets/portraits/640.webp | Bin 0 -> 29062 bytes .../ship-library/assets/portraits/641.webp | Bin 0 -> 28608 bytes .../ship-library/assets/portraits/642.webp | Bin 0 -> 25538 bytes .../ship-library/assets/portraits/643.webp | Bin 0 -> 28040 bytes .../ship-library/assets/portraits/644.webp | Bin 0 -> 34284 bytes .../ship-library/assets/portraits/645.webp | Bin 0 -> 27512 bytes .../ship-library/assets/portraits/646.webp | Bin 0 -> 25890 bytes .../ship-library/assets/portraits/647.webp | Bin 0 -> 22096 bytes .../ship-library/assets/portraits/648.webp | Bin 0 -> 31344 bytes .../ship-library/assets/portraits/649.webp | Bin 0 -> 23704 bytes .../ship-library/assets/portraits/65.webp | Bin 0 -> 30746 bytes .../ship-library/assets/portraits/650.webp | Bin 0 -> 26066 bytes .../ship-library/assets/portraits/651.webp | Bin 0 -> 36054 bytes .../ship-library/assets/portraits/66.webp | Bin 0 -> 24536 bytes .../ship-library/assets/portraits/67.webp | Bin 0 -> 23294 bytes .../ship-library/assets/portraits/68.webp | Bin 0 -> 23474 bytes .../ship-library/assets/portraits/69.webp | Bin 0 -> 20722 bytes resource/ship-library/assets/portraits/7.webp | Bin 0 -> 29254 bytes .../ship-library/assets/portraits/70.webp | Bin 0 -> 21932 bytes .../ship-library/assets/portraits/71.webp | Bin 0 -> 25486 bytes .../ship-library/assets/portraits/72.webp | Bin 0 -> 22164 bytes .../ship-library/assets/portraits/73.webp | Bin 0 -> 23500 bytes .../ship-library/assets/portraits/74.webp | Bin 0 -> 22914 bytes .../ship-library/assets/portraits/75.webp | Bin 0 -> 21944 bytes .../ship-library/assets/portraits/76.webp | Bin 0 -> 23662 bytes .../ship-library/assets/portraits/77.webp | Bin 0 -> 26624 bytes .../ship-library/assets/portraits/78.webp | Bin 0 -> 33520 bytes .../ship-library/assets/portraits/79.webp | Bin 0 -> 33246 bytes resource/ship-library/assets/portraits/8.webp | Bin 0 -> 27466 bytes .../ship-library/assets/portraits/80.webp | Bin 0 -> 35144 bytes .../ship-library/assets/portraits/8007.webp | Bin 0 -> 44416 bytes .../ship-library/assets/portraits/8009.webp | Bin 0 -> 28342 bytes .../ship-library/assets/portraits/81.webp | Bin 0 -> 23444 bytes .../ship-library/assets/portraits/8111.webp | Bin 0 -> 30744 bytes .../ship-library/assets/portraits/8116.webp | Bin 0 -> 41452 bytes .../ship-library/assets/portraits/82.webp | Bin 0 -> 25420 bytes .../ship-library/assets/portraits/83.webp | Bin 0 -> 27496 bytes .../ship-library/assets/portraits/84.webp | Bin 0 -> 29412 bytes .../ship-library/assets/portraits/85.webp | Bin 0 -> 23988 bytes .../ship-library/assets/portraits/86.webp | Bin 0 -> 24408 bytes .../ship-library/assets/portraits/87.webp | Bin 0 -> 22862 bytes .../ship-library/assets/portraits/88.webp | Bin 0 -> 34682 bytes .../ship-library/assets/portraits/89.webp | Bin 0 -> 22034 bytes resource/ship-library/assets/portraits/9.webp | Bin 0 -> 23730 bytes .../ship-library/assets/portraits/90.webp | Bin 0 -> 25486 bytes .../ship-library/assets/portraits/91.webp | Bin 0 -> 33724 bytes .../ship-library/assets/portraits/92.webp | Bin 0 -> 22198 bytes .../ship-library/assets/portraits/93.webp | Bin 0 -> 27778 bytes .../ship-library/assets/portraits/94.webp | Bin 0 -> 26118 bytes .../ship-library/assets/portraits/95.webp | Bin 0 -> 23580 bytes .../ship-library/assets/portraits/96.webp | Bin 0 -> 25520 bytes .../ship-library/assets/portraits/97.webp | Bin 0 -> 20046 bytes .../ship-library/assets/portraits/98.webp | Bin 0 -> 26150 bytes .../ship-library/assets/portraits/99.webp | Bin 0 -> 29844 bytes .../ship-library/assets/type-icons/ap.webp | Bin 0 -> 1484 bytes .../ship-library/assets/type-icons/av.webp | Bin 0 -> 1614 bytes .../ship-library/assets/type-icons/bb.webp | Bin 0 -> 1586 bytes .../ship-library/assets/type-icons/bbg.webp | Bin 0 -> 1782 bytes .../ship-library/assets/type-icons/bbv.webp | Bin 0 -> 1560 bytes .../ship-library/assets/type-icons/bc.webp | Bin 0 -> 1586 bytes .../ship-library/assets/type-icons/bm.webp | Bin 0 -> 1496 bytes .../ship-library/assets/type-icons/ca.webp | Bin 0 -> 1538 bytes .../ship-library/assets/type-icons/cav.webp | Bin 0 -> 1664 bytes .../ship-library/assets/type-icons/cbg.webp | Bin 0 -> 2232 bytes .../ship-library/assets/type-icons/cf.webp | Bin 0 -> 1878 bytes .../ship-library/assets/type-icons/cg.webp | Bin 0 -> 1772 bytes .../ship-library/assets/type-icons/cgaa.webp | Bin 0 -> 1510 bytes .../ship-library/assets/type-icons/cl.webp | Bin 0 -> 1618 bytes .../ship-library/assets/type-icons/clt.webp | Bin 0 -> 1662 bytes .../ship-library/assets/type-icons/cv.webp | Bin 0 -> 1512 bytes .../ship-library/assets/type-icons/cvl.webp | Bin 0 -> 1552 bytes .../ship-library/assets/type-icons/dd.webp | Bin 0 -> 1528 bytes .../ship-library/assets/type-icons/ddg.webp | Bin 0 -> 2612 bytes .../ship-library/assets/type-icons/ddgaa.webp | Bin 0 -> 2580 bytes .../ship-library/assets/type-icons/sc.webp | Bin 0 -> 1580 bytes .../ship-library/assets/type-icons/ss.webp | Bin 0 -> 1536 bytes .../ship-library/assets/type-icons/ssg.webp | Bin 0 -> 1480 bytes resource/ship-library/database/ships.sqlite3 | Bin 0 -> 950272 bytes resource/ship-library/labels.zh-CN.json | 53 + resource/ship-library/manifest.json | 14436 ++++++++++++++++ resource/user_team_plans/.gitkeep | 1 + src/controller/app/AppController.ts | 85 +- src/types/electronBridge.ts | 111 + src/view/config/ConfigView.ts | 23 + src/view/index.html | 165 + src/view/plan/FleetPlannerView.ts | 1964 +++ .../styles/pages/plan/_fleet-planner.scss | 1120 ++ src/view/styles/pages/plan/_index.scss | 1 + src/view/styles/styles.css | 1043 ++ tools/ship_library/update_ship_library.py | 1012 ++ 945 files changed, 20761 insertions(+), 4 deletions(-) create mode 100644 resource/ship-library/assets/backgrounds/rarity-1.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-2.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-3.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-4.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-5.webp create mode 100644 resource/ship-library/assets/backgrounds/rarity-6.webp create mode 100644 resource/ship-library/assets/frames/rarity-1.webp create mode 100644 resource/ship-library/assets/frames/rarity-2.webp create mode 100644 resource/ship-library/assets/frames/rarity-3.webp create mode 100644 resource/ship-library/assets/frames/rarity-4.webp create mode 100644 resource/ship-library/assets/frames/rarity-5.webp create mode 100644 resource/ship-library/assets/frames/rarity-6.webp create mode 100644 resource/ship-library/assets/portraits/1.webp create mode 100644 resource/ship-library/assets/portraits/10.webp create mode 100644 resource/ship-library/assets/portraits/100.webp create mode 100644 resource/ship-library/assets/portraits/1001.webp create mode 100644 resource/ship-library/assets/portraits/1002.webp create mode 100644 resource/ship-library/assets/portraits/1003.webp create mode 100644 resource/ship-library/assets/portraits/1004.webp create mode 100644 resource/ship-library/assets/portraits/1005.webp create mode 100644 resource/ship-library/assets/portraits/1006.webp create mode 100644 resource/ship-library/assets/portraits/1007.webp create mode 100644 resource/ship-library/assets/portraits/1008.webp create mode 100644 resource/ship-library/assets/portraits/1009.webp create mode 100644 resource/ship-library/assets/portraits/101.webp create mode 100644 resource/ship-library/assets/portraits/1010.webp create mode 100644 resource/ship-library/assets/portraits/1011.webp create mode 100644 resource/ship-library/assets/portraits/1012.webp create mode 100644 resource/ship-library/assets/portraits/1013.webp create mode 100644 resource/ship-library/assets/portraits/1014.webp create mode 100644 resource/ship-library/assets/portraits/1018.webp create mode 100644 resource/ship-library/assets/portraits/1019.webp create mode 100644 resource/ship-library/assets/portraits/102.webp create mode 100644 resource/ship-library/assets/portraits/1020.webp create mode 100644 resource/ship-library/assets/portraits/1021.webp create mode 100644 resource/ship-library/assets/portraits/1022.webp create mode 100644 resource/ship-library/assets/portraits/1023.webp create mode 100644 resource/ship-library/assets/portraits/1024.webp create mode 100644 resource/ship-library/assets/portraits/1025.webp create mode 100644 resource/ship-library/assets/portraits/1026.webp create mode 100644 resource/ship-library/assets/portraits/1027.webp create mode 100644 resource/ship-library/assets/portraits/1028.webp create mode 100644 resource/ship-library/assets/portraits/1029.webp create mode 100644 resource/ship-library/assets/portraits/103.webp create mode 100644 resource/ship-library/assets/portraits/1030.webp create mode 100644 resource/ship-library/assets/portraits/1031.webp create mode 100644 resource/ship-library/assets/portraits/1032.webp create mode 100644 resource/ship-library/assets/portraits/1033.webp create mode 100644 resource/ship-library/assets/portraits/1034.webp create mode 100644 resource/ship-library/assets/portraits/1035.webp create mode 100644 resource/ship-library/assets/portraits/1036.webp create mode 100644 resource/ship-library/assets/portraits/1037.webp create mode 100644 resource/ship-library/assets/portraits/1038.webp create mode 100644 resource/ship-library/assets/portraits/1039.webp create mode 100644 resource/ship-library/assets/portraits/104.webp create mode 100644 resource/ship-library/assets/portraits/1040.webp create mode 100644 resource/ship-library/assets/portraits/1041.webp create mode 100644 resource/ship-library/assets/portraits/1042.webp create mode 100644 resource/ship-library/assets/portraits/1043.webp create mode 100644 resource/ship-library/assets/portraits/1044.webp create mode 100644 resource/ship-library/assets/portraits/1045.webp create mode 100644 resource/ship-library/assets/portraits/1046.webp create mode 100644 resource/ship-library/assets/portraits/1047.webp create mode 100644 resource/ship-library/assets/portraits/1048.webp create mode 100644 resource/ship-library/assets/portraits/1049.webp create mode 100644 resource/ship-library/assets/portraits/105.webp create mode 100644 resource/ship-library/assets/portraits/1050.webp create mode 100644 resource/ship-library/assets/portraits/1054.webp create mode 100644 resource/ship-library/assets/portraits/1055.webp create mode 100644 resource/ship-library/assets/portraits/1056.webp create mode 100644 resource/ship-library/assets/portraits/1057.webp create mode 100644 resource/ship-library/assets/portraits/1058.webp create mode 100644 resource/ship-library/assets/portraits/1059.webp create mode 100644 resource/ship-library/assets/portraits/106.webp create mode 100644 resource/ship-library/assets/portraits/1060.webp create mode 100644 resource/ship-library/assets/portraits/1061.webp create mode 100644 resource/ship-library/assets/portraits/1062.webp create mode 100644 resource/ship-library/assets/portraits/1063.webp create mode 100644 resource/ship-library/assets/portraits/1064.webp create mode 100644 resource/ship-library/assets/portraits/1065.webp create mode 100644 resource/ship-library/assets/portraits/1066.webp create mode 100644 resource/ship-library/assets/portraits/1067.webp create mode 100644 resource/ship-library/assets/portraits/1068.webp create mode 100644 resource/ship-library/assets/portraits/1069.webp create mode 100644 resource/ship-library/assets/portraits/107.webp create mode 100644 resource/ship-library/assets/portraits/1070.webp create mode 100644 resource/ship-library/assets/portraits/1071.webp create mode 100644 resource/ship-library/assets/portraits/1072.webp create mode 100644 resource/ship-library/assets/portraits/1073.webp create mode 100644 resource/ship-library/assets/portraits/1074.webp create mode 100644 resource/ship-library/assets/portraits/1075.webp create mode 100644 resource/ship-library/assets/portraits/1076.webp create mode 100644 resource/ship-library/assets/portraits/1077.webp create mode 100644 resource/ship-library/assets/portraits/1079.webp create mode 100644 resource/ship-library/assets/portraits/108.webp create mode 100644 resource/ship-library/assets/portraits/1080.webp create mode 100644 resource/ship-library/assets/portraits/1081.webp create mode 100644 resource/ship-library/assets/portraits/1082.webp create mode 100644 resource/ship-library/assets/portraits/1083.webp create mode 100644 resource/ship-library/assets/portraits/1084.webp create mode 100644 resource/ship-library/assets/portraits/1085.webp create mode 100644 resource/ship-library/assets/portraits/1086.webp create mode 100644 resource/ship-library/assets/portraits/1087.webp create mode 100644 resource/ship-library/assets/portraits/1088.webp create mode 100644 resource/ship-library/assets/portraits/1089.webp create mode 100644 resource/ship-library/assets/portraits/109.webp create mode 100644 resource/ship-library/assets/portraits/1092.webp create mode 100644 resource/ship-library/assets/portraits/1093.webp create mode 100644 resource/ship-library/assets/portraits/1094.webp create mode 100644 resource/ship-library/assets/portraits/1097.webp create mode 100644 resource/ship-library/assets/portraits/1098.webp create mode 100644 resource/ship-library/assets/portraits/1099.webp create mode 100644 resource/ship-library/assets/portraits/11.webp create mode 100644 resource/ship-library/assets/portraits/110.webp create mode 100644 resource/ship-library/assets/portraits/1100.webp create mode 100644 resource/ship-library/assets/portraits/1101.webp create mode 100644 resource/ship-library/assets/portraits/1102.webp create mode 100644 resource/ship-library/assets/portraits/1105.webp create mode 100644 resource/ship-library/assets/portraits/1106.webp create mode 100644 resource/ship-library/assets/portraits/1107.webp create mode 100644 resource/ship-library/assets/portraits/1108.webp create mode 100644 resource/ship-library/assets/portraits/1109.webp create mode 100644 resource/ship-library/assets/portraits/111.webp create mode 100644 resource/ship-library/assets/portraits/1110.webp create mode 100644 resource/ship-library/assets/portraits/1111.webp create mode 100644 resource/ship-library/assets/portraits/1112.webp create mode 100644 resource/ship-library/assets/portraits/1113.webp create mode 100644 resource/ship-library/assets/portraits/1117.webp create mode 100644 resource/ship-library/assets/portraits/1118.webp create mode 100644 resource/ship-library/assets/portraits/112.webp create mode 100644 resource/ship-library/assets/portraits/1120.webp create mode 100644 resource/ship-library/assets/portraits/1121.webp create mode 100644 resource/ship-library/assets/portraits/1123.webp create mode 100644 resource/ship-library/assets/portraits/1124.webp create mode 100644 resource/ship-library/assets/portraits/1125.webp create mode 100644 resource/ship-library/assets/portraits/1126.webp create mode 100644 resource/ship-library/assets/portraits/113.webp create mode 100644 resource/ship-library/assets/portraits/1130.webp create mode 100644 resource/ship-library/assets/portraits/1131.webp create mode 100644 resource/ship-library/assets/portraits/1132.webp create mode 100644 resource/ship-library/assets/portraits/1133.webp create mode 100644 resource/ship-library/assets/portraits/1135.webp create mode 100644 resource/ship-library/assets/portraits/1136.webp create mode 100644 resource/ship-library/assets/portraits/1137.webp create mode 100644 resource/ship-library/assets/portraits/1139.webp create mode 100644 resource/ship-library/assets/portraits/114.webp create mode 100644 resource/ship-library/assets/portraits/1141.webp create mode 100644 resource/ship-library/assets/portraits/1142.webp create mode 100644 resource/ship-library/assets/portraits/1143.webp create mode 100644 resource/ship-library/assets/portraits/1145.webp create mode 100644 resource/ship-library/assets/portraits/1149.webp create mode 100644 resource/ship-library/assets/portraits/115.webp create mode 100644 resource/ship-library/assets/portraits/1150.webp create mode 100644 resource/ship-library/assets/portraits/1151.webp create mode 100644 resource/ship-library/assets/portraits/1158.webp create mode 100644 resource/ship-library/assets/portraits/1160.webp create mode 100644 resource/ship-library/assets/portraits/1162.webp create mode 100644 resource/ship-library/assets/portraits/1164.webp create mode 100644 resource/ship-library/assets/portraits/1165.webp create mode 100644 resource/ship-library/assets/portraits/1166.webp create mode 100644 resource/ship-library/assets/portraits/1167.webp create mode 100644 resource/ship-library/assets/portraits/1168.webp create mode 100644 resource/ship-library/assets/portraits/1169.webp create mode 100644 resource/ship-library/assets/portraits/117.webp create mode 100644 resource/ship-library/assets/portraits/1171.webp create mode 100644 resource/ship-library/assets/portraits/1175.webp create mode 100644 resource/ship-library/assets/portraits/1178.webp create mode 100644 resource/ship-library/assets/portraits/118.webp create mode 100644 resource/ship-library/assets/portraits/1181.webp create mode 100644 resource/ship-library/assets/portraits/1182.webp create mode 100644 resource/ship-library/assets/portraits/1183.webp create mode 100644 resource/ship-library/assets/portraits/1185.webp create mode 100644 resource/ship-library/assets/portraits/1187.webp create mode 100644 resource/ship-library/assets/portraits/1188.webp create mode 100644 resource/ship-library/assets/portraits/119.webp create mode 100644 resource/ship-library/assets/portraits/1192.webp create mode 100644 resource/ship-library/assets/portraits/1194.webp create mode 100644 resource/ship-library/assets/portraits/1195.webp create mode 100644 resource/ship-library/assets/portraits/1197.webp create mode 100644 resource/ship-library/assets/portraits/1198.webp create mode 100644 resource/ship-library/assets/portraits/1199.webp create mode 100644 resource/ship-library/assets/portraits/12.webp create mode 100644 resource/ship-library/assets/portraits/120.webp create mode 100644 resource/ship-library/assets/portraits/1205.webp create mode 100644 resource/ship-library/assets/portraits/1206.webp create mode 100644 resource/ship-library/assets/portraits/1207.webp create mode 100644 resource/ship-library/assets/portraits/1209.webp create mode 100644 resource/ship-library/assets/portraits/121.webp create mode 100644 resource/ship-library/assets/portraits/1211.webp create mode 100644 resource/ship-library/assets/portraits/1215.webp create mode 100644 resource/ship-library/assets/portraits/1219.webp create mode 100644 resource/ship-library/assets/portraits/122.webp create mode 100644 resource/ship-library/assets/portraits/1220.webp create mode 100644 resource/ship-library/assets/portraits/1221.webp create mode 100644 resource/ship-library/assets/portraits/1222.webp create mode 100644 resource/ship-library/assets/portraits/1223.webp create mode 100644 resource/ship-library/assets/portraits/1224.webp create mode 100644 resource/ship-library/assets/portraits/1225.webp create mode 100644 resource/ship-library/assets/portraits/1227.webp create mode 100644 resource/ship-library/assets/portraits/1228.webp create mode 100644 resource/ship-library/assets/portraits/123.webp create mode 100644 resource/ship-library/assets/portraits/1232.webp create mode 100644 resource/ship-library/assets/portraits/1233.webp create mode 100644 resource/ship-library/assets/portraits/1238.webp create mode 100644 resource/ship-library/assets/portraits/1239.webp create mode 100644 resource/ship-library/assets/portraits/124.webp create mode 100644 resource/ship-library/assets/portraits/1240.webp create mode 100644 resource/ship-library/assets/portraits/1241.webp create mode 100644 resource/ship-library/assets/portraits/1244.webp create mode 100644 resource/ship-library/assets/portraits/1247.webp create mode 100644 resource/ship-library/assets/portraits/1248.webp create mode 100644 resource/ship-library/assets/portraits/1249.webp create mode 100644 resource/ship-library/assets/portraits/125.webp create mode 100644 resource/ship-library/assets/portraits/1258.webp create mode 100644 resource/ship-library/assets/portraits/126.webp create mode 100644 resource/ship-library/assets/portraits/1265.webp create mode 100644 resource/ship-library/assets/portraits/1266.webp create mode 100644 resource/ship-library/assets/portraits/1267.webp create mode 100644 resource/ship-library/assets/portraits/1269.webp create mode 100644 resource/ship-library/assets/portraits/127.webp create mode 100644 resource/ship-library/assets/portraits/1270.webp create mode 100644 resource/ship-library/assets/portraits/1273.webp create mode 100644 resource/ship-library/assets/portraits/1275.webp create mode 100644 resource/ship-library/assets/portraits/1277.webp create mode 100644 resource/ship-library/assets/portraits/1278.webp create mode 100644 resource/ship-library/assets/portraits/1279.webp create mode 100644 resource/ship-library/assets/portraits/128.webp create mode 100644 resource/ship-library/assets/portraits/1280.webp create mode 100644 resource/ship-library/assets/portraits/1289.webp create mode 100644 resource/ship-library/assets/portraits/129.webp create mode 100644 resource/ship-library/assets/portraits/1290.webp create mode 100644 resource/ship-library/assets/portraits/1291.webp create mode 100644 resource/ship-library/assets/portraits/1293.webp create mode 100644 resource/ship-library/assets/portraits/1299.webp create mode 100644 resource/ship-library/assets/portraits/13.webp create mode 100644 resource/ship-library/assets/portraits/130.webp create mode 100644 resource/ship-library/assets/portraits/1301.webp create mode 100644 resource/ship-library/assets/portraits/1306.webp create mode 100644 resource/ship-library/assets/portraits/131.webp create mode 100644 resource/ship-library/assets/portraits/1311.webp create mode 100644 resource/ship-library/assets/portraits/1316.webp create mode 100644 resource/ship-library/assets/portraits/132.webp create mode 100644 resource/ship-library/assets/portraits/1323.webp create mode 100644 resource/ship-library/assets/portraits/1325.webp create mode 100644 resource/ship-library/assets/portraits/133.webp create mode 100644 resource/ship-library/assets/portraits/1332.webp create mode 100644 resource/ship-library/assets/portraits/1335.webp create mode 100644 resource/ship-library/assets/portraits/1339.webp create mode 100644 resource/ship-library/assets/portraits/134.webp create mode 100644 resource/ship-library/assets/portraits/1340.webp create mode 100644 resource/ship-library/assets/portraits/1342.webp create mode 100644 resource/ship-library/assets/portraits/1343.webp create mode 100644 resource/ship-library/assets/portraits/1344.webp create mode 100644 resource/ship-library/assets/portraits/135.webp create mode 100644 resource/ship-library/assets/portraits/1351.webp create mode 100644 resource/ship-library/assets/portraits/136.webp create mode 100644 resource/ship-library/assets/portraits/1362.webp create mode 100644 resource/ship-library/assets/portraits/1363.webp create mode 100644 resource/ship-library/assets/portraits/1366.webp create mode 100644 resource/ship-library/assets/portraits/137.webp create mode 100644 resource/ship-library/assets/portraits/1372.webp create mode 100644 resource/ship-library/assets/portraits/138.webp create mode 100644 resource/ship-library/assets/portraits/1380.webp create mode 100644 resource/ship-library/assets/portraits/139.webp create mode 100644 resource/ship-library/assets/portraits/14.webp create mode 100644 resource/ship-library/assets/portraits/140.webp create mode 100644 resource/ship-library/assets/portraits/1400.webp create mode 100644 resource/ship-library/assets/portraits/1408.webp create mode 100644 resource/ship-library/assets/portraits/141.webp create mode 100644 resource/ship-library/assets/portraits/1413.webp create mode 100644 resource/ship-library/assets/portraits/1414.webp create mode 100644 resource/ship-library/assets/portraits/1416.webp create mode 100644 resource/ship-library/assets/portraits/142.webp create mode 100644 resource/ship-library/assets/portraits/1425.webp create mode 100644 resource/ship-library/assets/portraits/1426.webp create mode 100644 resource/ship-library/assets/portraits/1429.webp create mode 100644 resource/ship-library/assets/portraits/143.webp create mode 100644 resource/ship-library/assets/portraits/1430.webp create mode 100644 resource/ship-library/assets/portraits/1431.webp create mode 100644 resource/ship-library/assets/portraits/144.webp create mode 100644 resource/ship-library/assets/portraits/145.webp create mode 100644 resource/ship-library/assets/portraits/1456.webp create mode 100644 resource/ship-library/assets/portraits/146.webp create mode 100644 resource/ship-library/assets/portraits/1467.webp create mode 100644 resource/ship-library/assets/portraits/147.webp create mode 100644 resource/ship-library/assets/portraits/148.webp create mode 100644 resource/ship-library/assets/portraits/1483.webp create mode 100644 resource/ship-library/assets/portraits/149.webp create mode 100644 resource/ship-library/assets/portraits/1490.webp create mode 100644 resource/ship-library/assets/portraits/1496.webp create mode 100644 resource/ship-library/assets/portraits/15.webp create mode 100644 resource/ship-library/assets/portraits/150.webp create mode 100644 resource/ship-library/assets/portraits/1503.webp create mode 100644 resource/ship-library/assets/portraits/1509.webp create mode 100644 resource/ship-library/assets/portraits/151.webp create mode 100644 resource/ship-library/assets/portraits/1516.webp create mode 100644 resource/ship-library/assets/portraits/1517.webp create mode 100644 resource/ship-library/assets/portraits/1519.webp create mode 100644 resource/ship-library/assets/portraits/152.webp create mode 100644 resource/ship-library/assets/portraits/1527.webp create mode 100644 resource/ship-library/assets/portraits/1528.webp create mode 100644 resource/ship-library/assets/portraits/153.webp create mode 100644 resource/ship-library/assets/portraits/1530.webp create mode 100644 resource/ship-library/assets/portraits/1532.webp create mode 100644 resource/ship-library/assets/portraits/1538.webp create mode 100644 resource/ship-library/assets/portraits/154.webp create mode 100644 resource/ship-library/assets/portraits/1545.webp create mode 100644 resource/ship-library/assets/portraits/155.webp create mode 100644 resource/ship-library/assets/portraits/156.webp create mode 100644 resource/ship-library/assets/portraits/1560.webp create mode 100644 resource/ship-library/assets/portraits/157.webp create mode 100644 resource/ship-library/assets/portraits/1575.webp create mode 100644 resource/ship-library/assets/portraits/158.webp create mode 100644 resource/ship-library/assets/portraits/1583.webp create mode 100644 resource/ship-library/assets/portraits/1589.webp create mode 100644 resource/ship-library/assets/portraits/159.webp create mode 100644 resource/ship-library/assets/portraits/1590.webp create mode 100644 resource/ship-library/assets/portraits/16.webp create mode 100644 resource/ship-library/assets/portraits/160.webp create mode 100644 resource/ship-library/assets/portraits/1606.webp create mode 100644 resource/ship-library/assets/portraits/161.webp create mode 100644 resource/ship-library/assets/portraits/1618.webp create mode 100644 resource/ship-library/assets/portraits/162.webp create mode 100644 resource/ship-library/assets/portraits/163.webp create mode 100644 resource/ship-library/assets/portraits/164.webp create mode 100644 resource/ship-library/assets/portraits/165.webp create mode 100644 resource/ship-library/assets/portraits/166.webp create mode 100644 resource/ship-library/assets/portraits/167.webp create mode 100644 resource/ship-library/assets/portraits/168.webp create mode 100644 resource/ship-library/assets/portraits/169.webp create mode 100644 resource/ship-library/assets/portraits/17.webp create mode 100644 resource/ship-library/assets/portraits/170.webp create mode 100644 resource/ship-library/assets/portraits/171.webp create mode 100644 resource/ship-library/assets/portraits/172.webp create mode 100644 resource/ship-library/assets/portraits/173.webp create mode 100644 resource/ship-library/assets/portraits/174.webp create mode 100644 resource/ship-library/assets/portraits/175.webp create mode 100644 resource/ship-library/assets/portraits/176.webp create mode 100644 resource/ship-library/assets/portraits/177.webp create mode 100644 resource/ship-library/assets/portraits/178.webp create mode 100644 resource/ship-library/assets/portraits/179.webp create mode 100644 resource/ship-library/assets/portraits/18.webp create mode 100644 resource/ship-library/assets/portraits/180.webp create mode 100644 resource/ship-library/assets/portraits/181.webp create mode 100644 resource/ship-library/assets/portraits/182.webp create mode 100644 resource/ship-library/assets/portraits/183.webp create mode 100644 resource/ship-library/assets/portraits/184.webp create mode 100644 resource/ship-library/assets/portraits/185.webp create mode 100644 resource/ship-library/assets/portraits/186.webp create mode 100644 resource/ship-library/assets/portraits/187.webp create mode 100644 resource/ship-library/assets/portraits/188.webp create mode 100644 resource/ship-library/assets/portraits/189.webp create mode 100644 resource/ship-library/assets/portraits/19.webp create mode 100644 resource/ship-library/assets/portraits/190.webp create mode 100644 resource/ship-library/assets/portraits/191.webp create mode 100644 resource/ship-library/assets/portraits/192.webp create mode 100644 resource/ship-library/assets/portraits/193.webp create mode 100644 resource/ship-library/assets/portraits/194.webp create mode 100644 resource/ship-library/assets/portraits/195.webp create mode 100644 resource/ship-library/assets/portraits/196.webp create mode 100644 resource/ship-library/assets/portraits/197.webp create mode 100644 resource/ship-library/assets/portraits/198.webp create mode 100644 resource/ship-library/assets/portraits/199.webp create mode 100644 resource/ship-library/assets/portraits/2.webp create mode 100644 resource/ship-library/assets/portraits/20.webp create mode 100644 resource/ship-library/assets/portraits/200.webp create mode 100644 resource/ship-library/assets/portraits/201.webp create mode 100644 resource/ship-library/assets/portraits/202.webp create mode 100644 resource/ship-library/assets/portraits/203.webp create mode 100644 resource/ship-library/assets/portraits/205.webp create mode 100644 resource/ship-library/assets/portraits/206.webp create mode 100644 resource/ship-library/assets/portraits/207.webp create mode 100644 resource/ship-library/assets/portraits/208.webp create mode 100644 resource/ship-library/assets/portraits/209.webp create mode 100644 resource/ship-library/assets/portraits/21.webp create mode 100644 resource/ship-library/assets/portraits/210.webp create mode 100644 resource/ship-library/assets/portraits/211.webp create mode 100644 resource/ship-library/assets/portraits/212.webp create mode 100644 resource/ship-library/assets/portraits/213.webp create mode 100644 resource/ship-library/assets/portraits/214.webp create mode 100644 resource/ship-library/assets/portraits/215.webp create mode 100644 resource/ship-library/assets/portraits/216.webp create mode 100644 resource/ship-library/assets/portraits/217.webp create mode 100644 resource/ship-library/assets/portraits/218.webp create mode 100644 resource/ship-library/assets/portraits/219.webp create mode 100644 resource/ship-library/assets/portraits/22.webp create mode 100644 resource/ship-library/assets/portraits/220.webp create mode 100644 resource/ship-library/assets/portraits/221.webp create mode 100644 resource/ship-library/assets/portraits/222.webp create mode 100644 resource/ship-library/assets/portraits/223.webp create mode 100644 resource/ship-library/assets/portraits/224.webp create mode 100644 resource/ship-library/assets/portraits/225.webp create mode 100644 resource/ship-library/assets/portraits/226.webp create mode 100644 resource/ship-library/assets/portraits/227.webp create mode 100644 resource/ship-library/assets/portraits/228.webp create mode 100644 resource/ship-library/assets/portraits/229.webp create mode 100644 resource/ship-library/assets/portraits/23.webp create mode 100644 resource/ship-library/assets/portraits/230.webp create mode 100644 resource/ship-library/assets/portraits/231.webp create mode 100644 resource/ship-library/assets/portraits/232.webp create mode 100644 resource/ship-library/assets/portraits/233.webp create mode 100644 resource/ship-library/assets/portraits/234.webp create mode 100644 resource/ship-library/assets/portraits/235.webp create mode 100644 resource/ship-library/assets/portraits/236.webp create mode 100644 resource/ship-library/assets/portraits/237.webp create mode 100644 resource/ship-library/assets/portraits/238.webp create mode 100644 resource/ship-library/assets/portraits/239.webp create mode 100644 resource/ship-library/assets/portraits/24.webp create mode 100644 resource/ship-library/assets/portraits/240.webp create mode 100644 resource/ship-library/assets/portraits/241.webp create mode 100644 resource/ship-library/assets/portraits/242.webp create mode 100644 resource/ship-library/assets/portraits/243.webp create mode 100644 resource/ship-library/assets/portraits/244.webp create mode 100644 resource/ship-library/assets/portraits/245.webp create mode 100644 resource/ship-library/assets/portraits/246.webp create mode 100644 resource/ship-library/assets/portraits/247.webp create mode 100644 resource/ship-library/assets/portraits/248.webp create mode 100644 resource/ship-library/assets/portraits/249.webp create mode 100644 resource/ship-library/assets/portraits/25.webp create mode 100644 resource/ship-library/assets/portraits/250.webp create mode 100644 resource/ship-library/assets/portraits/251.webp create mode 100644 resource/ship-library/assets/portraits/252.webp create mode 100644 resource/ship-library/assets/portraits/253.webp create mode 100644 resource/ship-library/assets/portraits/254.webp create mode 100644 resource/ship-library/assets/portraits/255.webp create mode 100644 resource/ship-library/assets/portraits/256.webp create mode 100644 resource/ship-library/assets/portraits/257.webp create mode 100644 resource/ship-library/assets/portraits/258.webp create mode 100644 resource/ship-library/assets/portraits/259.webp create mode 100644 resource/ship-library/assets/portraits/26.webp create mode 100644 resource/ship-library/assets/portraits/260.webp create mode 100644 resource/ship-library/assets/portraits/261.webp create mode 100644 resource/ship-library/assets/portraits/262.webp create mode 100644 resource/ship-library/assets/portraits/263.webp create mode 100644 resource/ship-library/assets/portraits/264.webp create mode 100644 resource/ship-library/assets/portraits/265.webp create mode 100644 resource/ship-library/assets/portraits/266.webp create mode 100644 resource/ship-library/assets/portraits/267.webp create mode 100644 resource/ship-library/assets/portraits/268.webp create mode 100644 resource/ship-library/assets/portraits/269.webp create mode 100644 resource/ship-library/assets/portraits/27.webp create mode 100644 resource/ship-library/assets/portraits/270.webp create mode 100644 resource/ship-library/assets/portraits/271.webp create mode 100644 resource/ship-library/assets/portraits/272.webp create mode 100644 resource/ship-library/assets/portraits/273.webp create mode 100644 resource/ship-library/assets/portraits/274.webp create mode 100644 resource/ship-library/assets/portraits/275.webp create mode 100644 resource/ship-library/assets/portraits/276.webp create mode 100644 resource/ship-library/assets/portraits/277.webp create mode 100644 resource/ship-library/assets/portraits/278.webp create mode 100644 resource/ship-library/assets/portraits/279.webp create mode 100644 resource/ship-library/assets/portraits/28.webp create mode 100644 resource/ship-library/assets/portraits/280.webp create mode 100644 resource/ship-library/assets/portraits/281.webp create mode 100644 resource/ship-library/assets/portraits/282.webp create mode 100644 resource/ship-library/assets/portraits/283.webp create mode 100644 resource/ship-library/assets/portraits/284.webp create mode 100644 resource/ship-library/assets/portraits/285.webp create mode 100644 resource/ship-library/assets/portraits/286.webp create mode 100644 resource/ship-library/assets/portraits/287.webp create mode 100644 resource/ship-library/assets/portraits/288.webp create mode 100644 resource/ship-library/assets/portraits/289.webp create mode 100644 resource/ship-library/assets/portraits/29.webp create mode 100644 resource/ship-library/assets/portraits/290.webp create mode 100644 resource/ship-library/assets/portraits/291.webp create mode 100644 resource/ship-library/assets/portraits/292.webp create mode 100644 resource/ship-library/assets/portraits/293.webp create mode 100644 resource/ship-library/assets/portraits/294.webp create mode 100644 resource/ship-library/assets/portraits/295.webp create mode 100644 resource/ship-library/assets/portraits/296.webp create mode 100644 resource/ship-library/assets/portraits/297.webp create mode 100644 resource/ship-library/assets/portraits/298.webp create mode 100644 resource/ship-library/assets/portraits/299.webp create mode 100644 resource/ship-library/assets/portraits/3.webp create mode 100644 resource/ship-library/assets/portraits/30.webp create mode 100644 resource/ship-library/assets/portraits/300.webp create mode 100644 resource/ship-library/assets/portraits/301.webp create mode 100644 resource/ship-library/assets/portraits/302.webp create mode 100644 resource/ship-library/assets/portraits/303.webp create mode 100644 resource/ship-library/assets/portraits/304.webp create mode 100644 resource/ship-library/assets/portraits/305.webp create mode 100644 resource/ship-library/assets/portraits/306.webp create mode 100644 resource/ship-library/assets/portraits/307.webp create mode 100644 resource/ship-library/assets/portraits/308.webp create mode 100644 resource/ship-library/assets/portraits/309.webp create mode 100644 resource/ship-library/assets/portraits/31.webp create mode 100644 resource/ship-library/assets/portraits/310.webp create mode 100644 resource/ship-library/assets/portraits/311.webp create mode 100644 resource/ship-library/assets/portraits/312.webp create mode 100644 resource/ship-library/assets/portraits/313.webp create mode 100644 resource/ship-library/assets/portraits/314.webp create mode 100644 resource/ship-library/assets/portraits/315.webp create mode 100644 resource/ship-library/assets/portraits/316.webp create mode 100644 resource/ship-library/assets/portraits/317.webp create mode 100644 resource/ship-library/assets/portraits/318.webp create mode 100644 resource/ship-library/assets/portraits/319.webp create mode 100644 resource/ship-library/assets/portraits/32.webp create mode 100644 resource/ship-library/assets/portraits/320.webp create mode 100644 resource/ship-library/assets/portraits/321.webp create mode 100644 resource/ship-library/assets/portraits/322.webp create mode 100644 resource/ship-library/assets/portraits/323.webp create mode 100644 resource/ship-library/assets/portraits/324.webp create mode 100644 resource/ship-library/assets/portraits/325.webp create mode 100644 resource/ship-library/assets/portraits/326.webp create mode 100644 resource/ship-library/assets/portraits/327.webp create mode 100644 resource/ship-library/assets/portraits/328.webp create mode 100644 resource/ship-library/assets/portraits/329.webp create mode 100644 resource/ship-library/assets/portraits/33.webp create mode 100644 resource/ship-library/assets/portraits/330.webp create mode 100644 resource/ship-library/assets/portraits/331.webp create mode 100644 resource/ship-library/assets/portraits/332.webp create mode 100644 resource/ship-library/assets/portraits/333.webp create mode 100644 resource/ship-library/assets/portraits/334.webp create mode 100644 resource/ship-library/assets/portraits/335.webp create mode 100644 resource/ship-library/assets/portraits/336.webp create mode 100644 resource/ship-library/assets/portraits/337.webp create mode 100644 resource/ship-library/assets/portraits/338.webp create mode 100644 resource/ship-library/assets/portraits/339.webp create mode 100644 resource/ship-library/assets/portraits/34.webp create mode 100644 resource/ship-library/assets/portraits/340.webp create mode 100644 resource/ship-library/assets/portraits/341.webp create mode 100644 resource/ship-library/assets/portraits/342.webp create mode 100644 resource/ship-library/assets/portraits/343.webp create mode 100644 resource/ship-library/assets/portraits/344.webp create mode 100644 resource/ship-library/assets/portraits/345.webp create mode 100644 resource/ship-library/assets/portraits/346.webp create mode 100644 resource/ship-library/assets/portraits/347.webp create mode 100644 resource/ship-library/assets/portraits/348.webp create mode 100644 resource/ship-library/assets/portraits/349.webp create mode 100644 resource/ship-library/assets/portraits/35.webp create mode 100644 resource/ship-library/assets/portraits/350.webp create mode 100644 resource/ship-library/assets/portraits/351.webp create mode 100644 resource/ship-library/assets/portraits/352.webp create mode 100644 resource/ship-library/assets/portraits/353.webp create mode 100644 resource/ship-library/assets/portraits/354.webp create mode 100644 resource/ship-library/assets/portraits/355.webp create mode 100644 resource/ship-library/assets/portraits/356.webp create mode 100644 resource/ship-library/assets/portraits/357.webp create mode 100644 resource/ship-library/assets/portraits/358.webp create mode 100644 resource/ship-library/assets/portraits/359.webp create mode 100644 resource/ship-library/assets/portraits/36.webp create mode 100644 resource/ship-library/assets/portraits/360.webp create mode 100644 resource/ship-library/assets/portraits/361.webp create mode 100644 resource/ship-library/assets/portraits/362.webp create mode 100644 resource/ship-library/assets/portraits/363.webp create mode 100644 resource/ship-library/assets/portraits/364.webp create mode 100644 resource/ship-library/assets/portraits/365.webp create mode 100644 resource/ship-library/assets/portraits/366.webp create mode 100644 resource/ship-library/assets/portraits/367.webp create mode 100644 resource/ship-library/assets/portraits/368.webp create mode 100644 resource/ship-library/assets/portraits/369.webp create mode 100644 resource/ship-library/assets/portraits/37.webp create mode 100644 resource/ship-library/assets/portraits/370.webp create mode 100644 resource/ship-library/assets/portraits/371.webp create mode 100644 resource/ship-library/assets/portraits/372.webp create mode 100644 resource/ship-library/assets/portraits/373.webp create mode 100644 resource/ship-library/assets/portraits/374.webp create mode 100644 resource/ship-library/assets/portraits/375.webp create mode 100644 resource/ship-library/assets/portraits/376.webp create mode 100644 resource/ship-library/assets/portraits/377.webp create mode 100644 resource/ship-library/assets/portraits/378.webp create mode 100644 resource/ship-library/assets/portraits/379.webp create mode 100644 resource/ship-library/assets/portraits/38.webp create mode 100644 resource/ship-library/assets/portraits/380.webp create mode 100644 resource/ship-library/assets/portraits/381.webp create mode 100644 resource/ship-library/assets/portraits/382.webp create mode 100644 resource/ship-library/assets/portraits/383.webp create mode 100644 resource/ship-library/assets/portraits/384.webp create mode 100644 resource/ship-library/assets/portraits/385.webp create mode 100644 resource/ship-library/assets/portraits/386.webp create mode 100644 resource/ship-library/assets/portraits/387.webp create mode 100644 resource/ship-library/assets/portraits/388.webp create mode 100644 resource/ship-library/assets/portraits/389.webp create mode 100644 resource/ship-library/assets/portraits/39.webp create mode 100644 resource/ship-library/assets/portraits/390.webp create mode 100644 resource/ship-library/assets/portraits/391.webp create mode 100644 resource/ship-library/assets/portraits/392.webp create mode 100644 resource/ship-library/assets/portraits/393.webp create mode 100644 resource/ship-library/assets/portraits/394.webp create mode 100644 resource/ship-library/assets/portraits/395.webp create mode 100644 resource/ship-library/assets/portraits/396.webp create mode 100644 resource/ship-library/assets/portraits/397.webp create mode 100644 resource/ship-library/assets/portraits/398.webp create mode 100644 resource/ship-library/assets/portraits/399.webp create mode 100644 resource/ship-library/assets/portraits/4.webp create mode 100644 resource/ship-library/assets/portraits/40.webp create mode 100644 resource/ship-library/assets/portraits/400.webp create mode 100644 resource/ship-library/assets/portraits/401.webp create mode 100644 resource/ship-library/assets/portraits/402.webp create mode 100644 resource/ship-library/assets/portraits/403.webp create mode 100644 resource/ship-library/assets/portraits/404.webp create mode 100644 resource/ship-library/assets/portraits/405.webp create mode 100644 resource/ship-library/assets/portraits/406.webp create mode 100644 resource/ship-library/assets/portraits/407.webp create mode 100644 resource/ship-library/assets/portraits/408.webp create mode 100644 resource/ship-library/assets/portraits/409.webp create mode 100644 resource/ship-library/assets/portraits/41.webp create mode 100644 resource/ship-library/assets/portraits/410.webp create mode 100644 resource/ship-library/assets/portraits/411.webp create mode 100644 resource/ship-library/assets/portraits/412.webp create mode 100644 resource/ship-library/assets/portraits/413.webp create mode 100644 resource/ship-library/assets/portraits/414.webp create mode 100644 resource/ship-library/assets/portraits/415.webp create mode 100644 resource/ship-library/assets/portraits/416.webp create mode 100644 resource/ship-library/assets/portraits/417.webp create mode 100644 resource/ship-library/assets/portraits/418.webp create mode 100644 resource/ship-library/assets/portraits/419.webp create mode 100644 resource/ship-library/assets/portraits/42.webp create mode 100644 resource/ship-library/assets/portraits/420.webp create mode 100644 resource/ship-library/assets/portraits/421.webp create mode 100644 resource/ship-library/assets/portraits/422.webp create mode 100644 resource/ship-library/assets/portraits/423.webp create mode 100644 resource/ship-library/assets/portraits/424.webp create mode 100644 resource/ship-library/assets/portraits/425.webp create mode 100644 resource/ship-library/assets/portraits/426.webp create mode 100644 resource/ship-library/assets/portraits/427.webp create mode 100644 resource/ship-library/assets/portraits/428.webp create mode 100644 resource/ship-library/assets/portraits/429.webp create mode 100644 resource/ship-library/assets/portraits/43.webp create mode 100644 resource/ship-library/assets/portraits/430.webp create mode 100644 resource/ship-library/assets/portraits/431.webp create mode 100644 resource/ship-library/assets/portraits/432.webp create mode 100644 resource/ship-library/assets/portraits/433.webp create mode 100644 resource/ship-library/assets/portraits/434.webp create mode 100644 resource/ship-library/assets/portraits/435.webp create mode 100644 resource/ship-library/assets/portraits/436.webp create mode 100644 resource/ship-library/assets/portraits/437.webp create mode 100644 resource/ship-library/assets/portraits/438.webp create mode 100644 resource/ship-library/assets/portraits/439.webp create mode 100644 resource/ship-library/assets/portraits/44.webp create mode 100644 resource/ship-library/assets/portraits/440.webp create mode 100644 resource/ship-library/assets/portraits/441.webp create mode 100644 resource/ship-library/assets/portraits/442.webp create mode 100644 resource/ship-library/assets/portraits/443.webp create mode 100644 resource/ship-library/assets/portraits/444.webp create mode 100644 resource/ship-library/assets/portraits/445.webp create mode 100644 resource/ship-library/assets/portraits/446.webp create mode 100644 resource/ship-library/assets/portraits/447.webp create mode 100644 resource/ship-library/assets/portraits/448.webp create mode 100644 resource/ship-library/assets/portraits/449.webp create mode 100644 resource/ship-library/assets/portraits/45.webp create mode 100644 resource/ship-library/assets/portraits/450.webp create mode 100644 resource/ship-library/assets/portraits/451.webp create mode 100644 resource/ship-library/assets/portraits/452.webp create mode 100644 resource/ship-library/assets/portraits/453.webp create mode 100644 resource/ship-library/assets/portraits/454.webp create mode 100644 resource/ship-library/assets/portraits/455.webp create mode 100644 resource/ship-library/assets/portraits/456.webp create mode 100644 resource/ship-library/assets/portraits/457.webp create mode 100644 resource/ship-library/assets/portraits/458.webp create mode 100644 resource/ship-library/assets/portraits/459.webp create mode 100644 resource/ship-library/assets/portraits/46.webp create mode 100644 resource/ship-library/assets/portraits/460.webp create mode 100644 resource/ship-library/assets/portraits/461.webp create mode 100644 resource/ship-library/assets/portraits/462.webp create mode 100644 resource/ship-library/assets/portraits/463.webp create mode 100644 resource/ship-library/assets/portraits/464.webp create mode 100644 resource/ship-library/assets/portraits/465.webp create mode 100644 resource/ship-library/assets/portraits/466.webp create mode 100644 resource/ship-library/assets/portraits/467.webp create mode 100644 resource/ship-library/assets/portraits/468.webp create mode 100644 resource/ship-library/assets/portraits/469.webp create mode 100644 resource/ship-library/assets/portraits/47.webp create mode 100644 resource/ship-library/assets/portraits/470.webp create mode 100644 resource/ship-library/assets/portraits/471.webp create mode 100644 resource/ship-library/assets/portraits/472.webp create mode 100644 resource/ship-library/assets/portraits/473.webp create mode 100644 resource/ship-library/assets/portraits/474.webp create mode 100644 resource/ship-library/assets/portraits/475.webp create mode 100644 resource/ship-library/assets/portraits/476.webp create mode 100644 resource/ship-library/assets/portraits/477.webp create mode 100644 resource/ship-library/assets/portraits/478.webp create mode 100644 resource/ship-library/assets/portraits/479.webp create mode 100644 resource/ship-library/assets/portraits/48.webp create mode 100644 resource/ship-library/assets/portraits/480.webp create mode 100644 resource/ship-library/assets/portraits/481.webp create mode 100644 resource/ship-library/assets/portraits/482.webp create mode 100644 resource/ship-library/assets/portraits/483.webp create mode 100644 resource/ship-library/assets/portraits/484.webp create mode 100644 resource/ship-library/assets/portraits/485.webp create mode 100644 resource/ship-library/assets/portraits/486.webp create mode 100644 resource/ship-library/assets/portraits/487.webp create mode 100644 resource/ship-library/assets/portraits/488.webp create mode 100644 resource/ship-library/assets/portraits/489.webp create mode 100644 resource/ship-library/assets/portraits/49.webp create mode 100644 resource/ship-library/assets/portraits/490.webp create mode 100644 resource/ship-library/assets/portraits/491.webp create mode 100644 resource/ship-library/assets/portraits/492.webp create mode 100644 resource/ship-library/assets/portraits/493.webp create mode 100644 resource/ship-library/assets/portraits/494.webp create mode 100644 resource/ship-library/assets/portraits/495.webp create mode 100644 resource/ship-library/assets/portraits/496.webp create mode 100644 resource/ship-library/assets/portraits/497.webp create mode 100644 resource/ship-library/assets/portraits/498.webp create mode 100644 resource/ship-library/assets/portraits/499.webp create mode 100644 resource/ship-library/assets/portraits/5.webp create mode 100644 resource/ship-library/assets/portraits/50.webp create mode 100644 resource/ship-library/assets/portraits/500.webp create mode 100644 resource/ship-library/assets/portraits/501.webp create mode 100644 resource/ship-library/assets/portraits/502.webp create mode 100644 resource/ship-library/assets/portraits/503.webp create mode 100644 resource/ship-library/assets/portraits/504.webp create mode 100644 resource/ship-library/assets/portraits/505.webp create mode 100644 resource/ship-library/assets/portraits/506.webp create mode 100644 resource/ship-library/assets/portraits/507.webp create mode 100644 resource/ship-library/assets/portraits/508.webp create mode 100644 resource/ship-library/assets/portraits/509.webp create mode 100644 resource/ship-library/assets/portraits/51.webp create mode 100644 resource/ship-library/assets/portraits/510.webp create mode 100644 resource/ship-library/assets/portraits/511.webp create mode 100644 resource/ship-library/assets/portraits/512.webp create mode 100644 resource/ship-library/assets/portraits/513.webp create mode 100644 resource/ship-library/assets/portraits/514.webp create mode 100644 resource/ship-library/assets/portraits/515.webp create mode 100644 resource/ship-library/assets/portraits/516.webp create mode 100644 resource/ship-library/assets/portraits/517.webp create mode 100644 resource/ship-library/assets/portraits/518.webp create mode 100644 resource/ship-library/assets/portraits/519.webp create mode 100644 resource/ship-library/assets/portraits/52.webp create mode 100644 resource/ship-library/assets/portraits/520.webp create mode 100644 resource/ship-library/assets/portraits/521.webp create mode 100644 resource/ship-library/assets/portraits/522.webp create mode 100644 resource/ship-library/assets/portraits/523.webp create mode 100644 resource/ship-library/assets/portraits/524.webp create mode 100644 resource/ship-library/assets/portraits/525.webp create mode 100644 resource/ship-library/assets/portraits/526.webp create mode 100644 resource/ship-library/assets/portraits/527.webp create mode 100644 resource/ship-library/assets/portraits/528.webp create mode 100644 resource/ship-library/assets/portraits/529.webp create mode 100644 resource/ship-library/assets/portraits/53.webp create mode 100644 resource/ship-library/assets/portraits/530.webp create mode 100644 resource/ship-library/assets/portraits/531.webp create mode 100644 resource/ship-library/assets/portraits/532.webp create mode 100644 resource/ship-library/assets/portraits/533.webp create mode 100644 resource/ship-library/assets/portraits/534.webp create mode 100644 resource/ship-library/assets/portraits/535.webp create mode 100644 resource/ship-library/assets/portraits/536.webp create mode 100644 resource/ship-library/assets/portraits/537.webp create mode 100644 resource/ship-library/assets/portraits/538.webp create mode 100644 resource/ship-library/assets/portraits/539.webp create mode 100644 resource/ship-library/assets/portraits/54.webp create mode 100644 resource/ship-library/assets/portraits/540.webp create mode 100644 resource/ship-library/assets/portraits/541.webp create mode 100644 resource/ship-library/assets/portraits/542.webp create mode 100644 resource/ship-library/assets/portraits/543.webp create mode 100644 resource/ship-library/assets/portraits/544.webp create mode 100644 resource/ship-library/assets/portraits/545.webp create mode 100644 resource/ship-library/assets/portraits/546.webp create mode 100644 resource/ship-library/assets/portraits/547.webp create mode 100644 resource/ship-library/assets/portraits/548.webp create mode 100644 resource/ship-library/assets/portraits/549.webp create mode 100644 resource/ship-library/assets/portraits/55.webp create mode 100644 resource/ship-library/assets/portraits/550.webp create mode 100644 resource/ship-library/assets/portraits/551.webp create mode 100644 resource/ship-library/assets/portraits/552.webp create mode 100644 resource/ship-library/assets/portraits/553.webp create mode 100644 resource/ship-library/assets/portraits/554.webp create mode 100644 resource/ship-library/assets/portraits/555.webp create mode 100644 resource/ship-library/assets/portraits/556.webp create mode 100644 resource/ship-library/assets/portraits/557.webp create mode 100644 resource/ship-library/assets/portraits/558.webp create mode 100644 resource/ship-library/assets/portraits/559.webp create mode 100644 resource/ship-library/assets/portraits/56.webp create mode 100644 resource/ship-library/assets/portraits/560.webp create mode 100644 resource/ship-library/assets/portraits/561.webp create mode 100644 resource/ship-library/assets/portraits/562.webp create mode 100644 resource/ship-library/assets/portraits/563.webp create mode 100644 resource/ship-library/assets/portraits/564.webp create mode 100644 resource/ship-library/assets/portraits/565.webp create mode 100644 resource/ship-library/assets/portraits/566.webp create mode 100644 resource/ship-library/assets/portraits/567.webp create mode 100644 resource/ship-library/assets/portraits/568.webp create mode 100644 resource/ship-library/assets/portraits/569.webp create mode 100644 resource/ship-library/assets/portraits/57.webp create mode 100644 resource/ship-library/assets/portraits/570.webp create mode 100644 resource/ship-library/assets/portraits/571.webp create mode 100644 resource/ship-library/assets/portraits/572.webp create mode 100644 resource/ship-library/assets/portraits/573.webp create mode 100644 resource/ship-library/assets/portraits/574.webp create mode 100644 resource/ship-library/assets/portraits/575.webp create mode 100644 resource/ship-library/assets/portraits/576.webp create mode 100644 resource/ship-library/assets/portraits/577.webp create mode 100644 resource/ship-library/assets/portraits/578.webp create mode 100644 resource/ship-library/assets/portraits/579.webp create mode 100644 resource/ship-library/assets/portraits/58.webp create mode 100644 resource/ship-library/assets/portraits/580.webp create mode 100644 resource/ship-library/assets/portraits/581.webp create mode 100644 resource/ship-library/assets/portraits/582.webp create mode 100644 resource/ship-library/assets/portraits/583.webp create mode 100644 resource/ship-library/assets/portraits/584.webp create mode 100644 resource/ship-library/assets/portraits/585.webp create mode 100644 resource/ship-library/assets/portraits/586.webp create mode 100644 resource/ship-library/assets/portraits/587.webp create mode 100644 resource/ship-library/assets/portraits/588.webp create mode 100644 resource/ship-library/assets/portraits/589.webp create mode 100644 resource/ship-library/assets/portraits/59.webp create mode 100644 resource/ship-library/assets/portraits/590.webp create mode 100644 resource/ship-library/assets/portraits/591.webp create mode 100644 resource/ship-library/assets/portraits/592.webp create mode 100644 resource/ship-library/assets/portraits/593.webp create mode 100644 resource/ship-library/assets/portraits/594.webp create mode 100644 resource/ship-library/assets/portraits/595.webp create mode 100644 resource/ship-library/assets/portraits/596.webp create mode 100644 resource/ship-library/assets/portraits/597.webp create mode 100644 resource/ship-library/assets/portraits/598.webp create mode 100644 resource/ship-library/assets/portraits/599.webp create mode 100644 resource/ship-library/assets/portraits/6.webp create mode 100644 resource/ship-library/assets/portraits/60.webp create mode 100644 resource/ship-library/assets/portraits/600.webp create mode 100644 resource/ship-library/assets/portraits/601.webp create mode 100644 resource/ship-library/assets/portraits/602.webp create mode 100644 resource/ship-library/assets/portraits/603.webp create mode 100644 resource/ship-library/assets/portraits/604.webp create mode 100644 resource/ship-library/assets/portraits/605.webp create mode 100644 resource/ship-library/assets/portraits/606.webp create mode 100644 resource/ship-library/assets/portraits/607.webp create mode 100644 resource/ship-library/assets/portraits/608.webp create mode 100644 resource/ship-library/assets/portraits/609.webp create mode 100644 resource/ship-library/assets/portraits/61.webp create mode 100644 resource/ship-library/assets/portraits/610.webp create mode 100644 resource/ship-library/assets/portraits/611.webp create mode 100644 resource/ship-library/assets/portraits/612.webp create mode 100644 resource/ship-library/assets/portraits/613.webp create mode 100644 resource/ship-library/assets/portraits/614.webp create mode 100644 resource/ship-library/assets/portraits/615.webp create mode 100644 resource/ship-library/assets/portraits/616.webp create mode 100644 resource/ship-library/assets/portraits/617.webp create mode 100644 resource/ship-library/assets/portraits/618.webp create mode 100644 resource/ship-library/assets/portraits/619.webp create mode 100644 resource/ship-library/assets/portraits/62.webp create mode 100644 resource/ship-library/assets/portraits/620.webp create mode 100644 resource/ship-library/assets/portraits/621.webp create mode 100644 resource/ship-library/assets/portraits/622.webp create mode 100644 resource/ship-library/assets/portraits/623.webp create mode 100644 resource/ship-library/assets/portraits/624.webp create mode 100644 resource/ship-library/assets/portraits/625.webp create mode 100644 resource/ship-library/assets/portraits/626.webp create mode 100644 resource/ship-library/assets/portraits/627.webp create mode 100644 resource/ship-library/assets/portraits/628.webp create mode 100644 resource/ship-library/assets/portraits/629.webp create mode 100644 resource/ship-library/assets/portraits/63.webp create mode 100644 resource/ship-library/assets/portraits/630.webp create mode 100644 resource/ship-library/assets/portraits/631.webp create mode 100644 resource/ship-library/assets/portraits/632.webp create mode 100644 resource/ship-library/assets/portraits/633.webp create mode 100644 resource/ship-library/assets/portraits/634.webp create mode 100644 resource/ship-library/assets/portraits/635.webp create mode 100644 resource/ship-library/assets/portraits/636.webp create mode 100644 resource/ship-library/assets/portraits/637.webp create mode 100644 resource/ship-library/assets/portraits/638.webp create mode 100644 resource/ship-library/assets/portraits/639.webp create mode 100644 resource/ship-library/assets/portraits/64.webp create mode 100644 resource/ship-library/assets/portraits/640.webp create mode 100644 resource/ship-library/assets/portraits/641.webp create mode 100644 resource/ship-library/assets/portraits/642.webp create mode 100644 resource/ship-library/assets/portraits/643.webp create mode 100644 resource/ship-library/assets/portraits/644.webp create mode 100644 resource/ship-library/assets/portraits/645.webp create mode 100644 resource/ship-library/assets/portraits/646.webp create mode 100644 resource/ship-library/assets/portraits/647.webp create mode 100644 resource/ship-library/assets/portraits/648.webp create mode 100644 resource/ship-library/assets/portraits/649.webp create mode 100644 resource/ship-library/assets/portraits/65.webp create mode 100644 resource/ship-library/assets/portraits/650.webp create mode 100644 resource/ship-library/assets/portraits/651.webp create mode 100644 resource/ship-library/assets/portraits/66.webp create mode 100644 resource/ship-library/assets/portraits/67.webp create mode 100644 resource/ship-library/assets/portraits/68.webp create mode 100644 resource/ship-library/assets/portraits/69.webp create mode 100644 resource/ship-library/assets/portraits/7.webp create mode 100644 resource/ship-library/assets/portraits/70.webp create mode 100644 resource/ship-library/assets/portraits/71.webp create mode 100644 resource/ship-library/assets/portraits/72.webp create mode 100644 resource/ship-library/assets/portraits/73.webp create mode 100644 resource/ship-library/assets/portraits/74.webp create mode 100644 resource/ship-library/assets/portraits/75.webp create mode 100644 resource/ship-library/assets/portraits/76.webp create mode 100644 resource/ship-library/assets/portraits/77.webp create mode 100644 resource/ship-library/assets/portraits/78.webp create mode 100644 resource/ship-library/assets/portraits/79.webp create mode 100644 resource/ship-library/assets/portraits/8.webp create mode 100644 resource/ship-library/assets/portraits/80.webp create mode 100644 resource/ship-library/assets/portraits/8007.webp create mode 100644 resource/ship-library/assets/portraits/8009.webp create mode 100644 resource/ship-library/assets/portraits/81.webp create mode 100644 resource/ship-library/assets/portraits/8111.webp create mode 100644 resource/ship-library/assets/portraits/8116.webp create mode 100644 resource/ship-library/assets/portraits/82.webp create mode 100644 resource/ship-library/assets/portraits/83.webp create mode 100644 resource/ship-library/assets/portraits/84.webp create mode 100644 resource/ship-library/assets/portraits/85.webp create mode 100644 resource/ship-library/assets/portraits/86.webp create mode 100644 resource/ship-library/assets/portraits/87.webp create mode 100644 resource/ship-library/assets/portraits/88.webp create mode 100644 resource/ship-library/assets/portraits/89.webp create mode 100644 resource/ship-library/assets/portraits/9.webp create mode 100644 resource/ship-library/assets/portraits/90.webp create mode 100644 resource/ship-library/assets/portraits/91.webp create mode 100644 resource/ship-library/assets/portraits/92.webp create mode 100644 resource/ship-library/assets/portraits/93.webp create mode 100644 resource/ship-library/assets/portraits/94.webp create mode 100644 resource/ship-library/assets/portraits/95.webp create mode 100644 resource/ship-library/assets/portraits/96.webp create mode 100644 resource/ship-library/assets/portraits/97.webp create mode 100644 resource/ship-library/assets/portraits/98.webp create mode 100644 resource/ship-library/assets/portraits/99.webp create mode 100644 resource/ship-library/assets/type-icons/ap.webp create mode 100644 resource/ship-library/assets/type-icons/av.webp create mode 100644 resource/ship-library/assets/type-icons/bb.webp create mode 100644 resource/ship-library/assets/type-icons/bbg.webp create mode 100644 resource/ship-library/assets/type-icons/bbv.webp create mode 100644 resource/ship-library/assets/type-icons/bc.webp create mode 100644 resource/ship-library/assets/type-icons/bm.webp create mode 100644 resource/ship-library/assets/type-icons/ca.webp create mode 100644 resource/ship-library/assets/type-icons/cav.webp create mode 100644 resource/ship-library/assets/type-icons/cbg.webp create mode 100644 resource/ship-library/assets/type-icons/cf.webp create mode 100644 resource/ship-library/assets/type-icons/cg.webp create mode 100644 resource/ship-library/assets/type-icons/cgaa.webp create mode 100644 resource/ship-library/assets/type-icons/cl.webp create mode 100644 resource/ship-library/assets/type-icons/clt.webp create mode 100644 resource/ship-library/assets/type-icons/cv.webp create mode 100644 resource/ship-library/assets/type-icons/cvl.webp create mode 100644 resource/ship-library/assets/type-icons/dd.webp create mode 100644 resource/ship-library/assets/type-icons/ddg.webp create mode 100644 resource/ship-library/assets/type-icons/ddgaa.webp create mode 100644 resource/ship-library/assets/type-icons/sc.webp create mode 100644 resource/ship-library/assets/type-icons/ss.webp create mode 100644 resource/ship-library/assets/type-icons/ssg.webp create mode 100644 resource/ship-library/database/ships.sqlite3 create mode 100644 resource/ship-library/labels.zh-CN.json create mode 100644 resource/ship-library/manifest.json create mode 100644 resource/user_team_plans/.gitkeep create mode 100644 src/view/plan/FleetPlannerView.ts create mode 100644 src/view/styles/pages/plan/_fleet-planner.scss create mode 100644 tools/ship_library/update_ship_library.py diff --git a/electron/main.ts b/electron/main.ts index 85fde38..4d823db 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -5,14 +5,16 @@ import { app, BrowserWindow, ipcMain, dialog, shell } from 'electron'; import * as path from 'path'; import * as fs from 'fs'; -import { exec } from 'child_process'; +import { pathToFileURL } from 'url'; +import { exec, spawn } from 'child_process'; import { promisify } from 'util'; import { autoUpdater, UpdateInfo, ProgressInfo } from 'electron-updater'; +import * as yaml from 'js-yaml'; import { initPythonEnv, clearPythonCache, isAllowedPythonVersion, findPython, checkEnvironment, checkForUpdates, installDependencies, installPortablePython, - pullUpdates, + pullUpdates, ensurePip, localSitePackages, pipEnv, } from './pythonEnv'; import { detectEmulator } from './emulatorDetect'; import { initBackend, getBackendProcess, startBackend, stopBackend, runSetupScript } from './backend'; @@ -217,6 +219,626 @@ function copyDirNoOverwrite(src: string, dest: string): void { } } +interface ShipLibraryStatus { + exists: boolean; + path: string; + generatedAt?: string; + shipCount: number; + assetCount: number; + missingAssets: number; + error?: string; +} + +interface ShipLibraryUpdateResult { + success: boolean; + output?: string; + generated_at?: string; + ship_count?: number; + asset_count?: number; + added?: number; + updated?: number; + removed?: number; + downloaded?: number; + failed?: number; + failures?: string[]; + error?: string; +} + +interface ShipLibraryManifest { + schemaVersion: number; + generatedAt: string; + labels: Record; + typeGroups: Record; + ships: Array>; +} + +/** 当前可写的舰船资料库目录。 */ +function shipLibraryDir(): string { + if (isPackaged()) { + return path.join(app.getPath('userData'), 'ship-library'); + } + return path.join(resourceRoot(), 'resource', 'ship-library'); +} + +/** 打包后将内置资料库复制到用户目录,已有文件不覆盖。 */ +function initUserShipLibraryDir(): void { + if (!isPackaged()) return; + const bundledDir = path.join(resourceRoot(), 'resource', 'ship-library'); + if (fs.existsSync(bundledDir)) { + copyDirNoOverwrite(bundledDir, shipLibraryDir()); + } +} + +const ALLOWED_FLEET_SHIP_TYPES = new Set([ + 'dd', + 'cl', + 'ca', + 'cav', + 'clt', + 'bb', + 'bc', + 'bbv', + 'cv', + 'cvl', + 'av', + 'ss', + 'ssg', + 'cg', + 'cgaa', + 'ddg', + 'ddgaa', + 'bm', + 'cbg', + 'cf', + 'ss_or_ssg', +]); +const TEAM_FILE_PATTERN = /^team[-_][^\\/]+\.ya?ml$/i; + +interface UserTeamShipRule { + name: string; + search_name?: string; + ship_type?: string[]; + min_level?: number; + max_level?: number; +} + +interface UserTeamPlanSlot { + name?: string; + search_name?: string; + ship_type?: string[]; + min_level?: number; + max_level?: number; + candidates?: UserTeamShipRule[]; +} + +interface UserTeamPlan { + file?: string; + name: string; + ships: UserTeamPlanSlot[]; +} + +/** 用户编队目录在开发模式下固定为 resource/user_team_plans。 */ +function userTeamPlansDir(): string { + return path.join( + isPackaged() ? appRoot() : resourceRoot(), + 'resource', + 'user_team_plans', + ); +} + +function initUserTeamPlansDir(): void { + fs.mkdirSync(userTeamPlansDir(), { recursive: true }); +} + +function isPlainObject(value: unknown): value is Record { + return Boolean(value) && typeof value === 'object' && !Array.isArray(value); +} + +function positiveInteger(value: unknown, field: string): number | undefined { + if (value === undefined || value === null || value === '') return undefined; + if (!Number.isInteger(value) || Number(value) < 1) { + throw new Error(`${field} 必须是大于或等于 1 的整数`); + } + return Number(value); +} + +function normalizeUserTeamShipTypes( + raw: unknown, + field: string, +): string[] | undefined { + if (raw === undefined || raw === null || raw === '') return undefined; + const values = typeof raw === 'string' ? [raw] : raw; + if (!Array.isArray(values) || values.length === 0) { + throw new Error(`${field} 必须是非空字符串列表`); + } + const result = values.map((value) => { + if (typeof value !== 'string' || !value.trim()) { + throw new Error(`${field} 必须是非空字符串列表`); + } + const shipType = value.trim().toLowerCase(); + if (!ALLOWED_FLEET_SHIP_TYPES.has(shipType)) { + throw new Error(`${field} 不符合后端接口: ${shipType}`); + } + return shipType; + }); + return [...new Set(result)]; +} + +/** 校验一艘主选或备选舰船自己的规则。 */ +function normalizeUserTeamShipRule( + raw: unknown, + field: string, +): UserTeamShipRule { + if (!isPlainObject(raw)) throw new Error(`${field} 必须是对象`); + const allowedKeys = new Set([ + 'name', + 'search_name', + 'ship_type', + 'min_level', + 'max_level', + ]); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error(`${field} 包含后端不支持的字段`); + } + if (typeof raw.name !== 'string' || !raw.name.trim()) { + throw new Error(`${field}.name 必须是非空字符串`); + } + + const result: UserTeamShipRule = { name: raw.name.trim() }; + if (raw.search_name !== undefined) { + if (typeof raw.search_name !== 'string' || !raw.search_name.trim()) { + throw new Error(`${field}.search_name 必须是非空字符串`); + } + result.search_name = raw.search_name.trim(); + } + const shipTypes = normalizeUserTeamShipTypes( + raw.ship_type, + `${field}.ship_type`, + ); + if (shipTypes) result.ship_type = shipTypes; + const minLevel = positiveInteger(raw.min_level, `${field}.min_level`); + const maxLevel = positiveInteger(raw.max_level, `${field}.max_level`); + if (minLevel !== undefined) result.min_level = minLevel; + if (maxLevel !== undefined) result.max_level = maxLevel; + if ( + minLevel !== undefined + && maxLevel !== undefined + && maxLevel < minLevel + ) { + throw new Error(`${field}.max_level 必须大于或等于 min_level`); + } + return result; +} + +/** 校验单个位置;主选可以为空,但位置必须至少包含一艘主选或备选。 */ +function normalizeUserTeamSlot(raw: unknown): UserTeamPlanSlot | null { + if (raw === null) return null; + if (!isPlainObject(raw)) throw new Error('ships 中的位置必须是对象'); + const allowedKeys = new Set([ + 'name', + 'candidates', + 'search_name', + 'ship_type', + 'min_level', + 'max_level', + ]); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error('位置包含后端不支持的字段'); + } + if (raw.candidates !== undefined && !Array.isArray(raw.candidates)) { + throw new Error('candidates 必须是列表'); + } + + const candidates = (raw.candidates ?? []).map( + (candidate: unknown, index: number) => normalizeUserTeamShipRule( + candidate, + `candidates[${index}]`, + ), + ); + const hasPrimary = typeof raw.name === 'string' && Boolean(raw.name.trim()); + if (!hasPrimary) { + if ( + raw.search_name !== undefined + || raw.ship_type !== undefined + || raw.min_level !== undefined + || raw.max_level !== undefined + ) { + throw new Error('没有主选 name 时不能填写主选规则'); + } + if (candidates.length === 0) { + throw new Error('位置至少需要一艘主选或备选舰船'); + } + return { candidates }; + } + + const { candidates: _ignored, ...primaryFields } = raw; + const result: UserTeamPlanSlot = { + ...normalizeUserTeamShipRule(primaryFields, '主选'), + }; + if (candidates.length > 0) result.candidates = candidates; + return result; +} + +/** 校验独立编队文件:一个名称对应一支最多六个位置的舰队。 */ +function normalizeUserTeamPlan(raw: unknown): UserTeamPlan { + if (!isPlainObject(raw)) throw new Error('编队 YAML 根节点必须是对象'); + const allowedKeys = new Set(['name', 'ships']); + if (Object.keys(raw).some(key => !allowedKeys.has(key))) { + throw new Error('编队 YAML 包含不支持的根字段'); + } + if (typeof raw.name !== 'string' || !raw.name.trim()) { + throw new Error('name 不能为空'); + } + if (!Array.isArray(raw.ships) || raw.ships.length < 1 || raw.ships.length > 6) { + throw new Error('ships 必须包含 1 到 6 个位置'); + } + const ships = raw.ships + .map(normalizeUserTeamSlot) + .filter((slot): slot is UserTeamPlanSlot => slot !== null); + if (ships.length === 0) { + throw new Error('ships 至少需要一个有效位置'); + } + return { name: raw.name.trim(), ships }; +} + +/** 使用行内 YAML 表示列表或备选对象,避免备选较多时纵向膨胀。 */ +function inlineYaml(value: unknown): string { + return yaml.dump(value, { + flowLevel: 0, + lineWidth: -1, + noRefs: true, + sortKeys: false, + }).trim(); +} + +/** 主选分行输出;纯备选位置不写 name,单个备选保持在同一行。 */ +function serializeUserTeamPlan(plan: UserTeamPlan): string { + const lines = [ + `name: ${inlineYaml(plan.name)}`, + 'ships:', + ]; + for (const slot of plan.ships) { + if (slot.name !== undefined) { + lines.push(` - name: ${inlineYaml(slot.name)}`); + if (slot.search_name !== undefined) { + lines.push(` search_name: ${inlineYaml(slot.search_name)}`); + } + if (slot.ship_type !== undefined) { + lines.push(` ship_type: ${inlineYaml(slot.ship_type)}`); + } + if (slot.min_level !== undefined) { + lines.push(` min_level: ${slot.min_level}`); + } + if (slot.max_level !== undefined) { + lines.push(` max_level: ${slot.max_level}`); + } + } + if (slot.candidates?.length) { + lines.push(slot.name === undefined ? ' - candidates:' : ' candidates:'); + for (const candidate of slot.candidates) { + lines.push(` - ${inlineYaml(candidate)}`); + } + } + } + return `${lines.join('\n')}\n`; +} + +function teamFileName(name: string): string { + const safeName = name + .trim() + .replace(/[<>:"/\\|?*\x00-\x1f]/g, '_') + .replace(/[. ]+$/g, '') + .slice(0, 80); + if (!safeName) throw new Error('编队预设名称不能用于文件名'); + return `team-${safeName}.yaml`; +} + +function atomicWrite(filePath: string, content: string): void { + const temporary = `${filePath}.${process.pid}.${Date.now()}.tmp`; + fs.writeFileSync(temporary, content, 'utf-8'); + try { + fs.renameSync(temporary, filePath); + } catch { + if (fs.existsSync(filePath)) fs.unlinkSync(filePath); + fs.renameSync(temporary, filePath); + } +} + +function readUserTeamPlan(filePath: string): UserTeamPlan { + return normalizeUserTeamPlan( + yaml.load(fs.readFileSync(filePath, 'utf-8')), + ); +} + +function yamlFiles(directory: string): string[] { + if (!fs.existsSync(directory)) return []; + return fs.readdirSync(directory) + .filter(file => /\.ya?ml$/i.test(file)) + .sort((left, right) => left.localeCompare(right, 'zh-CN')); +} + +/** 只列出用户编队目录中命名和内容均合法的编队文件。 */ +function listUserTeamPlans(): { + plans: UserTeamPlan[]; + errors: string[]; +} { + const directory = userTeamPlansDir(); + const plans: UserTeamPlan[] = []; + const errors: string[] = []; + for (const file of yamlFiles(directory)) { + if (!TEAM_FILE_PATTERN.test(file)) continue; + try { + const plan = readUserTeamPlan(path.join(directory, file)); + plans.push({ ...plan, file }); + } catch (error) { + const message = error instanceof Error ? error.message : String(error); + errors.push(`${file}: ${message}`); + } + } + return { plans, errors }; +} + +/** 读取清单,为配置页提供当前资料库状态。 */ +function getShipLibraryStatus(): ShipLibraryStatus { + const directory = shipLibraryDir(); + const manifestPath = path.join(directory, 'manifest.json'); + if (!fs.existsSync(manifestPath)) { + return { + exists: false, + path: directory, + shipCount: 0, + assetCount: 0, + missingAssets: 0, + }; + } + try { + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { + generated_at?: unknown; + counts?: Record; + }; + const counts = manifest.counts ?? {}; + return { + exists: true, + path: directory, + generatedAt: typeof manifest.generated_at === 'string' ? manifest.generated_at : undefined, + shipCount: typeof counts.ships === 'number' ? counts.ships : 0, + assetCount: typeof counts.assets === 'number' ? counts.assets : 0, + missingAssets: typeof counts.missing_assets === 'number' ? counts.missing_assets : 0, + }; + } catch (error) { + return { + exists: false, + path: directory, + shipCount: 0, + assetCount: 0, + missingAssets: 0, + error: `资料库清单读取失败: ${error instanceof Error ? error.message : String(error)}`, + }; + } +} + +function shipAssetUrl(relativePath: unknown): string { + if (typeof relativePath !== 'string' || !relativePath) return ''; + const root = path.resolve(shipLibraryDir()); + const absolutePath = path.resolve(root, relativePath); + if (absolutePath !== root && !absolutePath.startsWith(`${root}${path.sep}`)) return ''; + return pathToFileURL(absolutePath).href; +} + +/** 只向渲染进程提供舰队规划需要的清单字段和本地资源 URL。 */ +function getShipLibraryManifest(): ShipLibraryManifest { + const manifestPath = path.join(shipLibraryDir(), 'manifest.json'); + if (!fs.existsSync(manifestPath)) { + throw new Error('舰船资料库尚未建立,请先在配置页更新舰船数据库'); + } + const raw = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')) as { + schema_version?: unknown; + generated_at?: unknown; + labels?: unknown; + type_groups?: unknown; + ships?: unknown; + }; + if (!Array.isArray(raw.ships)) { + throw new Error('舰船资料库清单格式无效'); + } + return { + schemaVersion: typeof raw.schema_version === 'number' ? raw.schema_version : 0, + generatedAt: typeof raw.generated_at === 'string' ? raw.generated_at : '', + labels: raw.labels && typeof raw.labels === 'object' + ? raw.labels as Record + : {}, + typeGroups: raw.type_groups && typeof raw.type_groups === 'object' + ? raw.type_groups as Record + : {}, + ships: raw.ships.map((entry) => { + const ship = entry && typeof entry === 'object' + ? entry as Record + : {}; + return { + ...ship, + portraitUrl: shipAssetUrl(ship.portrait), + backgroundUrl: shipAssetUrl(ship.background), + frameUrl: shipAssetUrl(ship.frame), + typeIconUrl: shipAssetUrl(ship.type_icon), + }; + }), + }; +} + +function shipLibraryUpdaterPath(): string { + const root = isPackaged() ? resourceRoot() : appRoot(); + return path.join(root, 'tools', 'ship_library', 'update_ship_library.py'); +} + +function sendShipLibraryProgress(message: string): void { + mainWindow?.webContents.send('ship-library-update-progress', { message }); +} + +function runPython( + pythonCmd: string, + args: string[], +): Promise<{ code: number; output: string }> { + return new Promise((resolve) => { + const child = spawn(pythonCmd, args, { + cwd: appRoot(), + windowsHide: true, + env: pipEnv(), + }); + let output = ''; + child.stdout?.on('data', (chunk: Buffer) => { + output += chunk.toString(); + }); + child.stderr?.on('data', (chunk: Buffer) => { + output += chunk.toString(); + }); + child.once('error', (error) => { + resolve({ code: 1, output: error.message }); + }); + child.once('close', (code) => { + resolve({ code: code ?? 1, output }); + }); + }); +} + +function shipLibraryPythonBootstrap(): string { + const sitePackages = localSitePackages() + .replace(/\\/g, '\\\\') + .replace(/'/g, "\\'"); + return [ + 'import runpy, site, sys', + `sp = r'${sitePackages}'`, + 'sys.path.insert(0, sp)', + 'site.addsitedir(sp)', + 'script = sys.argv.pop(1)', + "runpy.run_path(script, run_name='__main__')", + ].join('; '); +} + +/** 确保更新器依赖安装在 GUI 自己的 Python 包目录中。 */ +async function ensureShipLibraryUpdaterDependencies( + pythonCmd: string, +): Promise { + const probe = await runPython(pythonCmd, [ + '-c', + [ + 'import site, sys', + `sp = r'${localSitePackages().replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`, + 'sys.path.insert(0, sp)', + 'site.addsitedir(sp)', + 'import requests, bs4', + ].join('; '), + ]); + if (probe.code === 0) return null; + + sendShipLibraryProgress('正在安装舰船数据库更新依赖…'); + if (!(await ensurePip(pythonCmd))) { + return '舰船数据库更新依赖安装失败:当前 Python 无法使用 pip'; + } + fs.mkdirSync(localSitePackages(), { recursive: true }); + const install = await runPython(pythonCmd, [ + '-m', + 'pip', + 'install', + '--target', + localSitePackages(), + 'requests', + 'beautifulsoup4', + ]); + if (install.code !== 0) { + return `舰船数据库更新依赖安装失败: ${install.output.trim().slice(-500)}`; + } + return null; +} + +/** 使用当前 GUI Python 环境执行增量更新,并解析脚本的机器可读结果。 */ +async function runShipLibraryUpdate(): Promise { + const pythonCmd = await findPython(); + if (!pythonCmd) { + return { success: false, error: '找不到可用的 Python 3.12 或 3.13' }; + } + const updaterPath = shipLibraryUpdaterPath(); + if (!fs.existsSync(updaterPath)) { + return { success: false, error: `找不到舰船资料库更新程序: ${updaterPath}` }; + } + const dependencyError = await ensureShipLibraryUpdaterDependencies(pythonCmd); + if (dependencyError) { + return { success: false, error: dependencyError }; + } + + return new Promise((resolve) => { + const child = spawn( + pythonCmd, + [ + '-c', + shipLibraryPythonBootstrap(), + updaterPath, + '--output', + shipLibraryDir(), + '--workers', + '8', + '--force-assets', + ], + { + cwd: appRoot(), + windowsHide: true, + env: pipEnv(), + }, + ); + let stdoutBuffer = ''; + let stderr = ''; + let result: ShipLibraryUpdateResult | null = null; + + const handleLine = (rawLine: string): void => { + const line = rawLine.trim(); + if (!line) return; + if (line.startsWith('PROGRESS sources')) { + sendShipLibraryProgress('正在获取舰R百科数据…'); + } else { + const records = line.match(/^PROGRESS records parsed=(\d+)$/); + const assets = line.match( + /^PROGRESS assets (\d+)\/(\d+) downloaded=(\d+) failed=(\d+)$/, + ); + if (records) { + sendShipLibraryProgress(`已读取 ${records[1]} 艘舰船,正在检查本地资源…`); + } else if (assets) { + sendShipLibraryProgress( + `正在检查资源 ${assets[1]}/${assets[2]},已下载 ${assets[3]},失败 ${assets[4]}`, + ); + } + } + if (line.startsWith('RESULT_JSON=')) { + try { + result = JSON.parse(line.slice('RESULT_JSON='.length)) as ShipLibraryUpdateResult; + } catch { + result = { success: false, error: '更新程序返回了无效结果' }; + } + } + }; + + child.stdout.setEncoding('utf-8'); + child.stdout.on('data', (chunk: string) => { + stdoutBuffer += chunk; + const lines = stdoutBuffer.split(/\r?\n/); + stdoutBuffer = lines.pop() ?? ''; + lines.forEach(handleLine); + }); + child.stderr.setEncoding('utf-8'); + child.stderr.on('data', (chunk: string) => { + stderr += chunk; + }); + child.once('error', (error) => { + resolve({ success: false, error: `更新程序启动失败: ${error.message}` }); + }); + child.once('close', (code) => { + if (stdoutBuffer) handleLine(stdoutBuffer); + resolve(result ?? { + success: false, + error: stderr.trim() || `更新程序异常退出(代码 ${code ?? 'unknown'})`, + }); + }); + }); +} + function createWindow(): BrowserWindow { const win = new BrowserWindow({ width: 1280, @@ -242,7 +864,7 @@ function createWindow(): BrowserWindow { responseHeaders: { ...details.responseHeaders, 'Content-Security-Policy': [ - `default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; connect-src 'self' http://localhost:${BACKEND_PORT} ws://localhost:${BACKEND_PORT}` + `default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self'; img-src 'self' file: data:; connect-src 'self' http://localhost:${BACKEND_PORT} ws://localhost:${BACKEND_PORT}` ], }, }); @@ -487,6 +1109,87 @@ ipcMain.handle('check-environment', async () => { return await checkEnvironment(); }); +ipcMain.handle('get-ship-library-status', () => { + return getShipLibraryStatus(); +}); + +ipcMain.handle('get-ship-library-manifest', () => { + return getShipLibraryManifest(); +}); + +ipcMain.handle('save-user-team-plan', ( + _event, + rawPlan: unknown, + overwrite: boolean, +) => { + try { + const plan = normalizeUserTeamPlan(rawPlan); + const file = teamFileName(plan.name); + const filePath = path.join(userTeamPlansDir(), file); + if (fs.existsSync(filePath) && overwrite !== true) { + return { + success: false, + exists: true, + file, + error: '存在同名配置', + }; + } + const content = serializeUserTeamPlan(plan); + atomicWrite(filePath, content); + return { success: true, file, plan: { ...plan, file } }; + } catch (error) { + return { + success: false, + error: error instanceof Error ? error.message : String(error), + }; + } +}); + +ipcMain.handle('pick-user-team-plan', async () => { + const directory = userTeamPlansDir(); + const result = await dialog.showOpenDialog({ + title: '加载编队预设', + defaultPath: directory, + properties: ['openFile'], + filters: [{ name: '编队 YAML', extensions: ['yaml', 'yml'] }], + }); + if (result.canceled || result.filePaths.length === 0) { + return { success: false, canceled: true }; + } + + const filePath = path.resolve(result.filePaths[0]); + const file = path.basename(filePath); + if ( + path.dirname(filePath).toLowerCase() !== path.resolve(directory).toLowerCase() + || !TEAM_FILE_PATTERN.test(file) + ) { + return { success: false, error: '当前yaml格式不符合规则' }; + } + try { + const plan = readUserTeamPlan(filePath); + return { success: true, file, plan: { ...plan, file } }; + } catch { + return { success: false, error: '当前yaml格式不符合规则' }; + } +}); + +ipcMain.handle('list-user-team-plans', () => { + return listUserTeamPlans(); +}); + +let shipLibraryUpdateRunning = false; +ipcMain.handle('update-ship-library', async () => { + if (shipLibraryUpdateRunning) { + return { success: false, error: '舰船资料库正在更新,请稍候' }; + } + shipLibraryUpdateRunning = true; + try { + return await runShipLibraryUpdate(); + } finally { + shipLibraryUpdateRunning = false; + } +}); + /* * 测试期接口(后端源码更新)已停用,逻辑保留便于回滚恢复。 ipcMain.handle('check-updates', async () => { @@ -612,6 +1315,8 @@ app.whenReady().then(() => { getMainWindow: () => mainWindow, }); initUserPlansDir(); + initUserShipLibraryDir(); + initUserTeamPlansDir(); initAutoUpdater(); createWindow(); diff --git a/electron/preload.ts b/electron/preload.ts index b75d86c..70929cd 100644 --- a/electron/preload.ts +++ b/electron/preload.ts @@ -188,6 +188,39 @@ contextBridge.exposeInMainWorld('electronBridge', { ipcRenderer.on('update-status', (_event, status) => callback(status)); }, + getShipLibraryStatus: () => { + return ipcRenderer.invoke('get-ship-library-status'); + }, + + getShipLibraryManifest: () => { + return ipcRenderer.invoke('get-ship-library-manifest'); + }, + + updateShipLibrary: () => { + return ipcRenderer.invoke('update-ship-library'); + }, + + onShipLibraryUpdateProgress: ( + callback: (progress: { message: string }) => void, + ) => { + ipcRenderer.on( + 'ship-library-update-progress', + (_event, progress) => callback(progress), + ); + }, + + saveUserTeamPlan: (plan: unknown, overwrite = false) => { + return ipcRenderer.invoke('save-user-team-plan', plan, overwrite); + }, + + pickUserTeamPlan: () => { + return ipcRenderer.invoke('pick-user-team-plan'); + }, + + listUserTeamPlans: () => { + return ipcRenderer.invoke('list-user-team-plans'); + }, + onBackendLog: (callback: (line: string) => void) => { ipcRenderer.on('backend-log', (_event, line: string) => callback(line)); }, diff --git a/package.json b/package.json index 2f1ca6b..5a5eed2 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,13 @@ "**/*" ] }, + { + "from": "tools/ship_library", + "to": "tools/ship_library", + "filter": [ + "update_ship_library.py" + ] + }, { "from": "setup.bat", "to": "setup.bat" diff --git a/resource/ship-library/assets/backgrounds/rarity-1.webp b/resource/ship-library/assets/backgrounds/rarity-1.webp new file mode 100644 index 0000000000000000000000000000000000000000..1fe19dd10e0a7af31a27ab32834470757ebdae8a GIT binary patch literal 13186 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 literal 0 HcmV?d00001 diff --git a/resource/ship-library/assets/backgrounds/rarity-2.webp b/resource/ship-library/assets/backgrounds/rarity-2.webp new file mode 100644 index 0000000000000000000000000000000000000000..4077a336d566464e485e82efcae032fe95493baf GIT binary patch literal 28136 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