WoWsStatInfo

Расширенная статистика и функционал на сайте World of Warships.

当前为 2016-12-26 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name WoWsStatInfo
  3. // @author Vov_chiK
  4. // @description Расширенная статистика и функционал на сайте World of Warships.
  5. // @copyright 2015+, Vov_chiK
  6. // @license GPL version 3 or any later version; http://www.gnu.org/copyleft/gpl.html
  7. // @namespace http://forum.walkure.pro/
  8. // @version 0.5.16.32
  9. // @creator Vov_chiK
  10. // @include https://worldofwarships.ru/ru/community/accounts/*
  11. // @include http://forum.worldofwarships.ru/index.php?/topic/*
  12. // @include http://forum.worldofwarships.ru/index.php?/user/*
  13. // @include https://worldofwarships.eu/*/community/accounts/*
  14. // @include http://forum.worldofwarships.eu/index.php?/topic/*
  15. // @include http://forum.worldofwarships.eu/index.php?/user/*
  16. // @include https://worldofwarships.com/*/community/accounts/*
  17. // @include http://forum.worldofwarships.com/index.php?/topic/*
  18. // @include http://forum.worldofwarships.com/index.php?/user/*
  19. // @include https://worldofwarships.asia/*/community/accounts/*
  20. // @include http://forum.worldofwarships.asia/index.php?/topic/*
  21. // @include http://forum.worldofwarships.asia/index.php?/user/*
  22. // @match https://worldofwarships.ru/ru/community/accounts/*
  23. // @match http://forum.worldofwarships.ru/index.php?/topic/*
  24. // @match http://forum.worldofwarships.ru/index.php?/user/*
  25. // @match https://worldofwarships.eu/*/community/accounts/*
  26. // @match http://forum.worldofwarships.eu/index.php?/topic/*
  27. // @match http://forum.worldofwarships.eu/index.php?/user/*
  28. // @match https://worldofwarships.com/*/community/accounts/*
  29. // @match http://forum.worldofwarships.com/index.php?/topic/*
  30. // @match http://forum.worldofwarships.com/index.php?/user/*
  31. // @match https://worldofwarships.asia/*/community/accounts/*
  32. // @match http://forum.worldofwarships.asia/index.php?/topic/*
  33. // @match http://forum.worldofwarships.asia/index.php?/user/*
  34. // @grant GM_xmlhttpRequest
  35. // ==/UserScript==
  36.  
  37. (function(window){
  38. /* ===== Main function ===== */
  39. function WoWsStatInfo(){
  40. var VersionWoWsStatInfo = '0.5.16.32';
  41. var WoWsStatInfoLinkLoc = [];
  42. WoWsStatInfoLinkLoc['ru'] = 'http://forum.worldofwarships.ru/index.php?/topic/19158-';
  43. WoWsStatInfoLinkLoc['asia'] = 'http://forum.worldofwarships.asia/index.php?/topic/8950-';
  44. WoWsStatInfoLinkLoc['na'] = 'http://forum.worldofwarships.com/index.php?/topic/47436-';
  45. WoWsStatInfoLinkLoc['eu'] = 'http://forum.worldofwarships.eu/index.php?/topic/14650-';
  46. var WoWsStatInfoLinkNameLoc = [];
  47. WoWsStatInfoLinkNameLoc['ru'] = '[ALL] [WoWsStatInfo] Расширенная статистика на оф. сайте.';
  48. WoWsStatInfoLinkNameLoc['asia'] = '[ALL] [WoWsStatInfo] Extended stat-info for official WoWS profile.';
  49. WoWsStatInfoLinkNameLoc['na'] = '[ALL] [WoWsStatInfo] Extended stat-info for official WoWS profile.';
  50. WoWsStatInfoLinkNameLoc['eu'] = '[ALL] [WoWsStatInfo] Extended stat-info for official WoWS profile.';
  51. var lang = getCookie('hllang');
  52. var host_split = window.location.host.split('.');
  53. var realm = host_split[host_split.length - 1]; if(realm == 'com'){realm = 'na';}
  54. var realm_host = realm; if(realm == 'na'){realm_host = 'com';}
  55. if(lang == null){
  56. if(realm == 'ru'){
  57. lang = 'ru';
  58. }else{
  59. lang = 'en';
  60. }
  61. }
  62. if(window.location.host.indexOf("cm-ru.wargaming.net") > -1){return;}
  63. var localizationText = getlocalizationText(lang);
  64. var application_id = getApplicationId();
  65. var WoWsStatInfoLink = WoWsStatInfoLinkLoc[realm];
  66. var WoWsStatInfoLinkName = WoWsStatInfoLinkNameLoc[realm];
  67. var WGAPI = 'https://api.worldoftanks.'+realm_host+'/wgn/';
  68. var WOWSAPI = 'https://api.worldofwarships.'+realm_host+'/wows/';
  69. var WoWsStatInfoHref = 'https://vzhabin.ru/US_WoWsStatInfo/';
  70. var Process = 0;
  71. var MaxProcess = 3;
  72. var MembersArray = [];
  73. var StatPvPMemberArray = [];
  74. var Encyclopedia = null;
  75. var typeStat = ["pvp", "pve", "pvp_solo", "pvp_div", "pvp_div2", "pvp_div3"];
  76. var typeShip = ["Battleship", "AirCarrier", "Cruiser", "Destroyer"];
  77. var color = new Array();
  78. color['very_bad'] = '#FE0E00'; // очень плохо, хуже чем у 85%
  79. color['bad'] = '#FE7903'; // плохо, хуже чем у 50%
  80. color['normal'] = '#F8F400'; // средне, лучше чем у 50%
  81. color['good'] = '#60FF00'; // хорошо, лучше чем у 75%
  82. color['very_good'] = '#02C9B3'; // очень хорошо, лучше чем у 95%
  83. color['unique'] = '#D042F3'; // уникально, лучше чем у 99%
  84. var colorStat = null;
  85. var ExpShips = null;
  86. /* ===== Style and Script UserScript ===== */
  87. {
  88. var StyleWoWsStatInfo = '' +
  89. 'div.div-link-block{font-size:13px; color: #fff; text-align: right; padding-top: 10px; padding-bottom: 10px;}' +
  90. 'span.link-block:hover{border-bottom: 1px dotted #fff; cursor: pointer;}' +
  91. 'span.link-block div.icon-link-block{background: url("//'+realm+'.wargaming.net/clans/static/0.1.0.1/images/table-sorter/table-sorter_arrow_sprite.png") no-repeat 0 0; width: 10px; height: 10px; margin: -15px 100%;}' +
  92. 'span.hide-block div.icon-link-block{background-position: 100% -26px;}' +
  93. 'span.show-block div.icon-link-block{background-position: 100% -16px;}' +
  94. 'div#userscript-block{border-radius: 2px; background-color: rgba(255, 255, 255, 0.03); border: 1px solid rgba(255, 255, 255, 0.1); padding: 10px; margin: 10px 0; line-height: 20px;}' +
  95. 'div.hide-block{display: none;}' +
  96. 'div.wowsstatinfo-stat{text-align: center; margin-top: 10px; color: white; font-size: 16px;}' +
  97. 'span.name-stat{color: #ffcc33;}' +
  98. 'table.account-table td{white-space: nowrap;}' +
  99. 'li.account-tab div._title{padding: 0 10px;}' +
  100. 'div.chart_div{text-align: center; float: left; margin-right: 40px;}' +
  101. '.userscript-placeholder {box-sizing: border-box;width: 550px;height: 330px;padding: 5px 15px 15px 40px;margin: 15px auto 30px auto;border: 1px solid #ddd;background: #fff;background: linear-gradient(#f6f6f6 0, #fff 50px);background: -o-linear-gradient(#f6f6f6 0, #fff 50px);background: -ms-linear-gradient(#f6f6f6 0, #fff 50px);background: -moz-linear-gradient(#f6f6f6 0, #fff 50px);background: -webkit-linear-gradient(#f6f6f6 0, #fff 50px);box-shadow: 0 3px 10px rgba(0,0,0,0.15);-o-box-shadow: 0 3px 10px rgba(0,0,0,0.1);-ms-box-shadow: 0 3px 10px rgba(0,0,0,0.1);-moz-box-shadow: 0 3px 10px rgba(0,0,0,0.1);-webkit-box-shadow: 0 3px 10px rgba(0,0,0,0.1);}' +
  102. '.chart-placeholder {width: 500px;height: 300px;font-size: 14px;line-height: 1.2em;}' +
  103. '.legend table {border-spacing: 5px;}' +
  104. '.flot-y-axis {margin-left: -40px; margin-top: -12px;}' +
  105. '.flot-x-axis {margin-left: -15px;}' +
  106. '';
  107. var StyleWoWsStatInfoAdd = document.createElement("style");
  108. StyleWoWsStatInfoAdd.textContent = StyleWoWsStatInfo.toString();
  109. document.head.appendChild(StyleWoWsStatInfoAdd);
  110. }
  111. /* ===== Flot: Attractive JavaScript plotting for jQuery ===== */
  112. if(window.location.host == 'worldofwarships.'+realm_host){
  113. var ScriptChart = document.createElement("script");
  114. ScriptChart.setAttribute("src", "https://www.flotcharts.org/javascript/jquery.flot.min.js");
  115. document.head.appendChild(ScriptChart);
  116. }
  117. /* ===== Message UserScript ===== */
  118. if(window.location.host != 'forum.worldofwarships.'+realm_host){
  119. var message = document.createElement("div");
  120. message.setAttribute("id", "message-wowsstatinfo");
  121. message.setAttribute("class", "wsi-ui-dialog wsi-ui-widget wsi-ui-widget-content wsi-ui-corner-all wsi-ui-front");
  122. message.setAttribute("style", "display: none; z-index:9999; left: 50%; margin-left: 0px; top: 0px;");
  123. message.innerHTML = '' +
  124. '<style>' +
  125. '.wsi-ui-dialog{box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.12), 0 0 25px 25px rgba(0, 0, 0, 0.3);background-color: rgba(41, 41, 41, 0.8);position: absolute;top: 0;left: 0;outline: 0;padding: 23px 31px 28px;}' +
  126. '.wsi-ui-widget-content{color: #b1b2b3;}' +
  127. '.wsi-ui-widget{font-family: Arial, "Helvetica CY", Helvetica, sans-serif;font-size: 15px;}' +
  128. '.wsi-ui-corner-all{border-bottom-right-radius: 2px;border-bottom-left-radius: 2px;border-top-right-radius: 2px;border-top-left-radius: 2px;}' +
  129. '.wsi-ui-front{z-index: 250;}' +
  130. '.wsi-ui-dialog:before{background: url("http://ru.wargaming.net/clans/static/1.4.4/images/plugins/jquery-ui/dialog_gradient.png") repeat-x;height: 162px;width: 100%;position: absolute;top: 0;left: 0;z-index: 5;}' +
  131. '.wsi-ui-dialog .wsi-ui-dialog-titlebar{border-bottom: 1px solid rgba(0, 0, 0, 0.7);box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05);padding: 0 0 14px;position: relative;z-index: 10;}' +
  132. '.wsi-ui-widget-header{color: #fff;font-family: "WarHeliosCondC", Arial Narrow, Tahoma, arial, sans-serif;font-size: 25px;font-weight: normal;line-height: 30px;}' +
  133. '.wsi-ui-helper-clearfix{min-height: 0;support: IE7;}' +
  134. '.wsi-ui-widget-content{color: #b1b2b3;}' +
  135. '.wsi-ui-widget{font-family: Arial, "Helvetica CY", Helvetica, sans-serif;font-size: 15px;}' +
  136. '.wsi-ui-helper-clearfix:before, .wsi-ui-helper-clearfix:after{content: "";display: table;border-collapse: collapse;}' +
  137. '.wsi-ui-helper-clearfix:after{clear: both;}' +
  138. '.wsi-ui-helper-clearfix:before, .wsi-ui-helper-clearfix:after{content: "";display: table;border-collapse: collapse;}' +
  139. '.wsi-ui-dialog .wsi-ui-dialog-title{float: left;margin: 0;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}' +
  140. '.wsi-ui-dialog .wsi-ui-dialog-titlebar-close{margin: -16px -3px 0;height: 20px;width: 20px;position: absolute;top: 50%;right: 0;}' +
  141. '.wsi-ui-widget .wsi-ui-widget{font-size: 1em;}' +
  142. 'wsi-button.wsi-ui-wsi-button-icon-only {width: 16px;}' +
  143. '.wsi-ui-state-default{border: 1px solid transparent;color: #b1b2b3;display: inline-block;font-size: 13px;line-height: 30px;padding: 0 5px;height: 30px;width: 20px;}' +
  144. '.wsi-ui-wsi-button{background: none;border: 0;display: inline-block;position: relative;padding: 0;line-height: normal;cursor: pointer;vertical-align: middle;text-align: center;overflow: visible;}' +
  145. '.wsi-ui-wsi-button-icon-only .wsi-ui-icon{left: 50%;margin-left: -8px;}' +
  146. '.wsi-ui-wsi-button-icon-only .wsi-ui-icon, .wsi-ui-wsi-button-text-icon-primary .wsi-ui-icon, .wsi-ui-wsi-button-text-icon-secondary .wsi-ui-icon, .wsi-ui-wsi-button-text-icons .wsi-ui-icon, .wsi-ui-wsi-button-icons-only .wsi-ui-icon{position: absolute;top: 50%;margin-top: -8px;}' +
  147. '.wsi-ui-icon-closethick{background: url("https://ru.wargaming.net/clans/static/1.4.4/images/plugins/jquery-ui/dialog_close.png");}' +
  148. '.wsi-ui-icon{width: 16px;height: 16px;}' +
  149. '.wsi-ui-icon{display: block;text-indent: -99999px;overflow: hidden;background-repeat: no-repeat;}' +
  150. '.wsi-ui-state-default{border: 1px solid transparent;color: #b1b2b3;display: inline-block;font-size: 13px;line-height: 30px;padding: 0 5px;height: 30px;width: 20px;}' +
  151. '.wsi-ui-wsi-button-icon-only .wsi-ui-wsi-button-text, .wsi-ui-wsi-button-icons-only .wsi-ui-wsi-button-text{padding: .4em;text-indent: -9999999px;}' +
  152. '.wsi-ui-wsi-button .wsi-ui-wsi-button-text{display: block;line-height: normal;}' +
  153. '.wsi-ui-dialog .wsi-ui-dialog-content{position: relative;border: 0;padding: 0;background: none;z-index: 10;}' +
  154. '.wsi-ui-widget-content{color: #b1b2b3;}' +
  155. '.wsi-popup{margin: 10px auto 0;font-size: 15px;transition: height .3s;}' +
  156. '.wsi-popup_footer{margin-top: 20px;position: relative;}' +
  157. '.wsi-button__align-middle{vertical-align: middle;}' +
  158. '.wsi-button{-webkit-appearance: none;-moz-appearance: none;background: #735917;border-radius: 2px;border: none;box-shadow: 0 0 10px rgba(0, 0, 0, 0.3), 1px 0 2px rgba(0, 0, 0, 0.3);display: inline-block;padding: 0 0 2px;overflow: hidden;color: #000;font-family: Arial, "Helvetica CY", Helvetica, sans-serif;font-size: 17px;font-weight: normal;text-decoration: none;cursor: pointer;vertical-align: top;}' +
  159. '.wsi-button_wrapper{background: #dbae30;background: linear-gradient(to bottom, #fff544 0%, #dbae30 100%);border-radius: 2px;display: block;padding: 1px 1px 0;position: relative;}' +
  160. '.wsi-button_body{background: #e5ad2c;background: linear-gradient(to bottom, #e7b530 0%, #e5ad2c 100%);display: block;border-radius: 2px;padding: 10px 23px 11px;position: relative;text-shadow: 0 1px 0 rgba(255, 255, 255, 0.3);transition: all .2s;}' +
  161. '.wsi-button_inner{display: block;position: relative;z-index: 10;white-space: nowrap;line-height: 20px;}' +
  162. '.wsi-link__cancel{display: inline-block;font-size: 15px;margin-left: 18px;padding-top: 10px;}' +
  163. '.wsi-link{border-bottom: 1px solid transparent;padding-bottom: 1px;color: #e5b12e;line-height: 18px;text-decoration: none;transition: all .2s;}' +
  164. '</style>' +
  165. '<div class="wsi-ui-dialog-titlebar wsi-ui-widget-header wsi-ui-corner-all wsi-ui-helper-clearfix">' +
  166. '<span class="wsi-ui-dialog-title">{%TITLE%}</span>' +
  167. '<wsi-button id="userscript-message-close" class="wsi-ui-wsi-button wsi-ui-widget wsi-ui-state-default wsi-ui-corner-all wsi-ui-wsi-button-icon-only wsi-ui-dialog-titlebar-close" title="Close">' +
  168. '<span class="wsi-ui-wsi-button-icon-primary wsi-ui-icon wsi-ui-icon-closethick"></span>' +
  169. '<span class="wsi-ui-wsi-button-text">Close</span>' +
  170. '</wsi-button>' +
  171. '</div>' +
  172. '<div class="wsi-ui-dialog-content wsi-ui-widget-content" style="width: auto; min-height: 44px; max-height: none; height: auto;">' +
  173. '<div class="wsi-popup">{%TEXT%}</div>' +
  174. '<div class="wsi-popup_footer">' +
  175. '<wsi-button id="userscript-message-ok" class="wsi-button wsi-button__align-middle">' +
  176. '<span class="wsi-button_wrapper">' +
  177. '<span class="wsi-button_body">' +
  178. '<span class="wsi-button_inner">'+localizationText['Ok']+'</span>' +
  179. '</span>' +
  180. '</span>' +
  181. '</wsi-button>' +
  182. '<a id="userscript-message-cancel" class="wsi-link wsi-link__cancel" style="display: block; cursor: pointer;" >'+localizationText['Cancel']+'</a>' +
  183. '</div>' +
  184. '</div>' +
  185. '';
  186. document.body.appendChild(message);
  187. var messagebg = document.createElement("div");
  188. messagebg.setAttribute("id", "userscript-message-bg");
  189. messagebg.setAttribute("style", "display: none; z-index:9998; background: url('//"+realm+".wargaming.net/clans/static/0.1.0.1/images/plugins/jquery-ui/widget_overlay-pattern.png'); position: fixed; top: 0; left: 0; width: 100%; height: 100%;");
  190. document.body.appendChild(messagebg);
  191. }
  192. getBrowser();
  193. function getBrowser(){
  194. var nVer = navigator.appVersion;
  195. var nAgt = navigator.userAgent;
  196. var browserName = navigator.appName;
  197. var fullVersion = ''+parseFloat(navigator.appVersion);
  198. var majorVersion = parseInt(navigator.appVersion, 10);
  199. var nameOffset, verOffset, ix;
  200.  
  201. // In Opera 15+, the true version is after "OPR/"
  202. if((verOffset = nAgt.indexOf("OPR/")) != -1){
  203. browserName = "Opera";
  204. fullVersion = nAgt.substring(verOffset + 4);
  205. }
  206. // In older Opera, the true version is after "Opera" or after "Version"
  207. else if((verOffset = nAgt.indexOf("Opera")) != -1){
  208. browserName = "Opera";
  209. fullVersion = nAgt.substring(verOffset + 6);
  210. if((verOffset = nAgt.indexOf("Version")) != -1)
  211. fullVersion = nAgt.substring(verOffset + 8);
  212. }
  213. // In MSIE, the true version is after "MSIE" in userAgent
  214. else if((verOffset = nAgt.indexOf("MSIE")) != -1){
  215. browserName = "Microsoft Internet Explorer";
  216. fullVersion = nAgt.substring(verOffset + 5);
  217. }
  218. // In Chrome, the true version is after "Chrome"
  219. else if((verOffset = nAgt.indexOf("Chrome")) != -1) {
  220. browserName = "Chrome";
  221. fullVersion = nAgt.substring(verOffset + 7);
  222. }
  223. // In Safari, the true version is after "Safari" or after "Version"
  224. else if((verOffset = nAgt.indexOf("Safari")) != -1){
  225. browserName = "Safari";
  226. fullVersion = nAgt.substring(verOffset + 7);
  227. if((verOffset = nAgt.indexOf("Version")) != -1)
  228. fullVersion = nAgt.substring(verOffset + 8);
  229. }
  230. // In Firefox, the true version is after "Firefox"
  231. else if((verOffset = nAgt.indexOf("Firefox")) != -1){
  232. browserName = "Firefox";
  233. fullVersion = nAgt.substring(verOffset + 8);
  234. }
  235. // In most other browsers, "name/version" is at the end of userAgent
  236. else if((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))){
  237. browserName = nAgt.substring(nameOffset, verOffset);
  238. fullVersion = nAgt.substring(verOffset + 1);
  239. if(browserName.toLowerCase() == browserName.toUpperCase()){
  240. browserName = navigator.appName;
  241. }
  242. }
  243. // trim the fullVersion string at semicolon/space if present
  244. if((ix = fullVersion.indexOf(";")) != -1)
  245. fullVersion = fullVersion.substring(0, ix);
  246. if((ix = fullVersion.indexOf(" ")) != -1)
  247. fullVersion = fullVersion.substring(0, ix);
  248.  
  249. majorVersion = parseInt(''+fullVersion, 10);
  250. if(isNaN(majorVersion)){
  251. fullVersion = ''+parseFloat(navigator.appVersion);
  252. majorVersion = parseInt(navigator.appVersion, 10);
  253. }
  254. var url = window.location.href;
  255. console.log(''
  256. +'----------------------- WoWsStatInfo '+VersionWoWsStatInfo+' -----------------------\n'
  257. +'| Lang = '+lang+'\n'
  258. +'| URL = '+url+'\n'
  259. +'| Browser name = '+browserName+'\n'
  260. +'| Full version = '+fullVersion+'\n'
  261. +'| Major version = '+majorVersion+'\n'
  262. +'| navigator.appName = '+navigator.appName+'\n'
  263. +'| navigator.userAgent = '+navigator.userAgent+'\n'
  264. +'---------------------------------------------------------------------\n'
  265. );
  266. var navigatorInfo = [];
  267. navigatorInfo['browserName'] = browserName;
  268. navigatorInfo['fullVersion'] = fullVersion;
  269. navigatorInfo['majorVersion'] = majorVersion;
  270. navigatorInfo['appName'] = navigator.appName;
  271. navigatorInfo['userAgent'] = navigator.userAgent;
  272. return navigatorInfo;
  273. }
  274. /* ===== Check load page ===== */
  275. if(window.location.href.indexOf("accounts") > -1 && window.location.href.split('/').length >= 8 && window.location.href.split('/')[6].match(/[0-9]+/) != null){
  276. checkJson();
  277. lang = window.location.href.split('/')[3].match(/[a-z\s-]+/); if(lang == 'zh-tw'){lang = 'zh-tw';}
  278. localizationText = getlocalizationText(lang);
  279. getJson(WoWsStatInfoHref+'version.php?random='+Math.floor(Math.random()*100000001), doneLastVersion, errorLastVersion);
  280. var account_id = window.location.href.split('/')[6].match(/[0-9]+/);
  281. MemberProfilePage();
  282. }else if(window.location.host == 'forum.worldofwarships.'+realm_host && window.location.href.indexOf("/user/") > -1){
  283. ForumUserPage();
  284. }else if(window.location.host == 'forum.worldofwarships.'+realm_host && window.location.href.indexOf("/topic/") > -1){
  285. ForumTopicPage();
  286. }
  287. function doneLastVersion(url, response){
  288. var data = response;
  289. if(VersionWoWsStatInfo != data['version']){
  290. onShowMessage(
  291. localizationText['Box'],
  292. localizationText['NewVersion']+' WoWsStatInfo '+data['version']+'<br />'+localizationText['NewUpdate']+'.' +
  293. '<br /><br />' +
  294. localizationText['userscript-topic']+'<br />'+
  295. '<a target="_blank" href="'+WoWsStatInfoLink+'">' +
  296. WoWsStatInfoLinkName +
  297. '</a>',
  298. onCloseMessage,
  299. localizationText['Ok'],
  300. false
  301. );
  302. }
  303. }
  304. function errorLastVersion(url){}
  305. /* ===== Pages function ===== */
  306. function MemberProfilePage(){
  307. if(colorStat == null || ExpShips == null){
  308. console.log('colorStat == null || ExpShips == null');
  309. setTimeout(function(){MemberProfilePage();}, 1000);
  310. return;
  311. }
  312. var account_profile = document.getElementsByClassName('account-profile')[0];
  313. if(account_profile === undefined){return;}
  314. MembersArray[0] = [];
  315. var _nick = document.getElementsByClassName('_nick')[0];
  316. nickname = _nick.textContent;
  317. var row = document.getElementsByClassName('row')[2];
  318. var div = document.createElement('div');
  319. div.setAttribute('id', 'userscript-block-list');
  320. div.setAttribute('style', 'padding: 0px 15px 20px 15px;');
  321. div.innerHTML = '' +
  322. '<div id="userscript-forum-link">' +
  323. '<a target="_blank" href="http://forum.worldofwarships.'+realm_host+'/index.php?/user/dn-'+nickname+'-/">'+localizationText['forum-profile']+'</a>' +
  324. '</div>' +
  325. '<style>' +
  326. '.b-profile-clan{max-width: 400px; padding-right: 100px;margin-bottom: 14px;padding-top: 5px;position: relative;}' +
  327. '.b-profile-clan_photo{float: left;width: 61px;position: relative;min-height: 70px;top: 5px;}' +
  328. '.b-profile-clan_color{width: 15px;height: 15px;position: absolute;left: 38px;top: 2px;}' +
  329. '.b-profile-clan_link{background-image: url("data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkI4NTIxMEI3ODRFODExRTI5ODYxODk4QjE3Q0IyNzkyIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkI4NTIxMEI4ODRFODExRTI5ODYxODk4QjE3Q0IyNzkyIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6Qjg1MjEwQjU4NEU4MTFFMjk4NjE4OThCMTdDQjI3OTIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6Qjg1MjEwQjY4NEU4MTFFMjk4NjE4OThCMTdDQjI3OTIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7V+fopAAAMmElEQVR42sxazY7jxhEmKc2IzaZmRrObwEGQi53kklcI4JzzPL7kkFtOQeAn2FfJYYG9OCcfYsd2YsObALGzQLwzErub0khkurqruqop7QgOYMNacHtIUeyuv6++qmZZxE95YqS/v/PPixcv2vl8XvlPOB+GodjtdoNzbnj16tX+yy+/HJ49e7Z/+fLl9Kfjm8a5EKASRynG7/zz/PnzxUcff/L1V//+CgQqDod9sd8fwng4HPzf+2KxUMXbb/88/A3X6AAlwDGOY3re3d031XwiFJxf+GOGx/ci3Icffqjv7jfFRx//9Vv9rvQWnvljXrKz7bbbMM6FdeZ/+eCDdz/79LNdZzfz3vXVdretvDuM4zCMh+EwPjwchr7fetUMIxgdtOS1OhwOg79lX2y3u6C2h/3DMKtmXvvbEdzLa3mA633fj4P/jf8vTA4W8c8YL+ZVDQvSTVN88cXn/7ci3/rJT5PZpMUu/vH53x9+9957f3bOFLXSRZ9GWzSNLpztigVdr/25H+G6tTC2fuwKFe4zflz6+/z9eN6o1o+b8D3dD89r9LKw5oOixvOf/fitEZ4L93X+vhavX+K8CuYxm6LWbbH139f+Pu+Mf/j6P69+DyGGcVpWAihm6/V6Bj9u6CEKhambYt2tw8ONjcJaIRQswsBkSSh/3ay9EprC+es6CL32QrQoFAjTBeHhdzA6FNaAcui+MF9UDiitxnkWIKwxSYnL61WQBsJsKhiMM2dttVCkYS8caBQe4oVY6mXUMCwShTIWhTNxMQ4tBtfpvNFXuHi/6G6Dllrj4uN1GEko3UahwSI9Wg6E0hqvN2ApeC4rdbO+S+5IyFoJeK88IlUgxCUu7tK7jzEdTircoI4PBQ12KBRMusD7wdJhDPevWWhYnAXLLsNzolAmsxxZPjxPuC1cb1DYGuej+66uV0mw2WyWCRaE2213ZXA/EzUfNKZj7IBlehEbKsVUXBxM5lwXJo+x1yYN224TRxsXb8MiURjvrmHR7RUKLdwMldMZMZ9iD4nKbYvN/euR0thsxq6YPvOLC78oi7EQf9yjUPCQ4KZ+0dEtYuxQTDlh2RALyUJxDN+DMHaDgBHHoAS47mMYYs+hG5I7djAPhoHC+YLyMFxAmUthsbI8tpiH636AgA+L8pN0m3VyRxAKNAojTJY0plGDaCFVRyE1ui2gISyaFqtUdKvovvF5PVke3S25KT3HiudTTCuNnuSFX9+Nj7kiZPBx5yI09xjIwWKgIdQcQDhNUit2l4haACw4EtDgc6J75RqH8x4tTBYxXSeAp8X5NAMXzSNie3nzeIz5RPow1Ohui4YfTosz+HCYTMZajzGVUFTGoJaL2CRAqDGVALoZikUQtoX7TPpdDfkPf28QRXsbLR7duy3Wd6+HFE7zE4LtHh5GS5qaAETQsJ+kQ8iOEMwQ704I3WhelOuim23x/mjRJbsx5qm42OhuWufKaTDfxbyHMQ2oeM5iDw9gsZhvyJfJxyFJbwk4hDtpigkd81DQMCkDheoNWWKqtE1yW3LLpIyG7yfhHQkvlI4x9rhgwOEcWqKnRaOl+gnNCpOkfOVjD1GxF2ga0JDQVCw25DGL6Cc9JFjKJCEUpoomCcVCp3MLeexWJOjT4DE07TJphpIwLTYt0kZ0c8jdgrDorkR3auGm5J4pLwrUy/KdIeEEUGi2THJvFIosv77/RlisOhbMs+2xtyZpog7JM3erhGqO6RYBDiyKaJDDwO9FMg0pIxNauJkhQtwlUhCUhha0E2Byht34ZvX0jZQqxpgv4i59LFFGh2StCZqR20mfD5pXnFfAUg1aLionElaiR0RwSYgspjClqAkaN0IJWWxR0leBeRQ/8lWBdMV5brHDuO2ZNRO7j+4ThQv0h9wtcbhl0nCH6NdLqG8kzaLfs8YbaSEBPE3ikrmFp0I/fevtceVr5svLy2SxTLC9R0WlpFCcT5oglEnuR8JrokUiBdBijMnzWW+6RMcUMhpNBFqiKNExYcFcKFZSYEgeFV/+81+/8CKs/WGOY2wYMDZ0ZPG+orUZ9HKx6VLpwPeTMIyajGI9jmDhQNMcax5o2VYwGqgSiDgz+m5EqaORfl2FWL+6uT2ququ85zMynQE6hYR4Gug95a1MaImmcfEJ+lOJEoXdOiLQiG6GYjqPKQIyqsd6Q0mdqoSIzjKPnRRsvz8MoCli47WoqwgNKXBtFx9K7tEFS+j0/ZZix+DzKEXYmMcAWCRqslLw3EkmssxSQoPMgywomcdJwYbh4N1iiZxOQLrhSSRq9b2ZAAQwlWUGHLHuQveynMQX2BOpdU7bUl5TOQNRDfVMItGWKWJ9f8Zi0EXaui5BtVKcJF1iFAKllEzeUagpQ6BkK5kCJVeiX5KGSdSrkxDRvaPlYykUz6Oyr29uHxcMGpALhZytWQqopbYAFpHoFjBeIl3Swf0Ma3iaf5AAE0OpKQbFyEAT3X6bqgaDecugG1NMR0Jsu/Xj4HExv+CKWDCIYBmkO84Yhlw/7pzJ67OM9aNF8HwhKu6UAiTdapgMBEAhjqkpb0Z6VqOSAzlweT122mIQYyI5U53lkk9H2kQ9ELIkcUZiFgYtYCXLV2gBLXoWhjlmTfkvVeRE03jeXlpads02ZywGnV1gHuRmi1qnUsQ47gopkaStYQsTnWrUCW4n6jCmVcRsNNZrOlnGJo9hMlBjQ4mKzRpRt72+OQf3+6Ku29QOiBpmN+nRTbY+v1HPQaX6CTWs2JKZcBPa1LQMHEy0DXfHFAvDHhSTOXkIxdx5i/nDUkeXNEeTiZIFGj52QkxTJU35x3FzdUqLCCgCULlu0h7vshjvLT9PFqORc+pgufbqvMXGRliAaVQUauuExhvu1LreMLqlVEAVtU6MQ0I/Jetp74RKIyWBA4tdaggZJNrcvdo8brFZVZXOiocT92u0aNgYbpIq9Pk6Ln6h8gpXU5dJHwvhHKNrLZkHoWsCDtHO1loUqYyiV2dj7HAoZfs4NWgQWo3h3RTq2Sc3IRqkJ31AxXmJkrPFIja5neHGT5OStxZ1HaNpapY2goj764/DvXdFJype6utR/pDdJCva39x+brP+H3/Pi+/xfOtMxjUT0yALCuXWatKUJXTF86vr1Vm4LykpUr9voXI6pESS7bE9HdBP0CPZLFXZ1hAl69gbMeKciG3TYmy13BbgfNllYZKev7k/R6mGqu8tN1YEtyN2TRCc2sxmkwOA2HqaWpCIbYP1WdOIVCH6kIR6jIYcFhxzHLPXqyePW6wsixH6h7L5qVvZbjYCktESGMhHvQnRkw+QriYxdpQCyL2iBxChVopZvVRqUh6UTGctNgxlIp4uarjrjjcEiNak3ZbEGI4bL7w4TvKN6G1spZuqNrUNrDOCSC85P6bic5O6aMtzeQwaplTsMctn5mEkajXUe8AkjoygFl2q1DEOewF6ksSPm6C9BByV138Z+6eK2trYCT7HPODDLTRGpQWhomb3S0kcLRaEVoL7WWlhZuVH9Zeo55SA/FOWlx5BqQeEvLk9E2P7w77iDYM2QXxv8sDPW2VaFJ9MhNU0GYvnccxMFo8AlZUw010dLSrtVLSeYR6l/8eMQFS4otEi8xZpsEltcJ3ciLeUjGiqcsxI5SyyGJQbD/kGRHpOI4iwDTua5bl6rExN0imHE1yvnxBb2niXFpVlfYJq1x2x/loo5ThfntjKEi05uXFxNkFbkWQzTUlLyZdJ5PdaNFqstJBgJtNNQ9HAUcJd7ckY06kSl72X1e2T6jHBRkBFSVjticCVTUxejGwPiDb4NF8JxlBnuym80UGeIffBZP4LKcKJVh2yfWiy4QHV11iJUmyoqmqQjENCez/trafvOWnX8jUilwvNaGmy38sdzNhO4CqiFm2H7FUMle+c4nseBxKKLDaipIfZrHpIW0PE5SaWm7bGgua6XOjeiZ4H1WOpfY37ZWLfS27XqsxSvDGS72Rushjr1mvYYtkL4dLrRvAq3+Vv3v31b//2yae/aper+Wb9uvSaGDfru/H6ZlWs719Dj3zc3IUxvIKwvL4p4fur69vB05rq2n9///q/I+QVf/94s4LxLvT97uD66hYCvbr2IyRV0DS0p1dPnpbw6oWfpwS38veXQJN87JR4fwnKWz15Uq3v/Hw3N6Xx98M6wCPeeeeXw/vv/+mP0BqFtzpAyFK8q3iBRw1C4k7M7Pt80/Rbfga0EFhqhwLtyHJz4Zd78fdOCFX9AIUaxXHA4wHHQe6PDRJExJul5Q/UYuNEwGGCikcvOZ960fmH6opvetE5/P0/AQYARWny6bv+xcUAAAAASUVORK5CYII=");display: block;height: 54px;position: absolute;left: 2px;padding: 11px 0 0 11px;width: 54px;}' +
  330. '.b-profile-clan_text{margin-left: 61px;}' +
  331. '.b-profile-clan_text-wrpr{font-size: 13px;margin: 5px 0 0;overflow: hidden;padding-right: 0;padding: 0 0 7px;text-overflow: ellipsis;white-space: nowrap;}' +
  332. '.b-link-clan{color: #f9d088;font-weight: bold;text-decoration: none;}' +
  333. '.b-link-clan_tag{color: #babcbf;}' +
  334. '.b-statistic{overflow: hidden;margin: 0 0 16px;line-height: 14px;}' +
  335. '.b-statistic_item{color: #606061;font-size: 11px;margin: 0;padding: 0;line-height: 125%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;word-wrap: normal;}' +
  336. '.b-statistic_value{color: #babcbf;}' +
  337. '</style>' +
  338. '<div id="wowsstatinfo-profile-clan">' +
  339. '<div class="b-profile-clan b-profile-clan__points js-tooltip" id="js-profile-clan">' +
  340. '<img src="//'+realm+'.wargaming.net/clans/static/0.1.0.1/images/processing/loader.gif" />' +
  341. '</div>' +
  342. '</div>' +
  343. getUserScriptDeveloperBlock() +
  344. '' +
  345. '';
  346. row.insertBefore(div, row.firstChild);
  347. var account_href = window.location.href.split('/')[6].split('-');
  348. var account_id = account_href[0];
  349. var language = lang; if(language == 'zh-tw'){language = 'zh-cn';}else if(language == 'ja' || language == 'es-mx' || language == 'pt-br'){language = 'en';}
  350. getJson(WOWSAPI+'encyclopedia/ships/?application_id='+application_id+'&fields=name,images,tier,nation,is_premium,images,type', doneEncyclopedia, errorEncyclopedia);
  351. getJson(WGAPI+'clans/membersinfo/?application_id='+application_id+'&language='+language+'&account_id='+account_id, doneClanInfo, errorClanInfo);
  352. getJson(WOWSAPI+'account/info/?application_id='+application_id+'&extra=statistics.pve,statistics.pvp_solo,statistics.pvp_div2,statistics.pvp_div3&account_id='+account_id+'&index=0&type=profile', doneAccountInfo, errorAccountInfo);
  353. jQ('#userscriptwowsstatinfo').click(function(){onViewBlock(this);});
  354. jQ('._item').click(function(){
  355. setTimeout(function(){viewMainPageProfile();}, 1000);
  356. var pvp_solo_div_charts = document.getElementById('pvp_solo_div_charts');
  357. if(pvp_solo_div_charts != null){
  358. jQ(pvp_solo_div_charts).hide();
  359. jQ('._container_type').hide();
  360. jQ('.dynamic-template').show();
  361. jQ('.button-stat').css('background-color', '#303b41');
  362. jQ('._diactive').removeClass('_diactive');
  363. }
  364. });
  365. jQ('.account-tabs').click(function(){
  366. setTimeout(function(){viewMainPageProfile();}, 1000);
  367. });
  368. }
  369. function ForumUserPage(){
  370. var nickname = document.getElementsByClassName('nickname')[0];
  371. var reputation__wrp = document.getElementsByClassName('reputation__wrp')[0];
  372. if(undefined !== reputation__wrp){
  373. var user_id = reputation__wrp.getAttribute('id').split('_')[1];
  374. var ipsList_data = document.getElementsByClassName('ipsList_data')[0];
  375. // var profile = '' +
  376. // '<li class="clear clearfix">' +
  377. // '<span class="row_title">'+localizationText['profile-wows']+':</span>' +
  378. // '<span class="row_data"><a href="http://worldofwarships.'+realm_host+'/community/accounts/'+user_id+'-/" target="_black">'+nickname.innerHTML+'</a></span>' +
  379. // '</li>' +
  380. // '';
  381. ipsList_data.innerHTML += '' +
  382. // profile +
  383. '<li class="clear clearfix">' +
  384. '<span class="row_title">'+localizationText['profile-clan']+':</span>' +
  385. '<span class="row_data member_'+user_id+'"></span>' +
  386. '</li>' +
  387. '';
  388. var language = lang; if(language == 'zh-tw'){language = 'zh-cn';}else if(language == 'ja' || language == 'es-mx' || language == 'pt-br'){language = 'en';}
  389. getJson(WGAPI+'clans/membersinfo/?application_id='+application_id+'&language='+language+'&account_id='+user_id, doneForumClanInfo, errorForumClanInfo);
  390. }
  391. }
  392. function ForumTopicPage(){
  393. var ForumTopicMembers = [];
  394. var basic_info = document.getElementsByClassName('basic_info');
  395. for(var i = 0; i < basic_info.length; i++){
  396. var ipsUserPhotoLink = basic_info[i].getElementsByClassName('ipsUserPhotoLink')[0];
  397. if(undefined === ipsUserPhotoLink){continue;}
  398. if(ipsUserPhotoLink.id == null){continue;}
  399. if(ipsUserPhotoLink.id.indexOf('anonymous_element') > -1){
  400. var linkParse = ipsUserPhotoLink.href.split('/');
  401. var accountParse = linkParse[5].split('-');
  402. var account_id = accountParse[accountParse.length - 1];
  403. if(ForumTopicMembers['member_'+account_id] === undefined){
  404. ForumTopicMembers['member_'+account_id] = account_id;
  405. var language = lang; if(language == 'zh-tw'){language = 'zh-cn';}else if(language == 'ja' || language == 'es-mx' || language == 'pt-br'){language = 'en';}
  406. getJson(WGAPI+'clans/membersinfo/?application_id='+application_id+'&language='+language+'&account_id='+account_id, doneForumClanInfo, errorForumClanInfo);
  407. }
  408. basic_info[i].innerHTML += '' +
  409. '<li class="member_'+account_id+' desc lighter" style="min-height: 50px;">' +
  410. '<img style="width: 32px; height: 32px;" src="//'+realm+'.wargaming.net/clans/static/0.1.0.1/images/processing/loader.gif" />' +
  411. localizationText['search-clan-forum'] +
  412. '</li>' +
  413. '';
  414. }
  415. }
  416. }
  417. /* ===== ForumTopicPage function ===== */
  418. function doneForumClanInfo(url, response){
  419. if(response.status && response.status == "error"){
  420. errorForumClanInfo();
  421. return;
  422. }
  423.  
  424. var vars = getUrlVars(url);
  425. var account_id = vars['account_id'];
  426. var clansInfo = response['data'][account_id];
  427. if(clansInfo != null){
  428. var icon = clansInfo['clan']['emblems']['x32']['portal'];
  429. if(icon === undefined){
  430. for(var key in clansInfo['clan']['emblems']['x32']){
  431. if(key != 'wot'){
  432. icon = clansInfo['clan']['emblems']['x32'][key];
  433. }
  434. }
  435. }
  436. var br_line = '';
  437. if(window.location.href.indexOf("/topic/") > -1){
  438. br_line = '<br />';
  439. }
  440. var html = '' +
  441. br_line +
  442. '<span>' +
  443. '<a align="center" href="https://'+realm+'.wargaming.net/clans/'+clansInfo['clan']['clan_id']+'/" title="'+clansInfo['clan']['tag']+'" rel="home" target="_blank">' +
  444. '<img src="'+icon+'" alt="'+clansInfo['clan']['tag']+'">' +
  445. '</a>' +
  446. '<a align="center" href="https://'+realm+'.wargaming.net/clans/'+clansInfo['clan']['clan_id']+'/" title="'+clansInfo['clan']['tag']+'" rel="home" target="_blank">['+clansInfo['clan']['tag']+']</a>' +
  447. '</span>' +
  448. '';
  449. jQ('.member_'+account_id).html(html);
  450. }else{
  451. jQ('.member_'+account_id).html('');
  452. }
  453. }
  454. function errorForumClanInfo(url){
  455. jQ('.member_'+account_id).html('');
  456. }
  457. /* ===== MemberProfilePage function ===== */
  458. function doneClanInfo(url, response){
  459. if(response.status && response.status == "error"){
  460. errorClanInfo();
  461. return;
  462. }
  463. var vars = getUrlVars(url);
  464. var account_id = vars['account_id'];
  465. if(response['data'][account_id] == null){errorClanInfo(); return;}
  466. MembersArray[0]['clan'] = response['data'][account_id]['clan'];
  467. MembersArray[0]['clan']['account_id'] = response['data'][account_id]['account_id'];
  468. MembersArray[0]['clan']['role_i18n'] = response['data'][account_id]['role_i18n'];
  469. MembersArray[0]['clan']['joined_at'] = response['data'][account_id]['joined_at'];
  470. MembersArray[0]['clan']['role'] = response['data'][account_id]['role'];
  471. MembersArray[0]['clan']['account_name'] = response['data'][account_id]['account_name'];
  472. viewMemberClan();
  473. }
  474. function errorClanInfo(url){
  475. MembersArray[0]['clan'] = null;
  476. viewMemberClan();
  477. }
  478. function viewMemberClan(){
  479. var wowsstatinfo_profile_clan = document.getElementById('wowsstatinfo-profile-clan');
  480. if(MembersArray[0]['clan'] != null){
  481. var day = dateDiffInDays(MembersArray[0]['clan']['joined_at'] * 1000, new Date().getTime());
  482. var icon = MembersArray[0]['clan']['emblems']['x32']['portal'];
  483. if(icon === undefined){
  484. for(var key in MembersArray[0]['clan']['emblems']['x32']){
  485. if(key != 'wot'){
  486. icon = MembersArray[0]['clan']['emblems']['x32'][key];
  487. }
  488. }
  489. }
  490. icon = icon.replace('http://', 'https://');
  491. wowsstatinfo_profile_clan.innerHTML = '' +
  492. '<div class="b-profile-clan b-profile-clan__points js-tooltip" id="js-profile-clan">' +
  493. '<div class="b-profile-clan_photo">' +
  494. '<div style="background: '+MembersArray[0]['clan']['color']+';" class="b-profile-clan_color"><!-- --></div>' +
  495. '<a class="b-profile-clan_link" href="https://'+realm+'.wargaming.net/clans/'+MembersArray[0]['clan']['clan_id']+'/" target="_blank">' +
  496. '<img alt="'+MembersArray[0]['clan']['name']+'" src="'+icon+'" width="32" height="32">' +
  497. '</a>' +
  498. '</div>' +
  499. '<div class="b-profile-clan_text">' +
  500. '<div class="b-profile-clan_text-wrpr">' +
  501. '<a class="b-link-clan" href="https://'+realm+'.wargaming.net/clans/'+MembersArray[0]['clan']['clan_id']+'/" target="_blank">' +
  502. '<span class="b-link-clan_tag" style="color: '+MembersArray[0]['clan']['color']+';">['+MembersArray[0]['clan']['tag']+']</span>&nbsp;'+MembersArray[0]['clan']['name']+'' +
  503. '</a>' +
  504. '</div>' +
  505. '<div class="b-statistic">' +
  506. '<p class="b-statistic_item">'+localizationText['role']+': <span class="b-statistic_value">'+MembersArray[0]['clan']['role_i18n']+'</span></p>' +
  507. '<p class="b-statistic_item">'+localizationText['clan-day']+': <span class="b-statistic_value">'+day+'</span></p>' +
  508. '</div>' +
  509. '</div>' +
  510. '</div>' +
  511. '';
  512. }else{
  513. wowsstatinfo_profile_clan.innerHTML = '';
  514. }
  515. }
  516. function viewMainPageProfile(){
  517. console.log('...function viewMainPageProfile...');
  518. if(Encyclopedia == null){console.log('Encyclopedia == null'); setTimeout(function(){viewMainPageProfile();}, 1000);return;}
  519. if(MembersArray[0]['info']['hidden_profile']){
  520. console.log(MembersArray[0]['info']['account_id']+' hidden profile!!!');
  521. return;
  522. }
  523. if(!calcStat(0)){
  524. console.log('Error calcStat '+MembersArray[0]['info']['account_id']);
  525. return;
  526. }
  527. var container = null;
  528. var account_tabs__game_mode_tabs_menu = document.getElementsByClassName('account-tabs__game-mode-tabs-menu')[0];
  529. if(account_tabs__game_mode_tabs_menu != null){
  530. var dropdown_select__html = account_tabs__game_mode_tabs_menu.getElementsByClassName('dropdown-select__html')[0];
  531. if(dropdown_select__html != null){
  532. var wows_pvp = dropdown_select__html.getElementsByClassName('wows-pvp')[0];
  533. if(wows_pvp != null){
  534. container = document.getElementsByClassName('account-tabs-containers')[0];
  535. }
  536. }
  537. }
  538. if(container != null){
  539. var account_tab_background = container.getElementsByClassName('account-tab-background');
  540. for(var atb = 0; atb < account_tab_background.length; atb++){
  541. account_tab_background[atb].style.zIndex = '-1';
  542. }
  543. var cm_user_menu_link_cutted_text = document.getElementsByClassName('cm-user-menu-link_cutted-text')[0];
  544. var login_name = null; if(cm_user_menu_link_cutted_text != null){login_name = cm_user_menu_link_cutted_text.textContent;}
  545. var userbar = '';
  546. if(login_name == MembersArray[0]['info']['nickname']){
  547. userbar += '<button class="btn btn-lg btn-turqoise" id="generator-userbar" style="margin: 5px; padding: 10px;">'+localizationText['generator-userbar']+'</button>';
  548. }
  549. userbar += '' +
  550. '<br />'+
  551. '<img id="userbar-img" src="'+WoWsStatInfoHref+'bg/userbar.png" />'+
  552. '<br />'+
  553. '<textarea id="userbar-link" style="margin-top: 5px; font-size: 14px; height: 100px; width: 468px; color: black;">'+
  554. '[url='+WoWsStatInfoHref+'][img]'+WoWsStatInfoHref+'bg/userbar.png[/img][/url]'+
  555. '</textarea>'
  556. '';
  557. var main_page_script_block = document.getElementById('main-page-script-block');
  558. var account_tab_overview = container.getElementsByClassName('account-tab-overview')[0];
  559. var account_main_stats_mobile = container.getElementsByClassName('account-main-stats-mobile')[0];
  560. if(main_page_script_block == null && account_main_stats_mobile != null && account_tab_overview != null){
  561. account_main_stats_mobile.outerHTML += '' +
  562. '<hr />' +
  563. '<table id="main-page-script-block" style="width: 100%;">' +
  564. '<tr>' +
  565. '<td style="vertical-align: top;">' +
  566. '<table class="account-table">' +
  567. '<thead>' +
  568. '<tr>' +
  569. '<th colspan="2">' +
  570. '<h3 class="_title">'+localizationText['stat-table-4']+'</h3>' +
  571. '</th>' +
  572. '</tr>' +
  573. '</thead>' +
  574. '<tbody>' +
  575. '<tr>' +
  576. '<td class="_name">' +
  577. '<span>'+localizationText['battles_days']+'</span>' +
  578. '</td>' +
  579. '<td class="_value">' +
  580. '<span>'+valueFormat((MembersArray[0]['info']['statistics']['pvp']['battles_days']).toFixed(0))+'</span>'+
  581. '</td>' +
  582. '</tr>' +
  583. '<tr>' +
  584. '<td class="_name">' +
  585. '<span>'+localizationText['number-ships-x']+'</span>' +
  586. '</td>' +
  587. '<td class="_value">' +
  588. '<span>'+MembersArray[0]['info']['ships_x_level']+'</span>'+
  589. '</td>' +
  590. '</tr>' +
  591. '<tr>' +
  592. '<td class="_name">' +
  593. '<span>'+localizationText['max_ship_level']+'</span>' +
  594. '</td>' +
  595. '<td class="_value">' +
  596. '<span>'+
  597. MembersArray[0]['info']['statistics']['pvp']['max_ship_level']+
  598. '</span>' +
  599. '</td>' +
  600. '</tr>' +
  601. '<tr>' +
  602. '<td class="_name">' +
  603. '<span>'+localizationText['avg_battles_level']+'</span>' +
  604. '</td>' +
  605. '<td class="_value">' +
  606. '<span>'+valueFormat((MembersArray[0]['info']['statistics']['pvp']['avg_battles_level']).toFixed(1))+'</span>'+
  607. '</td>' +
  608. '</tr>' +
  609. '<tr id="info-stat-pvp-wr">' +
  610. '<td class="_name">' +
  611. '<span>'+
  612. '<a target="_blank" href="http://vzhabin.ru/US_WoWsStatInfo/?realm_search='+realm+'&nickname='+MembersArray[0]['info']['nickname']+'">'+
  613. localizationText['wr']+
  614. '</a>' +
  615. '</span>' +
  616. '</td>' +
  617. '<td class="_value">' +
  618. '<span style="color: '+findColorASC(MembersArray[0]['info']['statistics']['pvp']['wr'], 'wr', 'main')+';">'+
  619. valueFormat((MembersArray[0]['info']['statistics']['pvp']['wr']).toFixed(2)) +
  620. '</span>'+
  621. '</td>' +
  622. '</tr>' +
  623. '</tbody>' +
  624. '</table>' +
  625. '</td>'+
  626. '<td>'+
  627. '</td>'+
  628. '<td style="text-align: right; vertical-align: top;">'+
  629. userbar +
  630. '</td>' +
  631. '</tr>' +
  632. '</table>'
  633. '';
  634. addStatHover(document.getElementById('info-stat-pvp-wr'), 'wr');
  635. var img = new Image();
  636. img.onload = function(){
  637. var userbar_img = document.getElementById('userbar-img');
  638. if(userbar_img != null){
  639. userbar_img.src = WoWsStatInfoHref+'userbar/'+MembersArray[0]['info']['nickname']+'.png'+'?'+Math.floor(Math.random()*100000001);
  640. var userbar_link = document.getElementById('userbar-link');
  641. userbar_link.textContent = '[url='+WoWsStatInfoHref+'?realm_search='+realm+'&nickname='+MembersArray[0]['info']['nickname']+'][img]'+WoWsStatInfoHref+'userbar/'+MembersArray[0]['info']['nickname']+'.png[/img][/url]';
  642. }
  643. }
  644. img.src = WoWsStatInfoHref+'userbar/'+MembersArray[0]['info']['nickname']+'.png'+'?'+Math.floor(Math.random()*100000001);
  645. jQ('#generator-userbar').click(function(){
  646. getJson(WoWsStatInfoHref+'bg/bg.php?'+Math.floor(Math.random()*100000001), doneUserBarBG, errorUserBarBG);
  647. });
  648. var _values = account_tab_overview.getElementsByClassName('_values')[0];
  649. var main_stat = _values.getElementsByTagName('div');
  650. main_stat[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['battles'], 'battles', 'main');
  651. addStatHover(main_stat[0], 'battles');
  652. main_stat[1].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['wins_percents'], 'wins_percents', 'main');
  653. addStatHover(main_stat[1], 'wins_percents');
  654. main_stat[2].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_xp'], 'avg_xp', 'main');
  655. addStatHover(main_stat[2], 'avg_xp');
  656. main_stat[3].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_damage_dealt'], 'avg_damage_dealt', 'main');
  657. addStatHover(main_stat[3], 'avg_damage_dealt');
  658. main_stat[4].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['kill_dead'], 'kill_dead', 'main');
  659. addStatHover(main_stat[4], 'kill_dead');
  660. var account_battle_stats = account_tab_overview.getElementsByClassName('account-battle-stats')[0];
  661. if(account_battle_stats != null){
  662. var account_table = account_battle_stats.getElementsByClassName('account-table');
  663. //Общие результаты
  664. account_table[0].rows[1].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['battles'], 'battles', 'main');
  665. addStatHover(account_table[0].rows[1], 'battles');
  666. //Средние показатели за бой
  667. account_table[1].rows[1].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_xp'], 'avg_xp', 'main');
  668. addStatHover(account_table[1].rows[1], 'avg_xp');
  669. account_table[1].rows[2].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_damage_dealt'], 'avg_damage_dealt', 'main');
  670. addStatHover(account_table[1].rows[2], 'avg_damage_dealt');
  671. account_table[1].rows[3].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_frags'], 'avg_frags', 'main');
  672. addStatHover(account_table[1].rows[3], 'avg_frags');
  673. account_table[1].rows[4].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_planes_killed'], 'avg_planes_killed', 'main');
  674. addStatHover(account_table[1].rows[4], 'avg_planes_killed');
  675. //account_table[1].rows[5].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_capture_points'], 'avg_capture_points', 'main');
  676. //account_table[1].rows[6].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['avg_dropped_capture_points'], 'avg_dropped_capture_points', 'main');
  677. // Рекордные показатели
  678. account_table[2].rows[1].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['max_xp'], 'max_xp', 'main');
  679. addStatHover(account_table[2].rows[1], 'max_xp');
  680. account_table[2].rows[2].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['max_damage_dealt'], 'max_damage_dealt', 'main');
  681. addStatHover(account_table[2].rows[2], 'max_damage_dealt');
  682. account_table[2].rows[3].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['max_frags_battle'], 'max_frags_battle', 'main');
  683. addStatHover(account_table[2].rows[3], 'max_frags_battle');
  684. account_table[2].rows[4].cells[1].getElementsByTagName('span')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['max_planes_killed'], 'max_planes_killed', 'main');
  685. addStatHover(account_table[2].rows[4], 'max_planes_killed');
  686. //Дополнительно
  687. account_table[0].rows[2].cells[1].getElementsByTagName('small')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['wins_percents'], 'wins_percents', 'main');
  688. addStatHover(account_table[0].rows[2], 'wins_percents');
  689. if(account_table[0].rows[3].cells[1].getElementsByClassName('small-survived_battles_percents')[0] == undefined){
  690. account_table[0].rows[3].cells[1].innerHTML += '<small class="small-survived_battles_percents">('+valueFormat((MembersArray[0]['info']['statistics']['pvp']['survived_battles_percents']).toFixed(2))+'%)</small>';
  691. account_table[0].rows[3].cells[1].getElementsByTagName('small')[0].style.color = findColorASC(MembersArray[0]['info']['statistics']['pvp']['survived_battles_percents'], 'survived_battles_percents', 'main');
  692. addStatHover(account_table[0].rows[3], 'survived_battles_percents');
  693. }
  694. if(account_table[2].rows[1].cells[0].getElementsByClassName('small-max_xp_ship')[0] == undefined
  695. && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_xp_ship_id']] != null && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_xp_ship_id']] !== undefined){
  696. account_table[2].rows[1].cells[0].innerHTML += '<small class="small-max_xp_ship">('+Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_xp_ship_id']]['name']+')</small>';
  697. }
  698. if(account_table[2].rows[2].cells[0].getElementsByClassName('small-max_damage_dealt_ship')[0] == undefined
  699. && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_damage_dealt_ship_id']] != null && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_damage_dealt_ship_id']] !== undefined){
  700. account_table[2].rows[2].cells[0].innerHTML += '<small class="small-max_damage_dealt_ship">('+Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_damage_dealt_ship_id']]['name']+')</small>';
  701. }
  702. if(account_table[2].rows[3].cells[0].getElementsByClassName('small-max_frags_ship')[0] == undefined
  703. && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_frags_ship_id']] != null && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_frags_ship_id']] !== undefined){
  704. account_table[2].rows[3].cells[0].innerHTML += '<small class="small-max_frags_ship">('+Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_frags_ship_id']]['name']+')</small>';
  705. }
  706. if(account_table[2].rows[4].cells[0].getElementsByClassName('small-max_planes_killed_ship')[0] == undefined
  707. && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_planes_killed_ship_id']] != null && Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_planes_killed_ship_id']] !== undefined){
  708. account_table[2].rows[4].cells[0].innerHTML += '<small class="small-max_planes_killed_ship">('+Encyclopedia[MembersArray[0]['info']['statistics']['pvp']['max_planes_killed_ship_id']]['name']+')</small>';
  709. }
  710. }
  711. }
  712. if(account_tab_overview != null){
  713. var account_main_stats = account_tab_overview.getElementsByClassName('account-main-stats')[0];
  714. var account_battle_stats = account_tab_overview.getElementsByClassName('account-battle-stats')[0];
  715. if(account_battle_stats != null && account_main_stats != null){
  716. var account_delta_stat = account_battle_stats.getElementsByClassName('account-delta-stat')[0];
  717. var Keys = Object.keys(MembersArray[0]['statsbydate']['pvp']);
  718. if(account_delta_stat == null && Keys.length > 1){
  719. account_battle_stats.innerHTML += '<div class="account-delta-stat"></div>';
  720. var IndexLast = Keys.length - 1;
  721. var IndexOld = Keys.length - 2;
  722. var battles = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['battles'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['battles'];
  723. var wins_percents = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['wins_percents'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['wins_percents'];
  724. var avg_xp = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_xp'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_xp'];
  725. var avg_damage_dealt = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_damage_dealt'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_damage_dealt'];
  726. var kill_dead = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['kill_dead'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['kill_dead'];
  727. var avg_frags = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_frags'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_frags'];
  728. var avg_planes_killed = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_planes_killed'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_planes_killed'];
  729. var avg_capture_points = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_capture_points'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_capture_points'];
  730. var avg_dropped_capture_points = MembersArray[0]['statsbydate']['pvp'][Keys[IndexLast]]['avg_dropped_capture_points'] - MembersArray[0]['statsbydate']['pvp'][Keys[IndexOld]]['avg_dropped_capture_points'];
  731. if(login_name == MembersArray[0]['info']['nickname']){
  732. var _values = account_main_stats.getElementsByClassName('_values')[0];
  733. var main_stat = _values.getElementsByTagName('div');
  734. main_stat[0].innerHTML += getHTMLDif(battles, 0);
  735. main_stat[1].innerHTML += getHTMLDif(wins_percents, 2);
  736. main_stat[2].innerHTML += getHTMLDif(avg_xp, 2);
  737. main_stat[3].innerHTML += getHTMLDif(avg_damage_dealt, 0);
  738. main_stat[4].innerHTML += getHTMLDif(kill_dead, 2);
  739. }
  740. if(account_battle_stats != null){
  741. var account_table = account_battle_stats.getElementsByClassName('account-table');
  742. if(login_name == MembersArray[0]['info']['nickname']){
  743. account_table[1].rows[1].cells[1].innerHTML += getHTMLDif(avg_xp, 2);
  744. account_table[1].rows[2].cells[1].innerHTML += getHTMLDif(avg_damage_dealt, 2);
  745. account_table[1].rows[3].cells[1].innerHTML += getHTMLDif(avg_frags, 2);
  746. account_table[1].rows[4].cells[1].innerHTML += getHTMLDif(avg_planes_killed, 2);
  747. //account_table[1].rows[5].cells[1].innerHTML += getHTMLDif(avg_capture_points, 2);
  748. //account_table[1].rows[6].cells[1].innerHTML += getHTMLDif(avg_dropped_capture_points, 2);
  749. }
  750. addStatHover(account_table[0].rows[1], 'battles');
  751. addStatHover(account_table[0].rows[2], 'wins_percents');
  752. addStatHover(account_table[0].rows[3], 'survived_battles_percents');
  753. addStatHover(account_table[1].rows[1], 'avg_xp');
  754. addStatHover(account_table[1].rows[2], 'avg_damage_dealt');
  755. addStatHover(account_table[1].rows[3], 'avg_frags');
  756. addStatHover(account_table[1].rows[4], 'avg_planes_killed');
  757. addStatHover(account_table[2].rows[1], 'max_xp');
  758. addStatHover(account_table[2].rows[2], 'max_damage_dealt');
  759. addStatHover(account_table[2].rows[3], 'max_frags_battle');
  760. addStatHover(account_table[2].rows[4], 'max_planes_killed');
  761. }
  762. }
  763. }
  764. }
  765. var achieves_block = container.getElementsByClassName('achieves-block')[0];
  766. if(achieves_block != null){
  767. var achieve_item = container.getElementsByClassName('achieve-item');
  768. for(var i = 0; i < achieve_item.length; i++){
  769. var item = achieve_item[i];
  770. var js_tooltip_show = item.getAttribute('js-tooltip-show');
  771. var _counter = item.getElementsByClassName('_counter')[0];
  772. if(_counter != null && item.getElementsByClassName('_counter').length == 1){
  773. _counter.setAttribute('style', 'left: 70%; background-color: #F7882E; min-width: 3em;');
  774. var battlesAchievement = 0;
  775. if(MembersArray[0]['achievements']['battle'][js_tooltip_show.toUpperCase()+'_battle'] === undefined){
  776. battlesAchievement = 'Error';
  777. }else{
  778. battlesAchievement = MembersArray[0]['achievements']['battle'][js_tooltip_show.toUpperCase()+'_battle'];
  779. }
  780. item.innerHTML += '<div class="_counter" style="left: 20%; background-color: #AAAAAA; min-width: 3em;">'+battlesAchievement+'</div>';
  781. }
  782. }
  783. var achieves_block = container.getElementsByClassName('achieves-block')[0];
  784. var achieve_counter = container.getElementsByClassName('achieve-counter')[0];
  785. if(achieve_counter == null && achieves_block != null){
  786. achieves_block.outerHTML += '' +
  787. '<div class="achieve-counter" style="margin-left: 10px;">' +
  788. '<div style="width: initial; height: initial; float: initial; font-size: 14px; color: #FFF;" class="achieve-item _big tooltip-target tooltip-enabled tooltip-element-attached-top tooltip-element-attached-left tooltip-target-attached-bottom tooltip-target-attached-left">' +
  789. '<div class="_counter" style="position: relative; background-color: #F7882E; min-width: 3em; left: 0; float: left;">12</div>' +
  790. '<div> - '+localizationText['achieve_counter_1']+'</div>' +
  791. '<div class="_counter" style="position: relative; background-color: #AAAAAA; min-width: 3em; left: 0; float: left;">31</div>' +
  792. '<div> - '+localizationText['achieve_counter_2']+'</div>' +
  793. '</div>' +
  794. '</div>' +
  795. '';
  796. }
  797. }
  798. var account_tabs_wrapper = document.getElementsByClassName('account-tabs-wrapper')[0];
  799. if(account_tabs_wrapper != null){
  800. var pvp_solo_div_charts = document.getElementById('pvp_solo_div_charts');
  801. if(pvp_solo_div_charts == null){
  802. var div = document.createElement('div');
  803. div.setAttribute('id', 'pvp_solo_div_charts');
  804. div.setAttribute('style', 'text-align: right;');
  805. div.innerHTML += '' +
  806. '<div style="text-align: right;">' +
  807. '<button class="btn btn-lg btn-turqoise button-stat" id="pvp_solo" style="margin: 5px; padding: 10px; background-color: #303b41;">' +
  808. localizationText['pvp_solo'] +
  809. '</button>' +
  810. '<button class="btn btn-lg btn-turqoise button-stat" id="pvp_div" style="margin: 5px; padding: 10px; background-color: #303b41;">' +
  811. localizationText['pvp_div'] +
  812. '</button>' +
  813. '<button class="btn btn-lg btn-turqoise button-stat" id="charts" style="margin: 5px; padding: 10px; background-color: #303b41;">' +
  814. localizationText['charts'] +
  815. '</button>' +
  816. '</div>' +
  817. '';
  818. account_tabs_wrapper.insertBefore(div, account_tabs_wrapper.firstChild);
  819. jQ('.button-stat').click(function(){
  820. jQ('._container_type').hide();
  821. jQ('.button-stat').css('background-color', '#303b41');
  822. var tab_content = document.getElementsByClassName('tab-content')[0];
  823. var li = tab_content.getElementsByTagName('li');
  824. for(var i = 0; i < li.length; i++){
  825. if(li[i].getAttribute('class') == 'account-tab _active'){
  826. jQ(li[i]).removeClass('_active');
  827. jQ(li[i]).addClass('_diactive');
  828. jQ('.dynamic-template').hide();
  829. }
  830. }
  831. jQ('._container_'+jQ(this).attr('id')).show();
  832. jQ(this).css('background-color', '#099');
  833. });
  834. jQ('.account-tab').click(function(){
  835. if(jQ(this).attr('class') == 'account-tab _diactive'){
  836. jQ(this).addClass('_active');
  837. }
  838. jQ('.dynamic-template').show();
  839. jQ('._container_type').hide();
  840. jQ('.button-stat').css('background-color', '#303b41');
  841. jQ('._diactive').removeClass('_diactive');
  842. });
  843. }else{
  844. jQ(pvp_solo_div_charts).show();
  845. }
  846. }
  847. var typeStatAdd = ["pvp_div", "pvp_solo"];
  848. var _container = document.getElementsByClassName('_container')[0];
  849. if(_container != null){
  850. var _container_solo_div_charts = document.getElementsByClassName('_container_solo_div_charts')[0];
  851. if(_container_solo_div_charts == null){
  852. var div = document.createElement('div');
  853. div.setAttribute('class', '_container_solo_div_charts');
  854. _container.insertBefore(div, _container.firstChild);
  855. _container_solo_div_charts = document.getElementsByClassName('_container_solo_div_charts')[0];
  856. }
  857. for(var i = 0; i < typeStatAdd.length; i++){
  858. var type = typeStatAdd[i];
  859. var _container_type = _container_solo_div_charts.getElementsByClassName('_container_'+type)[0];
  860. if(_container_type == null){
  861. _container_solo_div_charts.innerHTML += '' +
  862. '<div class="_container_type _container_'+type+' tab-container" style="display: none;">' +
  863. '<div class="account-main-stats">' +
  864. '<div class="_bg-for-average-exp"></div>' +
  865. '<div class="account-main-stats-table">' +
  866. '<div class="_icons">' +
  867. '<div class="_battles">' +
  868. '<div></div>' +
  869. '</div>' +
  870. '<div class="_victories">' +
  871. '<div></div>' +
  872. '</div>' +
  873. '<div class="_average-exp">' +
  874. '<div></div>' +
  875. '</div>' +
  876. '<div class="_kd">' +
  877. '<div></div>' +
  878. '</div>' +
  879. '<div class="_other">' +
  880. '<div></div>' +
  881. '</div>' +
  882. '</div>' +
  883. '<div class="_names">' +
  884. '<div>'+localizationText['title_battles']+'</div>' +
  885. '<div>'+localizationText['title_wins_percents']+'</div>' +
  886. '<div class="_average-exp">'+localizationText['title_avg_xp']+'</div>' +
  887. '<div>'+localizationText['title_avg_damage_dealt']+'</div>' +
  888. '<div>'+localizationText['title_kill_dead']+'</div>' +
  889. '</div>' +
  890. '<div class="_values">' +
  891. '<div style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['battles'], 'battles', 'main')+';">'+
  892. valueFormat((MembersArray[0]['info']['statistics'][type]['battles']).toFixed(0))+
  893. '</div>' +
  894. '<div style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['wins_percents'], 'wins_percents', 'main')+';">'+
  895. valueFormat((MembersArray[0]['info']['statistics'][type]['wins_percents']).toFixed(2))+
  896. '%</div>' +
  897. '<div style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['avg_xp'], 'avg_xp', 'main')+';">'+
  898. valueFormat((MembersArray[0]['info']['statistics'][type]['avg_xp']).toFixed(0))+
  899. '</div>' +
  900. '<div style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['avg_damage_dealt'], 'avg_damage_dealt', 'main')+';">'+
  901. valueFormat((MembersArray[0]['info']['statistics'][type]['avg_damage_dealt']).toFixed(0))+
  902. '</div>' +
  903. '<div style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['kill_dead'], 'kill_dead', 'main')+';">'+
  904. valueFormat((MembersArray[0]['info']['statistics'][type]['kill_dead']).toFixed(2))+
  905. '</div>' +
  906. '</div>' +
  907. '</div>' +
  908. '</div>' +
  909. '<hr />' +
  910. '<div class="account-battle-stats">' +
  911. getHTMLStat(MembersArray[0]['info']['statistics'][type], 'main')+
  912. '<div class="row">' +
  913. '<div class="col-xs-12 col-sm-4">' +
  914. '<table class="account-table _left">' +
  915. '<thead>' +
  916. '<tr>' +
  917. '<th colspan="2">' +
  918. '<h3 class="account-title">'+localizationText['stat-table-4']+'</h3>' +
  919. '</th>' +
  920. '</tr>' +
  921. '</thead>' +
  922. '<tbody>' +
  923. '<tr>' +
  924. '<td class="_name">' +
  925. '<span>'+localizationText['battles_days']+'</span>' +
  926. '</td>' +
  927. '<td class="_value">' +
  928. '<span>'+
  929. (MembersArray[0]['info']['statistics'][type]['battles_days']).toFixed(0)+
  930. '</span>' +
  931. '</td>' +
  932. '</tr>' +
  933. '<tr>' +
  934. '<td class="_name">' +
  935. '<span>'+localizationText['max_ship_level']+'</span>' +
  936. '</td>' +
  937. '<td class="_value">' +
  938. '<span>'+
  939. MembersArray[0]['info']['statistics'][type]['max_ship_level']+
  940. '</span>' +
  941. '</td>' +
  942. '</tr>' +
  943. '<tr>' +
  944. '<td class="_name">' +
  945. '<span>'+localizationText['avg_battles_level']+'</span>' +
  946. '</td>' +
  947. '<td class="_value">' +
  948. '<span>'+
  949. valueFormat((MembersArray[0]['info']['statistics'][type]['avg_battles_level']).toFixed(1))+
  950. '</span>' +
  951. '</td>' +
  952. '</tr>' +
  953. '<tr>' +
  954. '<td class="_name">' +
  955. '<span>' +
  956. '<a target="_blank" href="http://vzhabin.ru/US_WoWsStatInfo/?realm_search='+realm+'&nickname='+MembersArray[0]['info']['nickname']+'">'+
  957. localizationText['wr'] +
  958. '</a>' +
  959. '</span>' +
  960. '</td>' +
  961. '<td class="_value">' +
  962. '<span style="color: '+findColorASC(MembersArray[0]['info']['statistics'][type]['wr'], 'wr', 'main')+';">'+
  963. valueFormat((MembersArray[0]['info']['statistics'][type]['wr']).toFixed(2)) +
  964. '</span>'+
  965. '</td>' +
  966. '</tr>' +
  967. '</tbody>' +
  968. '</table>' +
  969. '</div>' +
  970. '</div>' +
  971. '</div>' +
  972. '<hr />' +
  973. '<div class="account-tab-ships tab-container _active" js-tab-cont-id="account-tab-ships-'+type+'">' +
  974. '<h3 class="account-title">'+localizationText['ships_stat']+'</h3>' +
  975. '<table class="table-wows">'+
  976. '<thead>'+
  977. '<tr>'+
  978. '<th class="_icon">'+
  979. '<div class="_icon-type-of-ship"></div>'+
  980. '</th>'+
  981. '<th class="_name">'+
  982. localizationText['title_ships']+
  983. '</th>'+
  984. '<th class="_value">'+
  985. '<div class="_icon-battles"></div>'+
  986. '<span>'+localizationText['battles']+'</span>'+
  987. '</th>'+
  988. '<th class="_value">'+
  989. '<div class="_icon-winrate"></div>'+
  990. '<span>'+localizationText['wins']+'</span>'+
  991. '</th>'+
  992. '<th class="_value">'+
  993. '<div class="_icon-exp"></div>'+
  994. '<span>'+localizationText['title_avg_xp']+'</span>'+
  995. '</th>'+
  996. '<th class="_value">'+
  997. '<span>'+localizationText['wr']+'</span>'+
  998. '</th>'+
  999. '</tr>'+
  1000. '</thead>'+
  1001. getHTMLShipStat(MembersArray[0], type)+
  1002. '</table>'+
  1003. '</div>' +
  1004. '</div>' +
  1005. '';
  1006. }
  1007. }
  1008. var _container_charts = _container_solo_div_charts.getElementsByClassName('_container_charts')[0];
  1009. if(_container_charts == null){
  1010. var date = [];
  1011. var value = [];
  1012. var html_chart = '';
  1013. var chart_value = ['wins_percents', 'avg_xp', 'avg_damage_dealt', 'kill_dead', 'avg_frags', 'avg_planes_killed'];
  1014. for(var key in chart_value){
  1015. var title = chart_value[key];
  1016. html_chart += '' +
  1017. '<div class="chart_div">' +
  1018. '<h3 class="_title">'+localizationText['title_'+title]+'</h3>' +
  1019. '<div class="userscript-placeholder"><div id="chart_'+title+'" class="chart-placeholder"></div></div>' +
  1020. '</div>' +
  1021. '';
  1022. value[title] = [];
  1023. }
  1024. _container_solo_div_charts.innerHTML += '' +
  1025. '<div class="_container_type _container_charts tab-container" js-tab-cont-id="account-tab-charts-pvp" style="display: none;">' +
  1026. '<div class="account-main-stats">' +
  1027. html_chart +
  1028. '</div>' +
  1029. '</div>' +
  1030. '';
  1031. var index = 0;
  1032. for(var key_stat in MembersArray[0]['statsbydate']['pvp']){
  1033. var d = key_stat.substring(6, 8);
  1034. var m = key_stat.substring(4, 6);
  1035. var y = key_stat.substring(2, 4);
  1036. date.push([index, d+'.'+m]);
  1037. for(var key in chart_value){
  1038. var title = chart_value[key];
  1039. value[title].push([index, parseFloat(MembersArray[0]['statsbydate']['pvp'][key_stat][title].toFixed(2))]);
  1040. }
  1041. index++;
  1042. }
  1043. for(var key in chart_value){
  1044. var title = chart_value[key];
  1045. viewChart(title, date, value[title]);
  1046. }
  1047. jQ(container).find('nav.account-tabs ul').append(''+
  1048. '<li class="account-tab" js-tab="" js-tab-show="account-tab-charts-pvp">'+
  1049. '<div class="_title">'+localizationText['charts']+'</div>'+
  1050. '<div class="_active-feature">'+
  1051. '<div class="_line"></div>'+
  1052. '<div class="_shadow"></div>'+
  1053. '</div>'+
  1054. '</li>'+
  1055. '');
  1056. jQ(container).find('div.account-tabs-mobile ul').append(''+
  1057. '<li class="_item" js-dropdown-item="" js-tab="" js-tab-show="account-tab-charts-pvp">'+localizationText['charts']+'</li>' +
  1058. '');
  1059. }
  1060. var _click_solo_div_ships = document.getElementsByClassName('_click_solo_div_ships')[0];
  1061. if(_click_solo_div_ships == null){
  1062. var div = document.createElement('div');
  1063. div.setAttribute('class', '_click_solo_div_ships');
  1064. _container.insertBefore(div, _container.firstChild);
  1065. for(var i = 0; i < typeStatAdd.length; i++){
  1066. var type = typeStatAdd[i];
  1067. jQ('.ships-class-'+type).click(function(){
  1068. if(jQ(this).attr('open-active') == 'true'){
  1069. jQ(this).removeClass('_active-btn');
  1070. jQ('.'+jQ(this).attr('open-block')).removeClass('_active');
  1071. jQ(this).attr('open-active', 'false');
  1072. }else{
  1073. jQ(this).addClass('_active-btn');
  1074. jQ('.'+jQ(this).attr('open-block')).addClass('_active');
  1075. jQ(this).attr('open-active', 'true');
  1076. }
  1077. });
  1078. jQ('.ship-stat-'+type).click(function(){
  1079. if(jQ(this).attr('open-active') == 'true'){
  1080. jQ(this).removeClass('_active-btn');
  1081. jQ('.'+jQ(this).attr('open-block')).removeClass('_active');
  1082. jQ(this).attr('open-active', 'false');
  1083. }else{
  1084. jQ(this).addClass('_active-btn');
  1085. jQ('.'+jQ(this).attr('open-block')).addClass('_active');
  1086. jQ(this).attr('open-active', 'true');
  1087. }
  1088. });
  1089. }
  1090. }
  1091. }
  1092. var ships_detail_stats = container.getElementsByClassName('ships-detail-stats')[0];
  1093. if(ships_detail_stats != null){
  1094. for(var i = 0; i < ships_detail_stats.rows.length; i++){
  1095. var row = ships_detail_stats.rows[i];
  1096. if(i == 0 && row.cells.length < 6){
  1097. var th = document.createElement('th');
  1098. th.setAttribute('class', '_value');
  1099. th.innerHTML = '<span>'+localizationText['wr']+'</span>';
  1100. row.appendChild(th);
  1101. continue;
  1102. }
  1103. if(row.getAttribute('class') == null){
  1104. var _icon = row.getElementsByClassName('_icon')[0];
  1105. var div_icon = _icon.getElementsByTagName('div')[0];
  1106. var ship_class = div_icon.getAttribute('class').split('-')[1];
  1107. if(row.cells.length < 6){
  1108. for(var t = 0; t < typeShip.length; t++){
  1109. var type = typeShip[t].toLowerCase();
  1110. if(ship_class == type){
  1111. ship_class = typeShip[t];
  1112. }
  1113. }
  1114. var td = document.createElement('td');
  1115. td.innerHTML = '<span style="color:'+findColorASC(MembersArray[0]['info']['statistics']['pvp']['wr_'+ship_class], 'wr', 'main')+';">'+valueFormat((MembersArray[0]['info']['statistics']['pvp']['wr_'+ship_class]).toFixed(0))+'</span>';
  1116. row.appendChild(td);
  1117. }
  1118. var battles = htmlParseMemberStatistic(row.cells[2]);
  1119. if(battles > 0){
  1120. var wins = htmlParseMemberStatistic(row.cells[3]);
  1121. var avg_xp = htmlParseMemberStatistic(row.cells[4]);
  1122. var wins_percents = (wins/battles)*100; if(isNaN(wins_percents)){wins_percents = 0;}
  1123. row.cells[3].setAttribute('style', 'white-space: nowrap;');
  1124. row.cells[3].innerHTML = valueFormat(wins)+' <span style="color:'+findColorASC(wins_percents, 'wins_percents', 'main')+';">('+valueFormat((wins_percents).toFixed(0))+'%)</span>';
  1125. row.cells[4].setAttribute('style', 'white-space: nowrap;');
  1126. row.cells[4].innerHTML = ' <span style="color:'+findColorASC(avg_xp, 'avg_xp', 'main')+';">'+valueFormat(avg_xp)+'</span>';
  1127. }
  1128. continue;
  1129. }
  1130. if(row.getAttribute('class').indexOf('_expandable') > -1){
  1131. if(row.cells.length < 5){
  1132. var src = row.cells[0].getElementsByClassName('_icon-ships')[0].src;
  1133. var src_split = src.split('/');
  1134. var img_name = src_split[src_split.length - 1];
  1135. var ship_id = getImgNameToShipId(img_name);
  1136. var name_text = row.cells[0].getElementsByClassName('_text')[0];
  1137. var is_premium = Encyclopedia[ship_id]['is_premium'];
  1138. if(is_premium){
  1139. name_text.setAttribute('style', 'color: #ffab34;');
  1140. }
  1141. var td = document.createElement('td');
  1142. td.setAttribute('id', 'wr-'+ship_id);
  1143. td.innerHTML = '<span>0</span>';
  1144. row.appendChild(td);
  1145. }
  1146. var battles = htmlParseMemberStatistic(row.cells[1]);
  1147. if(battles > 0){
  1148. var wins = htmlParseMemberStatistic(row.cells[2]);
  1149. var avg_xp = htmlParseMemberStatistic(row.cells[3]);
  1150. var wins_percents = (wins/battles)*100; if(isNaN(wins_percents)){wins_percents = 0;}
  1151. row.cells[2].setAttribute('style', 'white-space: nowrap;');
  1152. row.cells[2].innerHTML = valueFormat(wins)+' <span style="color:'+findColorASC(wins_percents, 'wins_percents', 'main')+';">('+valueFormat((wins_percents).toFixed(0))+'%)</span>';
  1153. row.cells[3].setAttribute('style', 'white-space: nowrap;');
  1154. row.cells[3].innerHTML = ' <span style="color:'+findColorASC(avg_xp, 'avg_xp', 'main')+';">'+valueFormat(avg_xp)+'</span>';
  1155. }
  1156. continue;
  1157. }
  1158. if(row.getAttribute('class').indexOf('_ship-entry-stat') > -1){
  1159. row.cells[0].setAttribute('colspan', '6');
  1160. continue;
  1161. }
  1162. }
  1163. for(var shipI = 0; shipI < MembersArray[0]['ships'].length; shipI++){
  1164. var ship_id = MembersArray[0]['ships'][shipI]['ship_id'];
  1165. var wr_cell = document.getElementById('wr-'+ship_id);
  1166. if(wr_cell != null){
  1167. wr_cell.setAttribute('style', 'white-space: nowrap;');
  1168. wr_cell.innerHTML = '<span style="color:'+findColorASC(MembersArray[0]['ships'][shipI]['pvp']['wr'], 'wr', 'main')+';">'+valueFormat((MembersArray[0]['ships'][shipI]['pvp']['wr']).toFixed(0))+'</span>';
  1169. }
  1170. }
  1171. }
  1172. var account_tabs = document.getElementsByClassName('account-tabs')[0];
  1173. var account_tabs_ul = account_tabs.getElementsByTagName("ul")[0];
  1174. var account_tabs_ul_li = account_tabs.getElementsByTagName("li");
  1175. if(account_tabs_ul_li[3].getAttribute('class') == 'account-tab _active' && !ships_detail_stats){
  1176. setTimeout(function(){viewMainPageProfile();}, 1000);
  1177. }else if(account_tabs_ul_li[2].getAttribute('class') == 'account-tab _active' && !achieves_block){
  1178. setTimeout(function(){viewMainPageProfile();}, 1000);
  1179. }else if(account_tabs_ul_li[0].getAttribute('class') == 'account-tab _active' && (!account_tab_overview || !main_page_script_block)){
  1180. setTimeout(function(){viewMainPageProfile();}, 1000);
  1181. }
  1182. }
  1183. }
  1184. function getHTMLStat(StatArray, type_stat){
  1185. var html = '';
  1186. var battles_percents = '';
  1187. var max_xp_ship = '';
  1188. var max_damage_dealt_ship = '';
  1189. var max_frags_ship = '';
  1190. var max_planes_killed_ship = '';
  1191. if(type_stat == 'main'){
  1192. var max_xp_ship_name = StatArray['max_xp_ship_id']; if(Encyclopedia[''+StatArray['max_xp_ship_id']+'']){max_xp_ship_name = Encyclopedia[''+StatArray['max_xp_ship_id']+'']['name'];}
  1193. var max_damage_dealt_ship_name = StatArray['max_damage_dealt_ship_id']; if(Encyclopedia[''+StatArray['max_damage_dealt_ship_id']+'']){max_damage_dealt_ship = Encyclopedia[''+StatArray['max_damage_dealt_ship_id']+'']['name'];}
  1194. var max_frags_ship_name = StatArray['max_frags_ship_id']; if(Encyclopedia[''+StatArray['max_frags_ship_id']+'']){max_frags_ship_name = Encyclopedia[''+StatArray['max_frags_ship_id']+'']['name'];}
  1195. var max_planes_killed_ship_name = StatArray['max_planes_killed_ship_id']; if(Encyclopedia[''+StatArray['max_planes_killed_ship_id']+'']){max_planes_killed_ship_name = Encyclopedia[''+StatArray['max_planes_killed_ship_id']+'']['name'];}
  1196. battles_percents = '<small>('+valueFormat((StatArray['battles_percents']).toFixed(2))+'%)</small>';
  1197. max_xp_ship = '<small> ('+max_xp_ship_name+')</small>';
  1198. max_damage_dealt_ship = '<small> ('+max_damage_dealt_ship_name+')</small>';
  1199. max_frags_ship = '<small> ('+max_frags_ship_name+')</small>';
  1200. max_planes_killed_ship = '<small> ('+max_planes_killed_ship_name+')</small>';
  1201. }
  1202. html = ''+
  1203. '<div class="row">' +
  1204. '<div class="col-xs-12 col-sm-4">' +
  1205. '<table class="account-table _left">' +
  1206. '<thead>' +
  1207. '<tr>' +
  1208. '<th colspan="2">' +
  1209. '<h3 class="account-title">'+localizationText['stat-table-1']+'</h3>' +
  1210. '</th>' +
  1211. '</tr>' +
  1212. '</thead>' +
  1213. '<tbody>' +
  1214. '<tr>' +
  1215. '<td class="_name">' +
  1216. '<span>'+localizationText['battles']+'</span>' +
  1217. '</td>' +
  1218. '<td class="_value">' +
  1219. '<span style="color: '+findColorASC(StatArray['battles'], 'battles', type_stat)+';">'+
  1220. valueFormat((StatArray['battles']).toFixed(0))+
  1221. '</span>' +
  1222. battles_percents+
  1223. '</td>' +
  1224. '</tr>' +
  1225. '<tr>' +
  1226. '<td class="_name">' +
  1227. '<span>'+localizationText['wins']+'</span>' +
  1228. '</td>' +
  1229. '<td class="_value">' +
  1230. '<span>'+
  1231. valueFormat((StatArray['wins']).toFixed(0))+
  1232. '</span>' +
  1233. '<small style="color: '+findColorASC(StatArray['wins_percents'], 'wins_percents', type_stat)+';">('+
  1234. valueFormat((StatArray['wins_percents']).toFixed(2))+
  1235. '%)</small>'+
  1236. '</td>' +
  1237. '</tr>' +
  1238. '<tr>' +
  1239. '<td class="_name">' +
  1240. '<span>'+localizationText['survived_battles']+'</span>' +
  1241. '</td>' +
  1242. '<td class="_value">' +
  1243. '<span>'+
  1244. valueFormat((StatArray['survived_battles']).toFixed(0))+
  1245. '</span>' +
  1246. '<small style="color: '+findColorASC(StatArray['survived_battles_percents'], 'survived_battles_percents', type_stat)+';">('+
  1247. valueFormat((StatArray['survived_battles_percents']).toFixed(2))+
  1248. '%)</small>'+
  1249. '</td>' +
  1250. '</tr>' +
  1251. '<tr>' +
  1252. '<td class="_name">' +
  1253. '<span>'+localizationText['damage_dealt']+'</span>' +
  1254. '</td>' +
  1255. '<td class="_value">' +
  1256. '<span>'+valueFormat((StatArray['damage_dealt']).toFixed(0))+'</span>' +
  1257. '</td>' +
  1258. '</tr>' +
  1259. '<tr>' +
  1260. '<td class="_name">' +
  1261. '<span>'+localizationText['frags']+'</span>' +
  1262. '</td>' +
  1263. '<td class="_value">' +
  1264. '<span>'+valueFormat((StatArray['frags']).toFixed(0))+'</span>' +
  1265. '</td>' +
  1266. '</tr>' +
  1267. '<tr>' +
  1268. '<td class="_name">' +
  1269. '<span>'+localizationText['planes_killed']+'</span>' +
  1270. '</td>' +
  1271. '<td class="_value">' +
  1272. '<span>'+valueFormat((StatArray['planes_killed']).toFixed(0))+'</span>' +
  1273. '</td>' +
  1274. '</tr>' +
  1275. '<tr>' +
  1276. '<td class="_name">' +
  1277. '<span>'+localizationText['capture_points']+'</span>' +
  1278. '</td>' +
  1279. '<td class="_value">' +
  1280. '<span>'+valueFormat((StatArray['capture_points']).toFixed(0))+'</span>' +
  1281. '</td>' +
  1282. '</tr>' +
  1283. '<tr>' +
  1284. '<td class="_name">' +
  1285. '<span>'+localizationText['dropped_capture_points']+'</span>' +
  1286. '</td>' +
  1287. '<td class="_value">' +
  1288. '<span>'+valueFormat((StatArray['dropped_capture_points']).toFixed(0))+'</span>' +
  1289. '</td>' +
  1290. '</tr>' +
  1291. '</tbody>' +
  1292. '</table>' +
  1293. '</div>' +
  1294. '<div class="col-xs-12 col-sm-4">' +
  1295. '<table class="account-table _center">' +
  1296. '<thead>' +
  1297. '<tr>' +
  1298. '<th colspan="2">' +
  1299. '<h3 class="account-title">'+localizationText['stat-table-2']+'</h3>' +
  1300. '</th>' +
  1301. '</tr>' +
  1302. '</thead>' +
  1303. '<tbody>' +
  1304. '<tr>' +
  1305. '<td class="_name">' +
  1306. '<span>'+localizationText['avg_xp']+'</span>' +
  1307. '</td>' +
  1308. '<td class="_value">' +
  1309. '<span style="color: '+findColorASC(StatArray['avg_xp'], 'avg_xp', type_stat)+';">'+
  1310. valueFormat((StatArray['avg_xp']).toFixed(2))+
  1311. '</span>' +
  1312. '</td>' +
  1313. '</tr>' +
  1314. '<tr>' +
  1315. '<td class="_name">' +
  1316. '<span>'+localizationText['avg_damage_dealt']+'</span>' +
  1317. '</td>' +
  1318. '<td class="_value">' +
  1319. '<span style="color: '+findColorASC(StatArray['avg_damage_dealt'], 'avg_damage_dealt', type_stat)+';">'+
  1320. valueFormat((StatArray['avg_damage_dealt']).toFixed(2))+
  1321. '</span>' +
  1322. '</td>' +
  1323. '</tr>' +
  1324. '<tr>' +
  1325. '<td class="_name">' +
  1326. '<span>'+localizationText['avg_frags']+'</span>' +
  1327. '</td>' +
  1328. '<td class="_value">' +
  1329. '<span style="color: '+findColorASC(StatArray['avg_frags'], 'avg_frags', type_stat)+';">'+
  1330. valueFormat((StatArray['avg_frags']).toFixed(2))+
  1331. '</span>' +
  1332. '</td>' +
  1333. '</tr>' +
  1334. '<tr>' +
  1335. '<td class="_name">' +
  1336. '<span>'+localizationText['avg_planes_killed']+'</span>' +
  1337. '</td>' +
  1338. '<td class="_value">' +
  1339. '<span style="color: '+findColorASC(StatArray['avg_planes_killed'], 'avg_planes_killed', type_stat)+';">'+
  1340. valueFormat((StatArray['avg_planes_killed']).toFixed(2))+
  1341. '</span>' +
  1342. '</td>' +
  1343. '</tr>' +
  1344. '<tr>' +
  1345. '<td class="_name">' +
  1346. '<span>'+localizationText['avg_capture_points']+'</span>' +
  1347. '</td>' +
  1348. '<td class="_value">' +
  1349. //'<span style="color: '+findColorASC(StatArray['avg_capture_points'], 'avg_capture_points', type_stat)+';">'
  1350. '<span>'
  1351. +valueFormat((StatArray['avg_capture_points']).toFixed(2))+
  1352. '</span>' +
  1353. '</td>' +
  1354. '</tr>' +
  1355. '<tr>' +
  1356. '<td class="_name">' +
  1357. '<span>'+localizationText['avg_dropped_capture_points']+'</span>' +
  1358. '</td>' +
  1359. '<td class="_value">' +
  1360. //'<span style="color: '+findColorASC(StatArray['avg_dropped_capture_points'], 'avg_dropped_capture_points', type_stat)+';">'+
  1361. '<span>'+
  1362. valueFormat((StatArray['avg_dropped_capture_points']).toFixed(0))+
  1363. '</span>' +
  1364. '</td>' +
  1365. '</tr>' +
  1366. '</tbody>' +
  1367. '</table>' +
  1368. '</div>' +
  1369. '<div class="col-xs-12 col-sm-4">' +
  1370. '<table class="account-table _right">' +
  1371. '<thead>' +
  1372. '<tr>' +
  1373. '<th colspan="2">' +
  1374. '<h3 class="account-title">'+localizationText['stat-table-3']+'</h3>' +
  1375. '</th>' +
  1376. '</tr>' +
  1377. '</thead>' +
  1378. '<tbody>' +
  1379. '<tr>' +
  1380. '<td class="_name">' +
  1381. '<span>'+localizationText['max_xp']+'</span>' +
  1382. max_xp_ship +
  1383. '</td>' +
  1384. '<td class="_value">' +
  1385. '<span style="color: '+findColorASC(StatArray['max_xp'], 'max_xp', type_stat)+';">'+
  1386. valueFormat((StatArray['max_xp']).toFixed(0))+
  1387. '</span>' +
  1388. '</td>' +
  1389. '</tr>' +
  1390. '<tr>' +
  1391. '<td class="_name">' +
  1392. '<span>'+localizationText['max_damage_dealt']+'</span>' +
  1393. max_damage_dealt_ship +
  1394. '</td>' +
  1395. '<td class="_value">' +
  1396. '<span style="color: '+findColorASC(StatArray['max_damage_dealt'], 'max_damage_dealt', type_stat)+';">'+
  1397. valueFormat((StatArray['max_damage_dealt']).toFixed(0))+
  1398. '</span>' +
  1399. '</td>' +
  1400. '</tr>' +
  1401. '<tr>' +
  1402. '<td class="_name">' +
  1403. '<span>'+localizationText['max_frags_battle']+'</span>' +
  1404. max_frags_ship+
  1405. '</td>' +
  1406. '<td class="_value">' +
  1407. '<span style="color: '+findColorASC(StatArray['max_frags_battle'], 'max_frags_battle', type_stat)+';">'+
  1408. valueFormat((StatArray['max_frags_battle']).toFixed(0))+
  1409. '</span>' +
  1410. '</td>' +
  1411. '</tr>' +
  1412. '<tr>' +
  1413. '<td class="_name">' +
  1414. '<span>'+localizationText['max_planes_killed']+'</span>' +
  1415. max_planes_killed_ship+
  1416. '</td>' +
  1417. '<td class="_value">' +
  1418. '<span style="color: '+findColorASC(StatArray['max_planes_killed'], 'max_planes_killed', type_stat)+';">'+
  1419. valueFormat((StatArray['max_planes_killed']).toFixed(0))+
  1420. '</span>' +
  1421. '</td>' +
  1422. '</tr>' +
  1423. '</tbody>' +
  1424. '</table>' +
  1425. '</div>' +
  1426. '</div>' +
  1427. '';
  1428. return html;
  1429. }
  1430. function getHTMLShipStat(StatArray, type){
  1431. var htmlArray = [];
  1432. var StatClassArray = [];
  1433. for(var tS = 0; tS < typeShip.length; tS++){
  1434. htmlArray[typeShip[tS]] = '';
  1435. StatClassArray[typeShip[tS]] = [];
  1436. StatClassArray[typeShip[tS]]['battles'] = 0;
  1437. StatClassArray[typeShip[tS]]['wins'] = 0;
  1438. StatClassArray[typeShip[tS]]['xp'] = 0;
  1439. StatClassArray[typeShip[tS]]['count'] = 0;
  1440. }
  1441. StatArray['ships'].sort(DESC(type+'.battles'));
  1442. for(var sI = 0; sI < StatArray['ships'].length; sI++){
  1443. var Ship = StatArray['ships'][sI];
  1444. var ship_id = Ship['ship_id'];
  1445. var ship_nation = Encyclopedia[ship_id]['nation'];
  1446. var ship_name = Encyclopedia[ship_id]['name'];
  1447. var ship_type = Encyclopedia[ship_id]['type'];
  1448. var ship_tier = Encyclopedia[ship_id]['tier'];
  1449. var ship_lvl = getLevelText(ship_tier);
  1450. var ship_img = Encyclopedia[ship_id]['images']['small']; ship_img = ship_img.replace('http://', 'https://');
  1451. var is_premium = Encyclopedia[ship_id]['is_premium'];
  1452. var color_name = '';
  1453. if(is_premium){
  1454. color_name = '#ffab34';
  1455. }
  1456. if(Ship[type]['battles'] > 0){
  1457. StatClassArray[ship_type]['battles'] += Ship[type]['battles'];
  1458. StatClassArray[ship_type]['wins'] += Ship[type]['wins'];
  1459. StatClassArray[ship_type]['xp'] += Ship[type]['xp'];
  1460. StatClassArray[ship_type]['count']++;
  1461. htmlArray[ship_type] += '' +
  1462. '<tr class="_expandable ship-stat-'+type+'" open-block="ship-'+ship_id+'-'+ship_tier+'-'+type+'" open-active="false">' +
  1463. '<td colspan="2" class="_name">' +
  1464. '<div class="_bg-nation-'+ship_nation+'"></div>' +
  1465. '<span class="_lvl">'+ship_lvl+'</span>' +
  1466. '<img class="_icon-ships img-responsive" style="width: 68px; height: 40px;" src="'+ship_img+'">' +
  1467. '<span class="_text" style="color: '+color_name+';">'+ship_name+'</span>' +
  1468. '</td>' +
  1469. '<td class="_value">'+valueFormat((Ship[type]['battles']).toFixed(0))+'</td>' +
  1470. '<td class="_value" style="white-space: nowrap;">' +
  1471. Ship[type]['wins']+' ' +
  1472. '<span style="color:'+findColorASC(Ship[type]['wins_percents'], 'wins_percents', 'main')+'">' +
  1473. '('+valueFormat((Ship[type]['wins_percents']).toFixed(0))+'%)' +
  1474. '</span>' +
  1475. '</td>' +
  1476. '<td class="_value" style="white-space: nowrap;">' +
  1477. '<span style="color:'+findColorASC(Ship[type]['avg_xp'], 'avg_xp', 'main')+';">' +
  1478. valueFormat((Ship[type]['avg_xp']).toFixed(0)) +
  1479. '</span>' +
  1480. '</td>' +
  1481. '<td style="white-space: nowrap;">' +
  1482. '<span style="color:'+findColorASC(Ship[type]['wr'], 'wr', 'main')+';">' +
  1483. valueFormat((Ship[type]['wr']).toFixed(0)) +
  1484. '</span>' +
  1485. '</td>' +
  1486. '</tr>' +
  1487. '<tr class="_hide _ship-entry-stat ship-'+ship_id+'-'+ship_tier+'-'+type+'">' +
  1488. '<td colspan="6">' +
  1489. getHTMLStat(Ship[type], 'ship') +
  1490. '</td>' +
  1491. '</tr>'+
  1492. '';
  1493. }
  1494. }
  1495. var html = '';
  1496. for(var tS = 0; tS < typeShip.length; tS++){
  1497. var wins_percents = (StatClassArray[typeShip[tS]]['wins']/StatClassArray[typeShip[tS]]['battles'])*100; if(isNaN(wins_percents)){wins_percents = 0;}
  1498. var avg_xp = StatClassArray[typeShip[tS]]['xp']/StatClassArray[typeShip[tS]]['battles']; if(isNaN(avg_xp)){avg_xp = 0;}
  1499. html += '' +
  1500. '<tbody class="_expandable ships-class-'+type+'" open-block="ships-class-'+typeShip[tS].toLowerCase()+'-'+type+'" open-active="false">' +
  1501. '<tr>' +
  1502. '<td class="_icon"><div class="_icon-'+typeShip[tS].toLowerCase()+'"></div></td>' +
  1503. '<td class="_name">' +
  1504. localizationText[typeShip[tS].toLowerCase()]+' ('+StatClassArray[typeShip[tS]]['count']+')' +
  1505. '</td>' +
  1506. '<td class="_value">'+valueFormat((StatClassArray[typeShip[tS]]['battles']).toFixed(0))+'</td>' +
  1507. '<td class="_value" style="white-space: nowrap;">' +
  1508. valueFormat((StatClassArray[typeShip[tS]]['wins']).toFixed(0))+' ' +
  1509. '<span style="color:'+findColorASC(wins_percents, 'wins_percents', 'main')+';">' +
  1510. '('+valueFormat((wins_percents).toFixed(0))+'%)' +
  1511. '</span>' +
  1512. '</td>' +
  1513. '<td class="_value" style="white-space: nowrap;"> ' +
  1514. '<span style="color:'+findColorASC(avg_xp, 'avg_xp', 'main')+';">' +
  1515. valueFormat((avg_xp).toFixed(0)) +
  1516. '</span>' +
  1517. '</td>' +
  1518. '<td>' +
  1519. '<span style="color:'+findColorASC(StatArray['info']['statistics'][type]['wr_'+typeShip[tS]], 'wr', 'main')+';">' +
  1520. valueFormat((StatArray['info']['statistics'][type]['wr_'+typeShip[tS]]).toFixed(0)) +
  1521. '</span>' +
  1522. '</td>' +
  1523. '</tr>' +
  1524. '</tbody>' +
  1525. '<tbody class="_hide ships-class-'+typeShip[tS].toLowerCase()+'-'+type+'">' +
  1526. htmlArray[typeShip[tS]] +
  1527. '</tbody>' +
  1528. '';
  1529. }
  1530. return html;
  1531. }
  1532. function GeneratorUserBar(userbarbg){
  1533. var jsonString = 'json='+JSON.stringify(MembersArray[0])+'&type=userbar&userbarbg='+userbarbg+'&lang='+lang;
  1534. var xmlhttp;
  1535. try{
  1536. xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
  1537. }catch(e){
  1538. try{
  1539. xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
  1540. }catch(E){
  1541. xmlhttp = false;
  1542. }
  1543. }
  1544. if(!xmlhttp && typeof XMLHttpRequest != 'undefined'){
  1545. xmlhttp = new XMLHttpRequest();
  1546. }
  1547. xmlhttp.open('POST', ''+WoWsStatInfoHref+'userbar.php?random='+Math.floor(Math.random()*100000001), true);
  1548. xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  1549. xmlhttp.onreadystatechange = function(){
  1550. if(xmlhttp.readyState == 4){
  1551. if(xmlhttp.status == 200){
  1552. var userbar_img = document.getElementById('userbar-img');
  1553. userbar_img.src = xmlhttp.responseText+'?'+Math.floor(Math.random()*100000001);
  1554. var userbar_link = document.getElementById('userbar-link');
  1555. userbar_link.textContent = '[url='+WoWsStatInfoHref+'?realm_search='+realm+'&nickname='+MembersArray[0]['info']['nickname']+'][img]'+xmlhttp.responseText+'[/img][/url]';
  1556. }
  1557. }
  1558. };
  1559. xmlhttp.send(jsonString);
  1560. }
  1561. var UserBarBGData = null;
  1562. var CountUserBar = [];
  1563. function doneUserBarBG(url, response){
  1564. UserBarBGData = response;
  1565. CountUserBar['all'] = 0;
  1566. CountUserBar['clan'] = 0;
  1567. CountUserBar['noclassification'] = 0;
  1568. CountUserBar['battleship'] = [];
  1569. CountUserBar['battleship']['count'] = 0;
  1570. CountUserBar['battleship']['japan'] = 0;
  1571. CountUserBar['battleship']['ussr'] = 0;
  1572. CountUserBar['battleship']['germany'] = 0;
  1573. CountUserBar['battleship']['uk'] = 0;
  1574. CountUserBar['battleship']['usa'] = 0;
  1575. CountUserBar['aircarrier'] = [];
  1576. CountUserBar['aircarrier']['count'] = 0;
  1577. CountUserBar['aircarrier']['japan'] = 0;
  1578. CountUserBar['aircarrier']['ussr'] = 0;
  1579. CountUserBar['aircarrier']['germany'] = 0;
  1580. CountUserBar['aircarrier']['uk'] = 0;
  1581. CountUserBar['aircarrier']['usa'] = 0;
  1582. CountUserBar['cruiser'] = [];
  1583. CountUserBar['cruiser']['count'] = 0;
  1584. CountUserBar['cruiser']['japan'] = 0;
  1585. CountUserBar['cruiser']['ussr'] = 0;
  1586. CountUserBar['cruiser']['germany'] = 0;
  1587. CountUserBar['cruiser']['uk'] = 0;
  1588. CountUserBar['cruiser']['usa'] = 0;
  1589. CountUserBar['destroyer'] = [];
  1590. CountUserBar['destroyer']['count'] = 0;
  1591. CountUserBar['destroyer']['japan'] = 0;
  1592. CountUserBar['destroyer']['ussr'] = 0;
  1593. CountUserBar['destroyer']['germany'] = 0;
  1594. CountUserBar['destroyer']['uk'] = 0;
  1595. CountUserBar['destroyer']['usa'] = 0;
  1596. for(var i = 0; i < UserBarBGData.length; i++){
  1597. var img = UserBarBGData[i].split('_');
  1598. if(img.length > 1){
  1599. for(var i_id = 1; i_id < img.length; i_id++){
  1600. if(MembersArray[0]['clan'] == null){break;}
  1601. if(img[i_id] == MembersArray[0]['clan']['clan_id']){
  1602. CountUserBar['clan']++;
  1603. CountUserBar['all']++;
  1604. }
  1605. }
  1606. }else{
  1607. CountUserBar['all']++;
  1608. var shipsBG = UserBarBGData[i].split('-');
  1609. if(shipsBG.length == 2){
  1610. CountUserBar['noclassification']++;
  1611. }else if(shipsBG.length == 3){
  1612. var type = shipsBG[1];
  1613. var nation = shipsBG[2];
  1614. CountUserBar[type]['count']++;
  1615. CountUserBar[type][nation]++;
  1616. }
  1617. }
  1618. }
  1619. var html = '' +
  1620. '<div style="width: 488px; border-bottom: 1px solid rgba(0, 0, 0, 0.7); box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.05); padding: 0 0 14px; margin: 0 0 14px;">' +
  1621. localizationText['userbar-filters']+' ' +
  1622. '<select id="userbar-bg-filtr-types" name="types" style="color: black;">' +
  1623. '<option value="all">'+localizationText['filters-all']+' ('+CountUserBar['all']+')</option>' +
  1624. '<option value="clan">'+localizationText['filters-clan']+' ('+CountUserBar['clan']+')</option>' +
  1625. '<option value="noclassification">'+localizationText['filters-noclassification']+' ('+CountUserBar['noclassification']+')</option>' +
  1626. '<option value="battleship">'+localizationText['filters-battleship']+' ('+CountUserBar['battleship']['count']+')</option>' +
  1627. '<option value="aircarrier">'+localizationText['filters-aircarrier']+' ('+CountUserBar['aircarrier']['count']+')</option>' +
  1628. '<option value="cruiser">'+localizationText['filters-cruiser']+' ('+CountUserBar['cruiser']['count']+')</option>' +
  1629. '<option value="destroyer">'+localizationText['filters-destroyer']+' ('+CountUserBar['destroyer']['count']+')</option>' +
  1630. '</select>' +
  1631. '<select id="userbar-bg-filtr-nations" name="nations" style="color: black; margin-left: 10px; display: none;">' +
  1632. '<option value="japan">'+localizationText['filters-japan']+'</option>' +
  1633. '<option value="ussr">'+localizationText['filters-ussr']+'</option>' +
  1634. '<option value="germany">'+localizationText['filters-germany']+'</option>' +
  1635. '<option value="uk">'+localizationText['filters-uk']+'</option>' +
  1636. '<option value="usa">'+localizationText['filters-usa']+'</option>' +
  1637. '</select>' +
  1638. '</div>' +
  1639. '';
  1640. var check = true;
  1641. html += '<div id="userbar-bg-content" style="width: 488px; height: 429px; overflow-y: scroll;">';
  1642. for(var i = 0; i < UserBarBGData.length; i++){
  1643. var imgbgview = false;
  1644. var img = UserBarBGData[i].split('_');
  1645. if(img.length > 1){
  1646. for(var i_id = 1; i_id < img.length; i_id++){
  1647. if(MembersArray[0]['clan'] == null){break;}
  1648. if(img[i_id] == MembersArray[0]['clan']['clan_id']){
  1649. imgbgview = true;
  1650. }
  1651. }
  1652. }else{
  1653. imgbgview = true;
  1654. }
  1655. if(imgbgview){
  1656. var checked = ''; if(check){checked = 'checked="checked"'; check = false;}
  1657. html += '<input type="radio" name="userbar-bg" value="'+UserBarBGData[i]+'" '+checked+'> '+UserBarBGData[i]+'<br />';
  1658. html += '<img src="'+WoWsStatInfoHref+'bg/'+UserBarBGData[i]+'.png" title="'+UserBarBGData[i]+'"/><br /><br />';
  1659. }
  1660. }
  1661. html += '</div>';
  1662. html += '' +
  1663. '<button class="btn btn-lg btn-turqoise" id="userbar-your-background" style="margin-top: 5px; padding: 5px;">' +
  1664. localizationText['userbar-your-background'] +
  1665. '</button>' +
  1666. '';
  1667. onShowMessage(
  1668. localizationText['userbar-bg'],
  1669. html,
  1670. function(){
  1671. var userbarbg = 'userbar';
  1672. var radios = document.getElementsByName('userbar-bg');
  1673. for(var i = 0; i < radios.length; i++){
  1674. if(radios[i].checked){
  1675. userbarbg = radios[i].value;
  1676. break;
  1677. }
  1678. }
  1679. GeneratorUserBar(userbarbg);
  1680. onCloseMessage();
  1681. },
  1682. localizationText['Ok'],
  1683. true
  1684. );
  1685.  
  1686. jQ('#userbar-your-background').click(function(){
  1687. onCloseMessage();
  1688. var html = '' +
  1689. '<div id="userbar-bg-content" style="width: 488px; height: 220px;">' +
  1690. '<p>'+localizationText['img-max-size']+', '+localizationText['img-max-px']+', '+localizationText['img-format']+'</p>' +
  1691. '<form id="upload-myfile" name="upload-myfile">' +
  1692. '<input type="file" name="myfile" accept="image/x-png" />' +
  1693. '<button type="submit" name="submit" class="btn btn-lg btn-turqoise" id="userbar-your-background" style="margin: 5px 0px; padding: 5px;">' +
  1694. localizationText['upload-submit'] +
  1695. '</button>' +
  1696. '</form>' +
  1697. '<img id="userbar-img-upload" src="'+WoWsStatInfoHref+'bg/userbar.png" userbarbg="userbar" />' +
  1698. '</div>'+
  1699. '';
  1700. var check_upload = false;
  1701. onShowMessage(
  1702. localizationText['upload-verification'],
  1703. html,
  1704. function(){
  1705. onCloseMessage();
  1706. if(check_upload){
  1707. onShowMessage(
  1708. localizationText['Box'],
  1709. localizationText['upload-verification'],
  1710. onCloseMessage,
  1711. localizationText['Ok'],
  1712. false
  1713. );
  1714. }else{
  1715. var userbar_img_upload = document.getElementById('userbar-img-upload');
  1716. if(userbar_img_upload.getAttribute('userbarbg') != 'userbar'){
  1717. GeneratorUserBar(userbar_img_upload.getAttribute('userbarbg'));
  1718. }
  1719. }
  1720. },
  1721. localizationText['Ok'],
  1722. true
  1723. );
  1724. var img = new Image();
  1725. img.onload = function(){
  1726. var userbar_img_upload = document.getElementById('userbar-img-upload');
  1727. if(userbar_img_upload != null){
  1728. userbar_img_upload.src = WoWsStatInfoHref+'bg/user/'+MembersArray[0]['info']['account_id']+'.png'+'?'+Math.floor(Math.random()*100000001);
  1729. userbar_img_upload.setAttribute('userbarbg', 'user/'+MembersArray[0]['info']['account_id']);
  1730. }
  1731. }
  1732. img.src = WoWsStatInfoHref+'bg/user/'+MembersArray[0]['info']['account_id']+'.png'+'?'+Math.floor(Math.random()*100000001);
  1733. document.forms["upload-myfile"].onsubmit = function(e){
  1734. e.preventDefault();
  1735. check_upload = true;
  1736. function validateExtension(v){
  1737. var allowedExtensions = new Array(".png", ".PNG");
  1738. for(var ct = 0;ct < allowedExtensions.length; ct++){
  1739. sample = v.lastIndexOf(allowedExtensions[ct]);
  1740. if(sample != -1){return true;}
  1741. }
  1742. return false;
  1743. }
  1744. var file_local_link = this.elements.myfile.value;
  1745. var file = this.elements.myfile.files[0];
  1746. if(file){
  1747. if(file.size <= 153600){
  1748. var _URL = window.URL || window.webkitURL;
  1749. var img = new Image();
  1750. img.onload = function (){
  1751. if(this.width == 468 && this.height == 100){
  1752. if(validateExtension(file_local_link)){
  1753. var xmlhttp;
  1754. try{
  1755. xmlhttp = new ActiveXObject('Msxml2.XMLHTTP');
  1756. }catch(e){
  1757. try{
  1758. xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
  1759. }catch(E){
  1760. xmlhttp = false;
  1761. }
  1762. }
  1763. if(!xmlhttp && typeof XMLHttpRequest != 'undefined'){
  1764. xmlhttp = new XMLHttpRequest();
  1765. }
  1766. xmlhttp.onload = xmlhttp.onerror = function(){
  1767. if(this.status == 200){
  1768. console.log("upload-myfile success");
  1769. console.log(xmlhttp.responseText);
  1770. var userbar_img_upload = document.getElementById('userbar-img-upload');
  1771. if(userbar_img_upload != null){
  1772. userbar_img_upload.src = WoWsStatInfoHref+'bg/user/temp/'+MembersArray[0]['info']['account_id']+'.png'+'?'+Math.floor(Math.random()*100000001);
  1773. userbar_img_upload.setAttribute('userbarbg', 'userbar');
  1774. }
  1775. }else{
  1776. console.log("upload-myfile error " + this.status);
  1777. }
  1778. };
  1779. xmlhttp.upload.onprogress = function(event){
  1780. console.log(event.loaded + ' / ' + event.total);
  1781. }
  1782. xmlhttp.open("POST", WoWsStatInfoHref+"upload-bg.php?random="+Math.floor(Math.random()*100000001), true);
  1783. var formData = new FormData();
  1784. formData.append("myfile", file);
  1785. formData.append("account_id", MembersArray[0]['info']['account_id']);
  1786. xmlhttp.send(formData);
  1787. }else{
  1788. alert(localizationText['img-format']);
  1789. }
  1790. }else{
  1791. alert(localizationText['img-max-px']);
  1792. }
  1793. };
  1794. img.src = _URL.createObjectURL(file);
  1795. }else{
  1796. alert(localizationText['img-max-size']);
  1797. }
  1798. }
  1799. return false;
  1800. }
  1801. });
  1802. jQ('#userbar-bg-filtr-types').change(function(){
  1803. updateUserBarBG();
  1804. });
  1805. jQ('#userbar-bg-filtr-nations').change(function(){
  1806. updateUserBarBG();
  1807. });
  1808. }
  1809. function errorUserBarBG(url){
  1810. var html = '' +
  1811. '<div style="width: 488px;">' +
  1812. '<input type="radio" name="userbar-bg" value="userbar" checked="checked"> userbar<br />' +
  1813. '<img src="'+WoWsStatInfoHref+'bg/userbar.png" title="userbar"/><br /><br />' +
  1814. '</div>' +
  1815. '';
  1816. onShowMessage(
  1817. localizationText['userbar-bg'],
  1818. html,
  1819. function(){
  1820. var userbarbg = 'userbar';
  1821. var radios = document.getElementsByName('userbar-bg');
  1822. for(var i = 0; i < radios.length; i++){
  1823. if(radios[i].checked){
  1824. userbarbg = radios[i].value;
  1825. break;
  1826. }
  1827. }
  1828. GeneratorUserBar(userbarbg);
  1829. onCloseMessage();
  1830. },
  1831. localizationText['Ok'],
  1832. true
  1833. );
  1834. }
  1835. function updateUserBarBG(){
  1836. console.log('===============');
  1837. var html = '';
  1838. var userbar_bg_filtr_types = document.getElementById("userbar-bg-filtr-types");
  1839. var types = userbar_bg_filtr_types.options[userbar_bg_filtr_types.selectedIndex].value;
  1840. var userbar_bg_filtr_nations = document.getElementById("userbar-bg-filtr-nations");
  1841. var nations = userbar_bg_filtr_nations.options[userbar_bg_filtr_nations.selectedIndex].value;
  1842. if(types != 'all' && types != 'clan' && types != 'noclassification'){
  1843. userbar_bg_filtr_nations.style.display = 'inline';
  1844. for(i = 0; i < userbar_bg_filtr_nations.options.length; i++){
  1845. var nation = userbar_bg_filtr_nations.options[i].value
  1846. userbar_bg_filtr_nations.options[i].text = localizationText['filters-'+nation]+' ('+CountUserBar[types][nation]+')';
  1847. }
  1848. }else{
  1849. userbar_bg_filtr_nations.style.display = 'none';
  1850. }
  1851. var check = true;
  1852. for(var i = 0; i < UserBarBGData.length; i++){
  1853. var imgbgview = false;
  1854. var img = UserBarBGData[i].split('_');
  1855. if(img.length > 1 && types == 'clan'){
  1856. for(var i_id = 1; i_id < img.length; i_id++){
  1857. if(MembersArray[0]['clan'] == null){break;}
  1858. if(img[i_id] == MembersArray[0]['clan']['clan_id']){
  1859. imgbgview = true;
  1860. }
  1861. }
  1862. }else{
  1863. if(types == 'all'){
  1864. if(img.length > 1){
  1865. if(MembersArray[0]['clan'] !== null){
  1866. for(var i_id = 1; i_id < img.length; i_id++){
  1867. if(img[i_id] == MembersArray[0]['clan']['clan_id']){
  1868. imgbgview = true;
  1869. }
  1870. }
  1871. }
  1872. }else{
  1873. imgbgview = true;
  1874. }
  1875. }else if(types == 'noclassification'){
  1876. var shipsBG = UserBarBGData[i].split('-');
  1877. if(shipsBG.length == 2){
  1878. var noclassification = shipsBG[1];
  1879. if(types == noclassification){
  1880. imgbgview = true;
  1881. }
  1882. }
  1883. }else if(types != 'clan'){
  1884. var shipsBG = UserBarBGData[i].split('-');
  1885. if(shipsBG.length == 3){
  1886. var type = shipsBG[1];
  1887. var nation = shipsBG[2];
  1888. if(types == type && nations == nation){
  1889. imgbgview = true;
  1890. }
  1891. }
  1892. }
  1893. }
  1894. if(imgbgview){
  1895. var checked = ''; if(check){checked = 'checked="checked"'; check = false;}
  1896. html += '<input type="radio" name="userbar-bg" value="'+UserBarBGData[i]+'" '+checked+'> '+UserBarBGData[i]+'<br />';
  1897. html += '<img src="'+WoWsStatInfoHref+'bg/'+UserBarBGData[i]+'.png" title="'+UserBarBGData[i]+'"/><br /><br />';
  1898. }
  1899. }
  1900. var userbar_bg_content = document.getElementById("userbar-bg-content");
  1901. userbar_bg_content.innerHTML = html;
  1902. }
  1903. function viewChart(title, date, value){
  1904. $.plot(
  1905. '#chart_'+title,
  1906. [value],
  1907. {
  1908. series: {lines: {show: true}, points: {show: true}},
  1909. xaxis: {ticks: date},
  1910. grid: {hoverable: true, clickable: true},
  1911. colors: ['#00c0c0']
  1912. }
  1913. );
  1914. $('<div id="tooltip-chart-'+title+'"></div>').css({
  1915. position: "absolute",
  1916. display: "none",
  1917. border: "1px solid #fdd",
  1918. padding: "2px",
  1919. "background-color": "#00c0c0",
  1920. opacity: 0.80,
  1921. zIndex: 999,
  1922. color: "black"
  1923. }).appendTo("body");
  1924.  
  1925. $('#chart_'+title).bind("plothover", function (event, pos, item) {
  1926. if(item){
  1927. var y = item.datapoint[1].toFixed(2);
  1928. $('#tooltip-chart-'+title).html(y).css({top: item.pageY - 35, left: item.pageX - 15}).fadeIn(200);
  1929. }else{
  1930. $('#tooltip-chart-'+title).hide();
  1931. }
  1932. });
  1933. }
  1934. function getHTMLDif(value, fixed){
  1935. var text = valueFormat(value.toFixed(fixed));
  1936. var color = '#fff';
  1937. if(value > 0){
  1938. text = '+'+text;
  1939. color = 'green';
  1940. }else if(value < 0){
  1941. color = 'red';
  1942. }
  1943. return ' <span style="color: '+color+';"><sup>'+text+'</sup></span>';
  1944. }
  1945. function addStatHover(elem, type_stat_hover){
  1946. $(elem).attr('type-stat', type_stat_hover);
  1947. $(elem).hover(hoverStatIn, hoverStatOut);
  1948. var tooltip_stat = document.getElementById('tooltip-stat-'+type_stat_hover);
  1949. if(tooltip_stat == null){
  1950. $('<div id="tooltip-stat-'+type_stat_hover+'" class="tooltip tooltip-element tooltip-enabled tooltip-element-attached-top tooltip-element-attached-left tooltip-target-attached-bottom tooltip-target-attached-left"></div>').css({
  1951. width: "200px",
  1952. position: "absolute",
  1953. display: "none",
  1954. textAlign: "center",
  1955. "background-color": "#066",
  1956. padding: "0px",
  1957. top: "0",
  1958. left: "0"
  1959. }).appendTo("body");
  1960. }
  1961. }
  1962. function hoverStatIn(){
  1963. var type_stat_hover = $(this).attr('type-stat');
  1964. var bodyRect = document.body.getBoundingClientRect(),
  1965. elemRect = this.getBoundingClientRect(),
  1966. offsetTop = elemRect.top - bodyRect.top,
  1967. offsetLeft = elemRect.left - bodyRect.left;
  1968. var offsetWidth = this.offsetWidth;
  1969. var offsetHeight = this.offsetHeight;
  1970. var paddingLeft = Number($(this).css('padding-left').replace(/[^0-9\.]+/g,""));
  1971. var paddingTop = Number($(this).css('padding-top').replace(/[^0-9\.]+/g,""));
  1972. var paddingRight = Number($(this).css('padding-bottom').replace(/[^0-9\.]+/g,""));
  1973. var paddingBottom = Number($(this).css('padding-bottom').replace(/[^0-9\.]+/g,""));
  1974. var statValue = MembersArray[0]['info']['statistics']['pvp'][type_stat_hover];
  1975. var plusValue = 0.01;
  1976. var tofixedNum = 2;
  1977. if(type_stat_hover == 'battles' || type_stat_hover.indexOf("max_") > -1){
  1978. tofixedNum = 0;
  1979. plusValue = 1;
  1980. }
  1981. var color1 = color['very_bad'];
  1982. var color2 = color['very_bad'];
  1983. var color3 = color['very_bad'];
  1984. var value1 = parseFloat(0);
  1985. var value3 = parseFloat(0);
  1986. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][5])){
  1987. color1 = color['very_good'];
  1988. color2 = color['unique'];
  1989. color3 = color['unique'];
  1990. value1 = (parseFloat(colorStat[type_stat_hover][4])).toFixed(tofixedNum);
  1991. value3 = '&infin;';
  1992. }
  1993. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][4])){
  1994. color1 = color['good'];
  1995. color2 = color['very_good'];
  1996. color3 = color['unique'];
  1997. value1 = (parseFloat(colorStat[type_stat_hover][3])).toFixed(tofixedNum);
  1998. value3 = (parseFloat(colorStat[type_stat_hover][4]) + plusValue).toFixed(tofixedNum);
  1999. }
  2000. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][3])){
  2001. color1 = color['normal'];
  2002. color2 = color['good'];
  2003. color3 = color['very_good'];
  2004. value1 = (parseFloat(colorStat[type_stat_hover][2])).toFixed(tofixedNum);
  2005. value3 = (parseFloat(colorStat[type_stat_hover][3]) + plusValue).toFixed(tofixedNum);
  2006. }
  2007. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][2])){
  2008. color1 = color['bad'];
  2009. color2 = color['normal'];
  2010. color3 = color['good'];
  2011. value1 = (parseFloat(colorStat[type_stat_hover][1])).toFixed(tofixedNum);
  2012. value3 = (parseFloat(colorStat[type_stat_hover][2]) + plusValue).toFixed(tofixedNum);
  2013. }
  2014. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][1])){
  2015. color1 = color['very_bad'];
  2016. color2 = color['bad'];
  2017. color3 = color['normal'];
  2018. value1 = (parseFloat(colorStat[type_stat_hover][0])).toFixed(tofixedNum);
  2019. value3 = (parseFloat(colorStat[type_stat_hover][1]) + plusValue).toFixed(tofixedNum);
  2020. }
  2021. if(parseFloat(statValue) <= parseFloat(colorStat[type_stat_hover][0])){
  2022. color1 = color['very_bad'];
  2023. color2 = color['very_bad'];
  2024. color3 = color['bad'];
  2025. value1 = (parseFloat(0)).toFixed(tofixedNum);
  2026. value3 = (parseFloat(colorStat[type_stat_hover][0]) + plusValue).toFixed(tofixedNum);
  2027. }
  2028. var next_percent_wins_html = '';
  2029. if(type_stat_hover == 'wins_percents'){
  2030. var next_percent_losses = Math.floor(100 - MembersArray[0]['info']['statistics']['pvp']['wins_percents']);
  2031. var next_percent_wins = 100 - next_percent_losses;
  2032. var next_losses_rate = next_percent_losses / 100;
  2033. var next_battles = Math.ceil(
  2034. (
  2035. (
  2036. MembersArray[0]['info']['statistics']['pvp']['battles'] - MembersArray[0]['info']['statistics']['pvp']['wins']
  2037. ) / next_losses_rate
  2038. ) - MembersArray[0]['info']['statistics']['pvp']['battles']
  2039. );
  2040. next_percent_wins_html = '<p class="tooltip__text" style="font-size: 14px; color: #FFF;">'+next_battles+' '+localizationText['to']+' '+next_percent_wins+'%</p>';
  2041. }
  2042. $('#tooltip-stat-'+type_stat_hover).html('' +
  2043. '<p class="tooltip__title" style="color: #FFF;">'+localizationText['info.statistics.pvp.'+type_stat_hover]+'</p>' +
  2044. '<p class="tooltip__text" style="font-size: 14px; color: #FFF;">' +
  2045. '<font color="'+color1+'">'+value1+'</font>' +
  2046. ' &lArr; <font color="'+color2+'">'+(statValue).toFixed(tofixedNum)+'</font> &rArr; ' +
  2047. '<font color="'+color3+'">'+value3+'</font>' +
  2048. '</p>' +
  2049. next_percent_wins_html +
  2050. '').css({
  2051. width: offsetWidth+"px", //(offsetWidth - paddingRight - paddingLeft)
  2052. display: "block",
  2053. top: offsetTop + offsetHeight - paddingTop - paddingBottom,
  2054. left: offsetLeft //+ paddingLeft
  2055. }).fadeIn(200);
  2056. }
  2057. function hoverStatOut(){
  2058. var type_stat_hover = $(this).attr('type-stat');
  2059. $('#tooltip-stat-'+type_stat_hover).hide();
  2060. }
  2061. /* ===== UserScript function ===== */
  2062. function getImgNameToShipId(img_name){
  2063. var ShipId = null;
  2064. for(ship_id in Encyclopedia){
  2065. if(!Encyclopedia[ship_id]['name']){continue;}
  2066. if(Encyclopedia[ship_id]['images']['small'].indexOf(img_name) > -1){
  2067. ShipId = ''+ship_id+'';
  2068. break;
  2069. }
  2070. }
  2071. return ShipId;
  2072. }
  2073. function checkJson(){
  2074. var date = new Date();
  2075. var d = date.getDate();
  2076. if(d < 10){d = '0'+d;}
  2077. var m = date.getMonth(); m++;
  2078. if(m < 10){m = '0'+m;}
  2079. var y = date.getFullYear();
  2080. var numJson = y+''+m+''+d;
  2081. if(getLocalStorage('numJson', false) < numJson){
  2082. setLocalStorage('numJson', numJson, false);
  2083. getJson(WoWsStatInfoHref+'get/color.php?'+Math.floor(Math.random()*100000001), doneColorStat, errorColorStat);
  2084. getJson(WoWsStatInfoHref+'get/expships.php?'+Math.floor(Math.random()*100000001), doneExpShips, errorExpShips);
  2085. }else{
  2086. getIndexedDB('ColorStat', updateColorStat, updateColorStat);
  2087. getIndexedDB('ExpShips', updateExpShips, updateExpShips);
  2088. }
  2089. }
  2090. function doneColorStat(url, response){
  2091. setIndexedDB('ColorStat', response, updateColorStat, updateColorStat);
  2092. }
  2093. function errorColorStat(url){}
  2094. function doneExpShips(url, response){
  2095. setIndexedDB('ExpShips', response, updateExpShips, updateExpShips);
  2096. }
  2097. function updateColorStat(response){
  2098. if(response == null){
  2099. colorStat = jQ.parseJSON('{"wws":["500.00","700.00","850.00","1150.00","1450.00","99999.00"],"max_frags_battle":[4,5,6,7,8,99],"avg_planes_killed":["0.21","0.91","1.75","3.73","6.15","99.00"],"max_damage_dealt":[77615,109179,133760,178157,220578,9999999],"wr":["527.48","836.83","1081.29","1524.19","1910.92","99999.00"],"kill_dead":["0.54","0.87","1.17","1.82","2.52","99.00"],"avg_capture_points":["0.00","0.09","0.33","0.95","1.61","99.00"],"survived_battles_percents":["15.97","25.60","33.03","44.90","53.70","100.00"],"max_xp":[1640,2301,2957,4163,5075,99999],"avg_damage_dealt":["14207.06","21050.05","26617.10","37703.95","48563.25","999999.00"],"avg_dropped_capture_points":["0.00","0.50","2.14","5.63","8.39","99.00"],"max_planes_killed":[7,23,35,53,69,999],"avg_xp":["470.63","628.41","774.77","1102.47","1413.55","99999.00"],"avg_frags":["0.44","0.65","0.80","1.07","1.28","99.00"],"wins_percents":["44.81","48.64","51.33","55.83","59.87","100.00"],"battles":[256,517,1040,2699,4571,99999]}');
  2100. }else{
  2101. colorStat = response;
  2102. }
  2103. }
  2104. function updateExpShips(response){
  2105. if(response == null){
  2106. ExpShips = jQ.parseJSON('{"4292818736":{"expDamage":45846.89,"expFrags":0.72,"expPlanesKilled":2.67},"4179539408":{"expDamage":54350.69,"expFrags":0.69,"expPlanesKilled":3.04},"4293834544":{"expDamage":7527.87,"expFrags":0.59,"expPlanesKilled":0.01},"4287542992":{"expDamage":25029.87,"expFrags":0.65,"expPlanesKilled":1.53},"3552491216":{"expDamage":34824.18,"expFrags":0.62,"expPlanesKilled":1.19},"4188976592":{"expDamage":8244.48,"expFrags":0.62,"expPlanesKilled":0.01},"4077795024":{"expDamage":36220.46,"expFrags":1.04,"expPlanesKilled":0.2},"4288558800":{"expDamage":20667.01,"expFrags":0.61,"expPlanesKilled":0.43},"4289607376":{"expDamage":18888.57,"expFrags":0.59,"expPlanesKilled":0.41},"4277057520":{"expDamage":33727.89,"expFrags":0.59,"expPlanesKilled":4.19},"4276041424":{"expDamage":77239.55,"expFrags":0.85,"expPlanesKilled":3.96},"4180588336":{"expDamage":44262.19,"expFrags":0.71,"expPlanesKilled":2.9},"4180555216":{"expDamage":21272.38,"expFrags":0.65,"expPlanesKilled":0.27},"3551442640":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4264441840":{"expDamage":17327.11,"expFrags":0.55,"expPlanesKilled":0.48},"3762173136":{"expDamage":23876.83,"expFrags":0.68,"expPlanesKilled":0.63},"4187928528":{"expDamage":15053.59,"expFrags":0.64,"expPlanesKilled":0.01},"4266538992":{"expDamage":12574.8,"expFrags":0.59,"expPlanesKilled":0.02},"3767449296":{"expDamage":26816.23,"expFrags":1.0,"expPlanesKilled":0.59},"4186912560":{"expDamage":27722.81,"expFrags":0.96,"expPlanesKilled":0.04},"4293867504":{"expDamage":17028.23,"expFrags":0.61,"expPlanesKilled":0.03},"3764336464":{"expDamage":44387.8,"expFrags":0.87,"expPlanesKilled":1.83},"4184815408":{"expDamage":40207.76,"expFrags":0.92,"expPlanesKilled":1.42},"4075697872":{"expDamage":30548.77,"expFrags":0.71,"expPlanesKilled":0.15},"4182685648":{"expDamage":47774.04,"expFrags":1.17,"expPlanesKilled":1.62},"3764303216":{"expDamage":29204.01,"expFrags":0.77,"expPlanesKilled":0.77},"4183734064":{"expDamage":23366.85,"expFrags":0.65,"expPlanesKilled":0.69},"4290655952":{"expDamage":24435.88,"expFrags":0.88,"expPlanesKilled":0.1},"4291737040":{"expDamage":28218.22,"expFrags":0.84,"expPlanesKilled":1.15},"4078843600":{"expDamage":19374.34,"expFrags":0.63,"expPlanesKilled":0.3},"3767416784":{"expDamage":19125.34,"expFrags":0.82,"expPlanesKilled":0.03},"3763255280":{"expDamage":29263.89,"expFrags":0.67,"expPlanesKilled":2.53},"4182685136":{"expDamage":32155.81,"expFrags":0.75,"expPlanesKilled":1.05},"4277122768":{"expDamage":86816.17,"expFrags":1.22,"expPlanesKilled":20.7},"3764303312":{"expDamage":32009.83,"expFrags":0.77,"expPlanesKilled":1.23},"4183701200":{"expDamage":17935.99,"expFrags":0.54,"expPlanesKilled":0.26},"4179539920":{"expDamage":74968.06,"expFrags":1.29,"expPlanesKilled":7.08},"4286527184":{"expDamage":26585.86,"expFrags":0.78,"expPlanesKilled":0.17},"3768465392":{"expDamage":12452.8,"expFrags":0.82,"expPlanesKilled":0.01},"4259231440":{"expDamage":69836.84,"expFrags":0.95,"expPlanesKilled":3.51},"4184782800":{"expDamage":20177.75,"expFrags":0.61,"expPlanesKilled":0.38},"3768497968":{"expDamage":15713.83,"expFrags":0.88,"expPlanesKilled":0.01},"4180588496":{"expDamage":60564.64,"expFrags":1.11,"expPlanesKilled":5.53},"4293866960":{"expDamage":35981.47,"expFrags":1.06,"expPlanesKilled":0.04},"4076746448":{"expDamage":26178.75,"expFrags":0.65,"expPlanesKilled":0.13},"4293834736":{"expDamage":8823.65,"expFrags":0.59,"expPlanesKilled":0.01},"4289640144":{"expDamage":19028.87,"expFrags":0.55,"expPlanesKilled":0.35},"4267620048":{"expDamage":27314.07,"expFrags":1.02,"expPlanesKilled":0.88},"4288657392":{"expDamage":28691.76,"expFrags":0.54,"expPlanesKilled":12.76},"4280170480":{"expDamage":17939.83,"expFrags":0.68,"expPlanesKilled":0.37},"4286461936":{"expDamage":27638.99,"expFrags":0.8,"expPlanesKilled":0.53},"4259264496":{"expDamage":35709.72,"expFrags":0.8,"expPlanesKilled":0.96},"4256085712":{"expDamage":10241.44,"expFrags":0.75,"expPlanesKilled":0.01},"4268635856":{"expDamage":35617.79,"expFrags":1.17,"expPlanesKilled":0.01},"4185863984":{"expDamage":35538.75,"expFrags":0.93,"expPlanesKilled":1.13},"4181604048":{"expDamage":35339.28,"expFrags":0.85,"expPlanesKilled":1.52},"4182652368":{"expDamage":32411.16,"expFrags":0.74,"expPlanesKilled":0.59},"4248745968":{"expDamage":39128.92,"expFrags":1.3,"expPlanesKilled":0.26},"4258182864":{"expDamage":12513.69,"expFrags":0.58,"expPlanesKilled":0.01},"4280170192":{"expDamage":16617.05,"expFrags":1.06,"expPlanesKilled":0.01},"4185831216":{"expDamage":14712.11,"expFrags":0.5,"expPlanesKilled":0.05},"3554621136":{"expDamage":37498.99,"expFrags":0.87,"expPlanesKilled":1.5},"3763255248":{"expDamage":40936.08,"expFrags":0.96,"expPlanesKilled":2.25},"3763287856":{"expDamage":51698.75,"expFrags":1.02,"expPlanesKilled":3.14},"4291737584":{"expDamage":12849.35,"expFrags":0.72,"expPlanesKilled":0.01},"4180621104":{"expDamage":63810.81,"expFrags":0.87,"expPlanesKilled":3.55},"4286527472":{"expDamage":41574.93,"expFrags":0.76,"expPlanesKilled":1.42},"4292818896":{"expDamage":36515.83,"expFrags":0.8,"expPlanesKilled":1.59},"4282267344":{"expDamage":41318.57,"expFrags":0.78,"expPlanesKilled":0.31},"3764336624":{"expDamage":46427.42,"expFrags":0.96,"expPlanesKilled":1.17},"4181636912":{"expDamage":31128.71,"expFrags":0.59,"expPlanesKilled":2.28},"4185830864":{"expDamage":17669.92,"expFrags":0.58,"expPlanesKilled":0.09},"4280203248":{"expDamage":29199.11,"expFrags":0.57,"expPlanesKilled":2.64},"4293801680":{"expDamage":16617.05,"expFrags":1.06,"expPlanesKilled":0.01},"4247697392":{"expDamage":39128.92,"expFrags":1.3,"expPlanesKilled":0.26},"4285445840":{"expDamage":34824.18,"expFrags":0.62,"expPlanesKilled":1.19},"4279154384":{"expDamage":16073.65,"expFrags":0.64,"expPlanesKilled":0.03},"4293867216":{"expDamage":17957.87,"expFrags":0.7,"expPlanesKilled":0.06},"4283381456":{"expDamage":12589.81,"expFrags":0.7,"expPlanesKilled":0.01},"4290754544":{"expDamage":21055.63,"expFrags":0.45,"expPlanesKilled":9.32},"4286494416":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4282365648":{"expDamage":51604.26,"expFrags":0.86,"expPlanesKilled":15.22},"4288624624":{"expDamage":26419.93,"expFrags":0.64,"expPlanesKilled":0.64},"4291704528":{"expDamage":20757.98,"expFrags":0.81,"expPlanesKilled":0.08},"4182718256":{"expDamage":51037.04,"expFrags":0.95,"expPlanesKilled":3.83},"4282300400":{"expDamage":25295.92,"expFrags":0.58,"expPlanesKilled":2.03},"4183700944":{"expDamage":15877.67,"expFrags":0.56,"expPlanesKilled":0.18},"4272830448":{"expDamage":32608.92,"expFrags":0.82,"expPlanesKilled":0.98},"4269684432":{"expDamage":14806.5,"expFrags":0.67,"expPlanesKilled":0.03},"4184749776":{"expDamage":18733.89,"expFrags":0.59,"expPlanesKilled":0.4},"4290689008":{"expDamage":18571.31,"expFrags":0.71,"expPlanesKilled":0.01},"4293834192":{"expDamage":19572.89,"expFrags":0.78,"expPlanesKilled":0.04},"3553539792":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4292786160":{"expDamage":10102.59,"expFrags":0.47,"expPlanesKilled":0.01},"4284430032":{"expDamage":42830.3,"expFrags":0.75,"expPlanesKilled":1.22},"4288559088":{"expDamage":20310.32,"expFrags":0.67,"expPlanesKilled":0.25},"4185831376":{"expDamage":19670.7,"expFrags":0.71,"expPlanesKilled":0.3},"4279220208":{"expDamage":85950.95,"expFrags":1.16,"expPlanesKilled":24.96},"4288624336":{"expDamage":39506.91,"expFrags":0.85,"expPlanesKilled":0.9},"3762206512":{"expDamage":32205.65,"expFrags":0.59,"expPlanesKilled":2.77},"4282365936":{"expDamage":54414.95,"expFrags":0.89,"expPlanesKilled":15.09},"4289607664":{"expDamage":18225.46,"expFrags":0.66,"expPlanesKilled":0.37},"4281284304":{"expDamage":52935.08,"expFrags":0.84,"expPlanesKilled":2.51},"4285511376":{"expDamage":37687.86,"expFrags":0.76,"expPlanesKilled":9.88},"4182652624":{"expDamage":22842.2,"expFrags":0.64,"expPlanesKilled":0.1},"3553572560":{"expDamage":37498.99,"expFrags":0.87,"expPlanesKilled":1.5},"4293801424":{"expDamage":22704.99,"expFrags":0.81,"expPlanesKilled":0.34},"4274927600":{"expDamage":17609.08,"expFrags":0.73,"expPlanesKilled":0.03},"4288657104":{"expDamage":39217.06,"expFrags":0.87,"expPlanesKilled":7.76},"4292753392":{"expDamage":9437.7,"expFrags":0.56,"expPlanesKilled":0.01},"4180587984":{"expDamage":44589.33,"expFrags":0.72,"expPlanesKilled":3.02},"3522082512":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4273911792":{"expDamage":54868.69,"expFrags":0.87,"expPlanesKilled":5.51},"4183734224":{"expDamage":34042.99,"expFrags":0.92,"expPlanesKilled":1.12},"4276041712":{"expDamage":56386.22,"expFrags":0.77,"expPlanesKilled":4.71},"4179506640":{"expDamage":45401.88,"expFrags":0.83,"expPlanesKilled":1.06},"4181636560":{"expDamage":33455.4,"expFrags":0.66,"expPlanesKilled":2.03},"4284397008":{"expDamage":20031.99,"expFrags":0.98,"expPlanesKilled":0.01},"4282333168":{"expDamage":50300.25,"expFrags":0.79,"expPlanesKilled":4.36},"4186879440":{"expDamage":18999.18,"expFrags":0.73,"expPlanesKilled":0.01},"4186846672":{"expDamage":10610.52,"expFrags":0.54,"expPlanesKilled":0.01},"4292753104":{"expDamage":11523.09,"expFrags":0.67,"expPlanesKilled":0.01},"4277024464":{"expDamage":35617.79,"expFrags":1.17,"expPlanesKilled":0.01},"4269717488":{"expDamage":17143.86,"expFrags":0.53,"expPlanesKilled":0.14},"4292851408":{"expDamage":33893.35,"expFrags":0.8,"expPlanesKilled":6.53},"3532568272":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4186879792":{"expDamage":13964.59,"expFrags":0.59,"expPlanesKilled":0.01},"4184782640":{"expDamage":23985.69,"expFrags":0.72,"expPlanesKilled":0.33},"4292785616":{"expDamage":20031.99,"expFrags":0.98,"expPlanesKilled":0.01},"4283414224":{"expDamage":46724.74,"expFrags":0.88,"expPlanesKilled":15.05},"4281284592":{"expDamage":27729.72,"expFrags":0.8,"expPlanesKilled":0.01},"4188977104":{"expDamage":4997.58,"expFrags":0.72,"expPlanesKilled":0.01},"3555669712":{"expDamage":37498.99,"expFrags":0.87,"expPlanesKilled":1.5},"4267587280":{"expDamage":35617.79,"expFrags":1.17,"expPlanesKilled":0.01},"4284463088":{"expDamage":42711.13,"expFrags":0.76,"expPlanesKilled":15.32},"4277090288":{"expDamage":69354.56,"expFrags":0.85,"expPlanesKilled":5.0},"4288591856":{"expDamage":23240.96,"expFrags":0.69,"expPlanesKilled":3.4},"4183733712":{"expDamage":27844.52,"expFrags":0.73,"expPlanesKilled":1.01},"3763221968":{"expDamage":27362.67,"expFrags":0.76,"expPlanesKilled":0.21},"3767482160":{"expDamage":37073.93,"expFrags":1.17,"expPlanesKilled":0.1},"4287543280":{"expDamage":27100.64,"expFrags":0.77,"expPlanesKilled":2.96},"3769513264":{"expDamage":25577.8,"expFrags":0.77,"expPlanesKilled":0.17},"4181669680":{"expDamage":61285.44,"expFrags":0.96,"expPlanesKilled":3.34},"4290721776":{"expDamage":25879.61,"expFrags":0.73,"expPlanesKilled":0.56},"3543054032":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"4255037136":{"expDamage":30932.16,"expFrags":0.61,"expPlanesKilled":1.65},"3555636944":{"expDamage":32336.84,"expFrags":0.75,"expPlanesKilled":2.3},"3554555600":{"expDamage":55238.54,"expFrags":1.84,"expPlanesKilled":0.01},"4181637072":{"expDamage":48603.67,"expFrags":1.0,"expPlanesKilled":2.57},"4179539760":{"expDamage":58730.5,"expFrags":0.82,"expPlanesKilled":4.25},"3764270288":{"expDamage":23093.46,"expFrags":0.77,"expPlanesKilled":0.35},"4287510224":{"expDamage":25175.0,"expFrags":0.64,"expPlanesKilled":0.3},"4185798096":{"expDamage":12544.22,"expFrags":0.51,"expPlanesKilled":0.07},"4186879952":{"expDamage":17815.87,"expFrags":0.71,"expPlanesKilled":0.07},"4291770064":{"expDamage":20655.92,"expFrags":0.54,"expPlanesKilled":0.52},"3552523984":{"expDamage":37498.99,"expFrags":0.87,"expPlanesKilled":1.5},"3553540080":{"expDamage":54045.13,"expFrags":1.41,"expPlanesKilled":5.72},"4281219056":{"expDamage":43219.95,"expFrags":0.89,"expPlanesKilled":1.09},"4281317360":{"expDamage":71827.4,"expFrags":1.1,"expPlanesKilled":19.47},"4184782288":{"expDamage":20998.36,"expFrags":0.56,"expPlanesKilled":0.81},"3763320816":{"expDamage":45726.47,"expFrags":0.85,"expPlanesKilled":22.61},"4187895248":{"expDamage":8216.25,"expFrags":0.55,"expPlanesKilled":0.01},"3762206160":{"expDamage":33441.22,"expFrags":0.69,"expPlanesKilled":3.89},"4183766832":{"expDamage":43191.14,"expFrags":0.86,"expPlanesKilled":1.73},"4179572528":{"expDamage":85899.78,"expFrags":1.06,"expPlanesKilled":4.36},"4292851696":{"expDamage":22309.14,"expFrags":0.44,"expPlanesKilled":12.84},"4184749520":{"expDamage":15193.24,"expFrags":0.58,"expPlanesKilled":0.18},"4282300112":{"expDamage":41537.15,"expFrags":0.69,"expPlanesKilled":2.88},"4187928016":{"expDamage":12020.5,"expFrags":0.63,"expPlanesKilled":0.01},"4182685488":{"expDamage":25665.96,"expFrags":0.61,"expPlanesKilled":1.29},"4289640432":{"expDamage":24294.3,"expFrags":0.74,"expPlanesKilled":0.93},"4272895696":{"expDamage":54552.6,"expFrags":0.73,"expPlanesKilled":2.7},"4279219920":{"expDamage":73411.52,"expFrags":1.15,"expPlanesKilled":18.33},"4290688720":{"expDamage":19824.16,"expFrags":0.69,"expPlanesKilled":1.76},"4181603792":{"expDamage":21518.15,"expFrags":0.58,"expPlanesKilled":0.35},"3555670000":{"expDamage":35975.51,"expFrags":0.79,"expPlanesKilled":3.44},"4292785968":{"expDamage":13425.28,"expFrags":0.78,"expPlanesKilled":0.01},"4284364496":{"expDamage":30523.45,"expFrags":0.67,"expPlanesKilled":0.15},"4287575760":{"expDamage":37498.99,"expFrags":0.87,"expPlanesKilled":1.5},"3765351888":{"expDamage":25669.52,"expFrags":0.75,"expPlanesKilled":1.09},"4281251536":{"expDamage":21943.27,"expFrags":0.72,"expPlanesKilled":0.26}}');
  2107. }else{
  2108. ExpShips = response;
  2109. }
  2110. }
  2111. function errorExpShips(url){}
  2112. function doneAccountInfo(url, response){
  2113. if(response.status && response.status == 'error'){
  2114. errorAccountInfo(url);
  2115. return;
  2116. }
  2117. var vars = getUrlVars(url);
  2118. var account_id = vars['account_id'];
  2119. var index = vars['index'];
  2120. var type = vars['type'];
  2121. MembersArray[index]['info'] = response['data'][account_id];
  2122. getJson(WOWSAPI+'ships/stats/?application_id='+application_id+'&extra=pve,pvp_solo,pvp_div2,pvp_div3&account_id='+account_id+'&index='+index+'&type='+type, doneShipsStats, errorShipsStats);
  2123. }
  2124. function errorAccountInfo(url){
  2125. var vars = getUrlVars(url);
  2126. var account_id = vars['account_id'];
  2127. var index = vars['index'];
  2128. var type = vars['type'];
  2129. console.log('Error AccountInfo '+account_id);
  2130. if(type == 'profile'){
  2131. onShowMessage(
  2132. localizationText['Box'],
  2133. localizationText['ErrorAPI'],
  2134. onCloseMessage,
  2135. localizationText['Ok'],
  2136. false
  2137. );
  2138. }else if(type == 'clan'){
  2139. getJson(WOWSAPI+'ships/stats/?application_id='+application_id+'&extra=pve,pvp_solo,pvp_div2,pvp_div3&account_id='+account_id+'&index='+index+'&type='+type, doneShipsStats, errorShipsStats);
  2140. }
  2141. }
  2142. function doneShipsStats(url, response){
  2143. if(response.status && response.status == 'error'){
  2144. errorShipsStats(url);
  2145. return;
  2146. }
  2147. var vars = getUrlVars(url);
  2148. var account_id = vars['account_id'];
  2149. var index = vars['index'];
  2150. var type = vars['type'];
  2151. MembersArray[index]['ships'] = response['data'][account_id];
  2152. getJson(WOWSAPI+'account/achievements/?application_id='+application_id+'&account_id='+account_id+'&index='+index+'&type='+type, doneAchievements, errorAchievements);
  2153. }
  2154. function errorShipsStats(url){
  2155. var vars = getUrlVars(url);
  2156. var account_id = vars['account_id'];
  2157. var index = vars['index'];
  2158. var type = vars['type'];
  2159. console.log('Error ShipsStats '+account_id);
  2160. if(type == 'profile'){
  2161. onShowMessage(
  2162. localizationText['Box'],
  2163. localizationText['ErrorAPI'],
  2164. onCloseMessage,
  2165. localizationText['Ok'],
  2166. false
  2167. );
  2168. }
  2169. }
  2170. function doneAchievements(url, response){
  2171. if(response.status && response.status == 'error'){
  2172. errorAchievements(url);
  2173. return;
  2174. }
  2175. var vars = getUrlVars(url);
  2176. var account_id = vars['account_id'];
  2177. var index = vars['index'];
  2178. var type = vars['type'];
  2179. MembersArray[index]['achievements'] = response['data'][account_id];
  2180. getJson(WOWSAPI+'account/statsbydate/?application_id='+application_id+'&account_id='+account_id+'&index='+index+'&type='+type+'&dates='+getDatesList(), doneStatsbydate, errorStatsbydate);
  2181. }
  2182. function errorAchievements(url){
  2183. var vars = getUrlVars(url);
  2184. var account_id = vars['account_id'];
  2185. var index = vars['index'];
  2186. var type = vars['type'];
  2187. console.log('Error Achievements '+account_id);
  2188. if(type == 'profile'){
  2189. onShowMessage(
  2190. localizationText['Box'],
  2191. localizationText['ErrorAPI'],
  2192. onCloseMessage,
  2193. localizationText['Ok'],
  2194. false
  2195. );
  2196. }
  2197. }
  2198. function doneStatsbydate(url, response){
  2199. if(response.status && response.status == 'error'){
  2200. errorStatsbydate(url);
  2201. return;
  2202. }
  2203. var vars = getUrlVars(url);
  2204. var account_id = vars['account_id'];
  2205. var index = vars['index'];
  2206. var type = vars['type'];
  2207. MembersArray[index]['statsbydate'] = response['data'][account_id];
  2208. if(type == 'profile'){
  2209. viewMainPageProfile();
  2210. }
  2211. }
  2212. function errorStatsbydate(url){
  2213. var vars = getUrlVars(url);
  2214. var account_id = vars['account_id'];
  2215. var index = vars['index'];
  2216. var type = vars['type'];
  2217. console.log('Error Statsbydate '+account_id);
  2218. if(type == 'profile'){
  2219. onShowMessage(
  2220. localizationText['Box'],
  2221. localizationText['ErrorAPI'],
  2222. onCloseMessage,
  2223. localizationText['Ok'],
  2224. false
  2225. );
  2226. }
  2227. }
  2228. function getDatesList(){
  2229. var DatesList = '';
  2230. var today = new Date();
  2231. for(var i = 1; i <= 10; i++){
  2232. today.setDate(today.getDate() - 1);
  2233. var day = today.getDate();
  2234. var d = ''; if(day < 10){d = '0'+day+'';}else{d = ''+day+'';}
  2235. var month = today.getMonth() + 1;
  2236. var m = ''; if(month < 10){m = '0'+month+'';}else{m = ''+month+'';}
  2237. var year = today.getFullYear();
  2238. var y = ''+year+'';
  2239. DatesList += y+''+m+''+d+',';
  2240. }
  2241. return DatesList;
  2242. }
  2243. function calcStat(index){
  2244. if(MembersArray[index]['info'] == null || MembersArray[index]['ships'] == null){
  2245. MembersArray[index]['info'] = [];
  2246. MembersArray[index]['info']['last_battle_time'] = 0;
  2247. MembersArray[index]['info']['logout_at'] = 0;
  2248. MembersArray[index]['info']['ships_x_level'] = 0;
  2249. MembersArray[index]['info']['statistics'] = [];
  2250. MembersArray[index]['info']['statistics']['pvp'] = [];
  2251. MembersArray[index]['info']['statistics']['pvp']['battles'] = 0;
  2252. MembersArray[index]['info']['statistics']['pvp']['wins'] = 0;
  2253. MembersArray[index]['info']['statistics']['pvp']['losses'] = 0;
  2254. MembersArray[index]['info']['statistics']['pvp']['draws'] = 0;
  2255. MembersArray[index]['info']['statistics']['pvp']['survived_battles'] = 0;
  2256. MembersArray[index]['info']['statistics']['pvp']['survived_wins'] = 0;
  2257. MembersArray[index]['info']['statistics']['pvp']['kill_dead'] = 0;
  2258. MembersArray[index]['info']['statistics']['pvp']['xp'] = 0;
  2259. MembersArray[index]['info']['statistics']['pvp']['damage_dealt'] = 0;
  2260. MembersArray[index]['info']['statistics']['pvp']['frags'] = 0;
  2261. MembersArray[index]['info']['statistics']['pvp']['planes_killed'] = 0;
  2262. MembersArray[index]['info']['statistics']['pvp']['capture_points'] = 0;
  2263. MembersArray[index]['info']['statistics']['pvp']['dropped_capture_points'] = 0;
  2264. MembersArray[index]['info']['statistics']['pvp']['avg_xp'] = 0;
  2265. MembersArray[index]['info']['statistics']['pvp']['avg_damage_dealt'] = 0;
  2266. MembersArray[index]['info']['statistics']['pvp']['avg_frags'] = 0;
  2267. MembersArray[index]['info']['statistics']['pvp']['avg_planes_killed'] = 0;
  2268. MembersArray[index]['info']['statistics']['pvp']['avg_capture_points'] = 0;
  2269. MembersArray[index]['info']['statistics']['pvp']['avg_dropped_capture_points'] = 0;
  2270. MembersArray[index]['info']['statistics']['pvp']['max_xp'] = 0;
  2271. MembersArray[index]['info']['statistics']['pvp']['max_damage_dealt'] = 0;
  2272. MembersArray[index]['info']['statistics']['pvp']['max_frags_battle'] = 0;
  2273. MembersArray[index]['info']['statistics']['pvp']['max_planes_killed'] = 0;
  2274. MembersArray[index]['info']['statistics']['pvp']['wins_percents'] = 0;
  2275. MembersArray[index]['info']['statistics']['pvp']['survived_battles_percents'] = 0;
  2276. MembersArray[index]['info']['statistics']['pvp']['wr'] = 0;
  2277. MembersArray[index]['info']['statistics']['pvp']['avg_battles_level'] = 0;
  2278. MembersArray[index]['info']['statistics']['pvp']['max_ship_level'] = 0;
  2279. return false;
  2280. }
  2281. for(var t = 0; t < typeStat.length; t++){
  2282. var type = typeStat[t];
  2283. if(type == 'pvp_div' && MembersArray[index]['info']['statistics']['pvp_div'] == undefined){
  2284. MembersArray[index]['info']['statistics']['pvp_div'] = [];
  2285. if(MembersArray[index]['info']['statistics']['pvp_div2']['max_xp'] > MembersArray[index]['info']['statistics']['pvp_div3']['max_xp']){
  2286. MembersArray[index]['info']['statistics']['pvp_div']['max_xp'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_xp'];
  2287. MembersArray[index]['info']['statistics']['pvp_div']['max_xp_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_xp_ship_id'];
  2288. }else{
  2289. MembersArray[index]['info']['statistics']['pvp_div']['max_xp'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_xp'];
  2290. MembersArray[index]['info']['statistics']['pvp_div']['max_xp_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_xp_ship_id'];
  2291. }
  2292. if(MembersArray[index]['info']['statistics']['pvp_div2']['max_frags_battle'] > MembersArray[index]['info']['statistics']['pvp_div3']['max_frags_battle']){
  2293. MembersArray[index]['info']['statistics']['pvp_div']['max_frags_battle'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_frags_battle'];
  2294. MembersArray[index]['info']['statistics']['pvp_div']['max_frags_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_frags_ship_id'];
  2295. }else{
  2296. MembersArray[index]['info']['statistics']['pvp_div']['max_frags_battle'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_frags_battle'];
  2297. MembersArray[index]['info']['statistics']['pvp_div']['max_frags_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_frags_ship_id'];
  2298. }
  2299. if(MembersArray[index]['info']['statistics']['pvp_div2']['max_planes_killed'] > MembersArray[index]['info']['statistics']['pvp_div3']['max_planes_killed']){
  2300. MembersArray[index]['info']['statistics']['pvp_div']['max_planes_killed'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_planes_killed'];
  2301. MembersArray[index]['info']['statistics']['pvp_div']['max_planes_killed_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_planes_killed_ship_id'];
  2302. }else{
  2303. MembersArray[index]['info']['statistics']['pvp_div']['max_planes_killed'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_planes_killed'];
  2304. MembersArray[index]['info']['statistics']['pvp_div']['max_planes_killed_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_planes_killed_ship_id'];
  2305. }
  2306. if(MembersArray[index]['info']['statistics']['pvp_div2']['max_damage_dealt'] > MembersArray[index]['info']['statistics']['pvp_div3']['max_damage_dealt']){
  2307. MembersArray[index]['info']['statistics']['pvp_div']['max_damage_dealt'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_damage_dealt'];
  2308. MembersArray[index]['info']['statistics']['pvp_div']['max_damage_dealt_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_damage_dealt_ship_id'];
  2309. }else{
  2310. MembersArray[index]['info']['statistics']['pvp_div']['max_damage_dealt'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_damage_dealt'];
  2311. MembersArray[index]['info']['statistics']['pvp_div']['max_damage_dealt_ship_id'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_damage_dealt_ship_id'];
  2312. }
  2313. MembersArray[index]['info']['statistics']['pvp_div']['xp'] = MembersArray[index]['info']['statistics']['pvp_div2']['xp'] + MembersArray[index]['info']['statistics']['pvp_div3']['xp'];
  2314. MembersArray[index]['info']['statistics']['pvp_div']['survived_battles'] = MembersArray[index]['info']['statistics']['pvp_div2']['survived_battles'] + MembersArray[index]['info']['statistics']['pvp_div3']['survived_battles'];
  2315. MembersArray[index]['info']['statistics']['pvp_div']['dropped_capture_points'] = MembersArray[index]['info']['statistics']['pvp_div2']['dropped_capture_points'] + MembersArray[index]['info']['statistics']['pvp_div3']['dropped_capture_points'];
  2316. MembersArray[index]['info']['statistics']['pvp_div']['draws'] = MembersArray[index]['info']['statistics']['pvp_div2']['draws'] + MembersArray[index]['info']['statistics']['pvp_div3']['draws'];
  2317. MembersArray[index]['info']['statistics']['pvp_div']['wins'] = MembersArray[index]['info']['statistics']['pvp_div2']['wins'] + MembersArray[index]['info']['statistics']['pvp_div3']['wins'];
  2318. MembersArray[index]['info']['statistics']['pvp_div']['damage_dealt'] = MembersArray[index]['info']['statistics']['pvp_div2']['damage_dealt'] + MembersArray[index]['info']['statistics']['pvp_div3']['damage_dealt'];
  2319. MembersArray[index]['info']['statistics']['pvp_div']['losses'] = MembersArray[index]['info']['statistics']['pvp_div2']['losses'] + MembersArray[index]['info']['statistics']['pvp_div3']['losses'];
  2320. MembersArray[index]['info']['statistics']['pvp_div']['frags'] = MembersArray[index]['info']['statistics']['pvp_div2']['frags'] + MembersArray[index]['info']['statistics']['pvp_div3']['frags'];
  2321. MembersArray[index]['info']['statistics']['pvp_div']['capture_points'] = MembersArray[index]['info']['statistics']['pvp_div2']['capture_points'] + MembersArray[index]['info']['statistics']['pvp_div3']['capture_points'];
  2322. MembersArray[index]['info']['statistics']['pvp_div']['survived_wins'] = MembersArray[index]['info']['statistics']['pvp_div2']['survived_wins'] + MembersArray[index]['info']['statistics']['pvp_div3']['survived_wins'];
  2323. MembersArray[index]['info']['statistics']['pvp_div']['battles'] = MembersArray[index]['info']['statistics']['pvp_div2']['battles'] + MembersArray[index]['info']['statistics']['pvp_div3']['battles'];
  2324. MembersArray[index]['info']['statistics']['pvp_div']['planes_killed'] = MembersArray[index]['info']['statistics']['pvp_div2']['planes_killed'] + MembersArray[index]['info']['statistics']['pvp_div3']['planes_killed'];
  2325. }
  2326. var Statistics = MembersArray[index]['info']['statistics'][type];
  2327. var timestamp = Math.round(+new Date()/1000);
  2328. var created_at = MembersArray[index]['info']['created_at'];
  2329. var days = (timestamp - created_at)/60/60/24;
  2330. var battles_days = Statistics['battles'] / days;
  2331. MembersArray[index]['info']['statistics'][type]['battles_days'] = battles_days;
  2332. MembersArray[index]['info']['statistics'][type]['avg_xp'] = Statistics['xp'] / Statistics['battles'];
  2333. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_xp'])){MembersArray[index]['info']['statistics'][type]['avg_xp'] = 0;}
  2334. MembersArray[index]['info']['statistics'][type]['avg_damage_dealt'] = Statistics['damage_dealt'] / Statistics['battles'];
  2335. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_damage_dealt'])){MembersArray[index]['info']['statistics'][type]['avg_damage_dealt'] = 0;}
  2336. MembersArray[index]['info']['statistics'][type]['avg_frags'] = Statistics['frags'] / Statistics['battles'];
  2337. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_frags'])){MembersArray[index]['info']['statistics'][type]['avg_frags'] = 0;}
  2338. MembersArray[index]['info']['statistics'][type]['avg_planes_killed'] = Statistics['planes_killed'] / Statistics['battles'];
  2339. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_planes_killed'])){MembersArray[index]['info']['statistics'][type]['avg_planes_killed'] = 0;}
  2340. MembersArray[index]['info']['statistics'][type]['avg_capture_points'] = Statistics['capture_points'] / Statistics['battles'];
  2341. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_capture_points'])){MembersArray[index]['info']['statistics'][type]['avg_capture_points'] = 0;}
  2342. MembersArray[index]['info']['statistics'][type]['avg_dropped_capture_points'] = Statistics['dropped_capture_points'] / Statistics['battles'];
  2343. if(isNaN(MembersArray[index]['info']['statistics'][type]['avg_dropped_capture_points'])){MembersArray[index]['info']['statistics'][type]['avg_dropped_capture_points'] = 0;}
  2344. MembersArray[index]['info']['statistics'][type]['wins_percents'] = (Statistics['wins']/Statistics['battles'])*100;
  2345. if(isNaN(MembersArray[index]['info']['statistics'][type]['wins_percents'])){MembersArray[index]['info']['statistics'][type]['wins_percents'] = 0;}
  2346. MembersArray[index]['info']['statistics'][type]['survived_battles_percents'] = (Statistics['survived_battles']/Statistics['battles'])*100;
  2347. if(isNaN(MembersArray[index]['info']['statistics'][type]['survived_battles_percents'])){MembersArray[index]['info']['statistics'][type]['survived_battles_percents'] = 0;}
  2348. if(Statistics['battles'] == Statistics['survived_battles']){
  2349. MembersArray[index]['info']['statistics'][type]['kill_dead'] = Statistics['frags']/Statistics['battles'];
  2350. }else{
  2351. MembersArray[index]['info']['statistics'][type]['kill_dead'] = Statistics['frags']/(Statistics['battles']-Statistics['survived_battles']);
  2352. }
  2353. if(isNaN(MembersArray[index]['info']['statistics'][type]['kill_dead'])){MembersArray[index]['info']['statistics'][type]['kill_dead'] = 0;}
  2354. if(type != 'pvp' && type != 'pve'){
  2355. var type_start = type.split('_')[0];
  2356. MembersArray[index]['info']['statistics'][type]['battles_percents'] = (Statistics['battles']/MembersArray[index]['info']['statistics'][type_start]['battles'])*100;
  2357. if(isNaN(MembersArray[index]['info']['statistics'][type]['battles_percents'])){MembersArray[index]['info']['statistics'][type]['battles_percents'] = 0;}
  2358. }
  2359. }
  2360. MembersArray[index]['info']['ships_x_level'] = 0;
  2361. MembersArray[index]['info']['statistics']['pvp_div']['avg_battles_level'] = 0;
  2362. MembersArray[index]['info']['statistics']['pvp_div']['max_ship_level'] = 0;
  2363. for(var t = 0; t < typeStat.length; t++){
  2364. var type = typeStat[t];
  2365. MembersArray[index]['info']['statistics'][type]['avg_battles_level'] = 0;
  2366. MembersArray[index]['info']['statistics'][type]['max_ship_level'] = 0;
  2367. MembersArray[index]['info']['statistics'][type]['wr'] = 0;
  2368. var StatShips = [];
  2369. StatShips['damage_dealt'] = 0;
  2370. StatShips['frags'] = 0;
  2371. StatShips['planes_killed'] = 0;
  2372. StatShips['expDamage'] = 0;
  2373. StatShips['expFrags'] = 0;
  2374. StatShips['expPlanesKilled'] = 0;
  2375. StatShips['actual.wins'] = 0;
  2376. StatShips['actual.damage_dealt'] = 0;
  2377. StatShips['actual.frags'] = 0;
  2378. StatShips['actual.planes_killed'] = 0;
  2379. StatShips['actual.capture_points'] = 0;
  2380. StatShips['actual.dropped_capture_points'] = 0;
  2381. StatShips['expected.wins'] = 0;
  2382. StatShips['expected.damage_dealt'] = 0;
  2383. StatShips['expected.frags'] = 0;
  2384. StatShips['expected.planes_killed'] = 0;
  2385. StatShips['expected.capture_points'] = 0;
  2386. StatShips['expected.dropped_capture_points'] = 0;
  2387. var StatShipsClass = [];
  2388. for(var tS = 0; tS < typeShip.length; tS++){
  2389. var typeS = typeShip[tS];
  2390. StatShipsClass[typeS] = [];
  2391. StatShipsClass[typeS]['damage_dealt'] = 0;
  2392. StatShipsClass[typeS]['frags'] = 0;
  2393. StatShipsClass[typeS]['planes_killed'] = 0;
  2394. StatShipsClass[typeS]['expDamage'] = 0;
  2395. StatShipsClass[typeS]['expFrags'] = 0;
  2396. StatShipsClass[typeS]['expPlanesKilled'] = 0;
  2397. StatShipsClass[typeS]['actual.wins'] = 0;
  2398. StatShipsClass[typeS]['actual.damage_dealt'] = 0;
  2399. StatShipsClass[typeS]['actual.frags'] = 0;
  2400. StatShipsClass[typeS]['actual.planes_killed'] = 0;
  2401. StatShipsClass[typeS]['actual.capture_points'] = 0;
  2402. StatShipsClass[typeS]['actual.dropped_capture_points'] = 0;
  2403. StatShipsClass[typeS]['expected.wins'] = 0;
  2404. StatShipsClass[typeS]['expected.damage_dealt'] = 0;
  2405. StatShipsClass[typeS]['expected.frags'] = 0;
  2406. StatShipsClass[typeS]['expected.planes_killed'] = 0;
  2407. StatShipsClass[typeS]['expected.capture_points'] = 0;
  2408. StatShipsClass[typeS]['expected.dropped_capture_points'] = 0;
  2409. }
  2410. for(var shipI = 0; shipI < MembersArray[index]['ships'].length; shipI++){
  2411. if(type == 'pvp_div' && MembersArray[index]['ships'][shipI]['pvp_div'] == undefined){
  2412. MembersArray[index]['ships'][shipI]['pvp_div'] = [];
  2413. if(MembersArray[index]['ships'][shipI]['pvp_div2']['max_xp'] > MembersArray[index]['ships'][shipI]['pvp_div3']['max_xp']){
  2414. MembersArray[index]['ships'][shipI]['pvp_div']['max_xp'] = MembersArray[index]['ships'][shipI]['pvp_div2']['max_xp'];
  2415. }else{
  2416. MembersArray[index]['ships'][shipI]['pvp_div']['max_xp'] = MembersArray[index]['ships'][shipI]['pvp_div3']['max_xp'];
  2417. }
  2418. if(MembersArray[index]['ships'][shipI]['pvp_div2']['max_frags_battle'] > MembersArray[index]['ships'][shipI]['pvp_div3']['max_frags_battle']){
  2419. MembersArray[index]['ships'][shipI]['pvp_div']['max_frags_battle'] = MembersArray[index]['ships'][shipI]['pvp_div2']['max_frags_battle'];
  2420. }else{
  2421. MembersArray[index]['ships'][shipI]['pvp_div']['max_frags_battle'] = MembersArray[index]['ships'][shipI]['pvp_div3']['max_frags_battle'];
  2422. }
  2423. if(MembersArray[index]['ships'][shipI]['pvp_div2']['max_planes_killed'] > MembersArray[index]['ships'][shipI]['pvp_div3']['max_planes_killed']){
  2424. MembersArray[index]['ships'][shipI]['pvp_div']['max_planes_killed'] = MembersArray[index]['ships'][shipI]['pvp_div2']['max_planes_killed'];
  2425. }else{
  2426. MembersArray[index]['ships'][shipI]['pvp_div']['max_planes_killed'] = MembersArray[index]['ships'][shipI]['pvp_div3']['max_planes_killed'];
  2427. }
  2428. if(MembersArray[index]['ships'][shipI]['pvp_div2']['max_damage_dealt'] > MembersArray[index]['ships'][shipI]['pvp_div3']['max_damage_dealt']){
  2429. MembersArray[index]['ships'][shipI]['pvp_div']['max_damage_dealt'] = MembersArray[index]['ships'][shipI]['pvp_div2']['max_damage_dealt'];
  2430. }else{
  2431. MembersArray[index]['ships'][shipI]['pvp_div']['max_damage_dealt'] = MembersArray[index]['ships'][shipI]['pvp_div3']['max_damage_dealt'];
  2432. }
  2433. MembersArray[index]['ships'][shipI]['pvp_div']['xp'] = MembersArray[index]['ships'][shipI]['pvp_div2']['xp'] + MembersArray[index]['ships'][shipI]['pvp_div3']['xp'];
  2434. MembersArray[index]['ships'][shipI]['pvp_div']['survived_battles'] = MembersArray[index]['ships'][shipI]['pvp_div2']['survived_battles'] + MembersArray[index]['ships'][shipI]['pvp_div3']['survived_battles'];
  2435. MembersArray[index]['ships'][shipI]['pvp_div']['dropped_capture_points'] = MembersArray[index]['ships'][shipI]['pvp_div2']['dropped_capture_points'] + MembersArray[index]['ships'][shipI]['pvp_div3']['dropped_capture_points'];
  2436. MembersArray[index]['ships'][shipI]['pvp_div']['draws'] = MembersArray[index]['ships'][shipI]['pvp_div2']['draws'] + MembersArray[index]['ships'][shipI]['pvp_div3']['draws'];
  2437. MembersArray[index]['ships'][shipI]['pvp_div']['wins'] = MembersArray[index]['ships'][shipI]['pvp_div2']['wins'] + MembersArray[index]['ships'][shipI]['pvp_div3']['wins'];
  2438. MembersArray[index]['ships'][shipI]['pvp_div']['damage_dealt'] = MembersArray[index]['ships'][shipI]['pvp_div2']['damage_dealt'] + MembersArray[index]['ships'][shipI]['pvp_div3']['damage_dealt'];
  2439. MembersArray[index]['ships'][shipI]['pvp_div']['losses'] = MembersArray[index]['ships'][shipI]['pvp_div2']['losses'] + MembersArray[index]['ships'][shipI]['pvp_div3']['losses'];
  2440. MembersArray[index]['ships'][shipI]['pvp_div']['frags'] = MembersArray[index]['ships'][shipI]['pvp_div2']['frags'] + MembersArray[index]['ships'][shipI]['pvp_div3']['frags'];
  2441. MembersArray[index]['ships'][shipI]['pvp_div']['capture_points'] = MembersArray[index]['ships'][shipI]['pvp_div2']['capture_points'] + MembersArray[index]['ships'][shipI]['pvp_div3']['capture_points'];
  2442. MembersArray[index]['ships'][shipI]['pvp_div']['survived_wins'] = MembersArray[index]['ships'][shipI]['pvp_div2']['survived_wins'] + MembersArray[index]['ships'][shipI]['pvp_div3']['survived_wins'];
  2443. MembersArray[index]['ships'][shipI]['pvp_div']['battles'] = MembersArray[index]['ships'][shipI]['pvp_div2']['battles'] + MembersArray[index]['ships'][shipI]['pvp_div3']['battles'];
  2444. MembersArray[index]['ships'][shipI]['pvp_div']['planes_killed'] = MembersArray[index]['ships'][shipI]['pvp_div2']['planes_killed'] + MembersArray[index]['ships'][shipI]['pvp_div3']['planes_killed'];
  2445. }
  2446. var Ship = MembersArray[index]['ships'][shipI];
  2447. var ship_id = Ship['ship_id'];
  2448. var Statistics = Ship[type];
  2449. MembersArray[index]['ships'][shipI][type]['avg_xp'] = Statistics['xp'] / Statistics['battles'];
  2450. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_xp'])){MembersArray[index]['ships'][shipI][type]['avg_xp'] = 0;}
  2451. MembersArray[index]['ships'][shipI][type]['avg_damage_dealt'] = Statistics['damage_dealt'] / Statistics['battles'];
  2452. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_damage_dealt'])){MembersArray[index]['ships'][shipI][type]['avg_damage_dealt'] = 0;}
  2453. MembersArray[index]['ships'][shipI][type]['avg_frags'] = Statistics['frags'] / Statistics['battles'];
  2454. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_frags'])){MembersArray[index]['ships'][shipI][type]['avg_frags'] = 0;}
  2455. MembersArray[index]['ships'][shipI][type]['avg_planes_killed'] = Statistics['planes_killed'] / Statistics['battles'];
  2456. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_planes_killed'])){MembersArray[index]['ships'][shipI][type]['avg_planes_killed'] = 0;}
  2457. MembersArray[index]['ships'][shipI][type]['avg_capture_points'] = Statistics['capture_points'] / Statistics['battles'];
  2458. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_capture_points'])){MembersArray[index]['ships'][shipI][type]['avg_capture_points'] = 0;}
  2459. MembersArray[index]['ships'][shipI][type]['avg_dropped_capture_points'] = Statistics['dropped_capture_points'] / Statistics['battles'];
  2460. if(isNaN(MembersArray[index]['ships'][shipI][type]['avg_dropped_capture_points'])){MembersArray[index]['ships'][shipI][type]['avg_dropped_capture_points'] = 0;}
  2461. MembersArray[index]['ships'][shipI][type]['wins_percents'] = (Statistics['wins']/Statistics['battles'])*100;
  2462. if(isNaN(MembersArray[index]['ships'][shipI][type]['wins_percents'])){MembersArray[index]['ships'][shipI][type]['wins_percents'] = 0;}
  2463. MembersArray[index]['ships'][shipI][type]['survived_battles_percents'] = (Statistics['survived_battles']/Statistics['battles'])*100;
  2464. if(isNaN(MembersArray[index]['ships'][shipI][type]['survived_battles_percents'])){MembersArray[index]['ships'][shipI][type]['survived_battles_percents'] = 0;}
  2465. if(Statistics['battles'] == Statistics['survived_battles']){
  2466. MembersArray[index]['ships'][shipI][type]['kill_dead'] = Statistics['frags']/Statistics['battles'];
  2467. }else{
  2468. MembersArray[index]['ships'][shipI][type]['kill_dead'] = Statistics['frags']/(Statistics['battles']-Statistics['survived_battles']);
  2469. }
  2470. if(isNaN(MembersArray[index]['ships'][shipI][type]['kill_dead'])){MembersArray[index]['ships'][shipI][type]['kill_dead'] = 0;}
  2471. if(Encyclopedia != null){
  2472. var ship_type = Encyclopedia[ship_id]['type'];
  2473. var ship_tier = Encyclopedia[ship_id]['tier'];
  2474. if(ExpShips[ship_id] !== undefined){
  2475. var battles = Statistics['battles'];
  2476. var damage_dealt = Statistics['damage_dealt'];
  2477. var frags = Statistics['frags'];
  2478. var planes_killed = Statistics['planes_killed'];
  2479. var StatShip = [];
  2480. StatShip['damage_dealt'] = damage_dealt;
  2481. StatShip['frags'] = frags;
  2482. StatShip['planes_killed'] = planes_killed;
  2483. StatShip['expDamage'] = battles * ExpShips[ship_id]['expDamage'];
  2484. StatShip['expFrags'] = battles * ExpShips[ship_id]['expFrags'];
  2485. StatShip['expPlanesKilled'] = battles * ExpShips[ship_id]['expPlanesKilled'];
  2486. MembersArray[index]['ships'][shipI][type]['wr'] = calcWR(StatShip);
  2487. StatShipsClass[ship_type]['damage_dealt'] += damage_dealt;
  2488. StatShipsClass[ship_type]['frags'] += frags;
  2489. StatShipsClass[ship_type]['planes_killed'] += planes_killed;
  2490. StatShipsClass[ship_type]['expDamage'] += StatShip['expDamage'];
  2491. StatShipsClass[ship_type]['expFrags'] += StatShip['expFrags'];
  2492. StatShipsClass[ship_type]['expPlanesKilled'] += StatShip['expPlanesKilled'];
  2493. StatShips['damage_dealt'] += damage_dealt;
  2494. StatShips['frags'] += frags;
  2495. StatShips['planes_killed'] += planes_killed;
  2496. StatShips['expDamage'] += StatShip['expDamage'];
  2497. StatShips['expFrags'] += StatShip['expFrags'];
  2498. StatShips['expPlanesKilled'] += StatShip['expPlanesKilled'];
  2499. }else{
  2500. MembersArray[index]['ships'][shipI][type]['wr'] = 0;
  2501. }
  2502. if(Statistics['battles'] > 0){
  2503. MembersArray[index]['info']['statistics'][type]['avg_battles_level'] += ship_tier * Statistics['battles'] / MembersArray[index]['info']['statistics'][type]['battles'];
  2504. }
  2505. if(Encyclopedia[ship_id]['tier'] == 10 && type == 'pvp'){
  2506. MembersArray[index]['info']['ships_x_level']++;
  2507. }
  2508. if(MembersArray[index]['info']['statistics'][type]['max_ship_level'] < Encyclopedia[ship_id]['tier']){
  2509. MembersArray[index]['info']['statistics'][type]['max_ship_level'] = Encyclopedia[ship_id]['tier'];
  2510. }
  2511. }
  2512. }
  2513. for(var tS = 0; tS < typeShip.length; tS++){
  2514. var typeS = typeShip[tS];
  2515. MembersArray[index]['info']['statistics'][type]['wr_'+typeS] = calcWR(StatShipsClass[typeS]);
  2516. }
  2517. MembersArray[index]['info']['statistics'][type]['wr'] = calcWR(StatShips);
  2518. }
  2519. if(MembersArray[index]['info']['statistics']['pvp_div2']['avg_battles_level'] > MembersArray[index]['info']['statistics']['pvp_div3']['avg_battles_level']){
  2520. MembersArray[index]['info']['statistics']['pvp_div']['avg_battles_level'] = MembersArray[index]['info']['statistics']['pvp_div2']['avg_battles_level'];
  2521. }else{
  2522. MembersArray[index]['info']['statistics']['pvp_div']['avg_battles_level'] = MembersArray[index]['info']['statistics']['pvp_div3']['avg_battles_level'];
  2523. }
  2524. if(MembersArray[index]['info']['statistics']['pvp_div2']['max_ship_level'] > MembersArray[index]['info']['statistics']['pvp_div3']['max_ship_level']){
  2525. MembersArray[index]['info']['statistics']['pvp_div']['max_ship_level'] = MembersArray[index]['info']['statistics']['pvp_div2']['max_ship_level'];
  2526. }else{
  2527. MembersArray[index]['info']['statistics']['pvp_div']['max_ship_level'] = MembersArray[index]['info']['statistics']['pvp_div3']['max_ship_level'];
  2528. }
  2529. for(var key in MembersArray[index]['achievements']['battle']){
  2530. var battle = MembersArray[index]['info']['statistics']['pvp']['battles'];
  2531. var achievements = MembersArray[index]['achievements']['battle'];
  2532. MembersArray[index]['achievements']['battle'][key+'_battle'] = (battle / achievements[key]).toFixed(0);
  2533. }
  2534. if(MembersArray[index]['statsbydate'] !== undefined && MembersArray[index]['statsbydate'] != null){
  2535. for(var date in MembersArray[index]['statsbydate']['pvp']){
  2536. MembersArray[index]['statsbydate']['pvp'][date]['avg_xp'] = MembersArray[index]['statsbydate']['pvp'][date]['xp'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2537. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_xp'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_xp'] = 0;}
  2538. MembersArray[index]['statsbydate']['pvp'][date]['avg_damage_dealt'] = MembersArray[index]['statsbydate']['pvp'][date]['damage_dealt'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2539. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_damage_dealt'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_damage_dealt'] = 0;}
  2540. MembersArray[index]['statsbydate']['pvp'][date]['avg_frags'] = MembersArray[index]['statsbydate']['pvp'][date]['frags'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2541. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_frags'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_frags'] = 0;}
  2542. MembersArray[index]['statsbydate']['pvp'][date]['avg_planes_killed'] = MembersArray[index]['statsbydate']['pvp'][date]['planes_killed'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2543. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_planes_killed'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_planes_killed'] = 0;}
  2544. MembersArray[index]['statsbydate']['pvp'][date]['avg_capture_points'] = MembersArray[index]['statsbydate']['pvp'][date]['capture_points'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2545. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_capture_points'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_capture_points'] = 0;}
  2546. MembersArray[index]['statsbydate']['pvp'][date]['avg_dropped_capture_points'] = MembersArray[index]['statsbydate']['pvp'][date]['dropped_capture_points'] / MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2547. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['avg_dropped_capture_points'])){MembersArray[index]['statsbydate']['pvp'][date]['avg_dropped_capture_points'] = 0;}
  2548. MembersArray[index]['statsbydate']['pvp'][date]['wins_percents'] = (MembersArray[index]['statsbydate']['pvp'][date]['wins']/MembersArray[index]['statsbydate']['pvp'][date]['battles'])*100;
  2549. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['wins_percents'])){MembersArray[index]['statsbydate']['pvp'][date]['wins_percents'] = 0;}
  2550. MembersArray[index]['statsbydate']['pvp'][date]['survived_battles_percents'] = (MembersArray[index]['statsbydate']['pvp'][date]['survived_battles']/MembersArray[index]['statsbydate']['pvp'][date]['battles'])*100;
  2551. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['survived_battles_percents'])){MembersArray[index]['statsbydate']['pvp'][date]['survived_battles_percents'] = 0;}
  2552. if(MembersArray[index]['statsbydate']['pvp'][date]['battles'] == MembersArray[index]['statsbydate']['pvp'][date]['survived_battles']){
  2553. MembersArray[index]['statsbydate']['pvp'][date]['kill_dead'] = MembersArray[index]['statsbydate']['pvp'][date]['frags']/MembersArray[index]['statsbydate']['pvp'][date]['battles'];
  2554. }else{
  2555. MembersArray[index]['statsbydate']['pvp'][date]['kill_dead'] = MembersArray[index]['statsbydate']['pvp'][date]['frags']/(MembersArray[index]['statsbydate']['pvp'][date]['battles']-MembersArray[index]['statsbydate']['pvp'][date]['survived_battles']);
  2556. }
  2557. if(isNaN(MembersArray[index]['statsbydate']['pvp'][date]['kill_dead'])){MembersArray[index]['statsbydate']['pvp'][date]['kill_dead'] = 0;}
  2558. }
  2559. var today = new Date();
  2560. var day = today.getDate();
  2561. var d = ''; if(day < 10){d = '0'+day+'';}else{d = ''+day+'';}
  2562. var month = today.getMonth() + 1;
  2563. var m = ''; if(month < 10){m = '0'+month+'';}else{m = ''+month+'';}
  2564. var year = today.getFullYear();
  2565. var y = ''+year+'';
  2566. var lastDate = parseInt(y+''+m+''+d);
  2567. if(MembersArray[index]['statsbydate']['pvp'] == null){MembersArray[index]['statsbydate']['pvp'] = {};}
  2568. MembersArray[index]['statsbydate']['pvp'][lastDate]= {};
  2569. MembersArray[index]['statsbydate']['pvp'][lastDate]['date'] = ''+lastDate+'';
  2570. MembersArray[index]['statsbydate']['pvp'][lastDate]['battles'] = MembersArray[index]['info']['statistics']['pvp']['battles'];
  2571. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_xp'] = MembersArray[index]['info']['statistics']['pvp']['avg_xp'];
  2572. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_damage_dealt'] = MembersArray[index]['info']['statistics']['pvp']['avg_damage_dealt'];
  2573. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_frags'] = MembersArray[index]['info']['statistics']['pvp']['avg_frags'];
  2574. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_planes_killed'] = MembersArray[index]['info']['statistics']['pvp']['avg_planes_killed'];
  2575. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_capture_points'] = MembersArray[index]['info']['statistics']['pvp']['avg_capture_points'];
  2576. MembersArray[index]['statsbydate']['pvp'][lastDate]['avg_dropped_capture_points'] = MembersArray[index]['info']['statistics']['pvp']['avg_dropped_capture_points'];
  2577. MembersArray[index]['statsbydate']['pvp'][lastDate]['wins_percents'] = MembersArray[index]['info']['statistics']['pvp']['wins_percents'];
  2578. MembersArray[index]['statsbydate']['pvp'][lastDate]['survived_battles_percents'] = MembersArray[index]['info']['statistics']['pvp']['survived_battles_percents'];
  2579. MembersArray[index]['statsbydate']['pvp'][lastDate]['kill_dead'] = MembersArray[index]['info']['statistics']['pvp']['kill_dead'];
  2580. }
  2581. return true;
  2582. }
  2583. function calcWR(Stat){
  2584. var rDamage = Stat['damage_dealt'] / Stat['expDamage']; if(isNaN(rDamage)){rDamage = 0;}
  2585. var rFrags = Stat['frags'] / Stat['expFrags']; if(isNaN(rFrags)){rFrags = 0;}
  2586. var rPlanesKilled = Stat['planes_killed'] / Stat['expPlanesKilled']; if(isNaN(rPlanesKilled)){rPlanesKilled = 0;}
  2587. var rDamagec = Math.max(0, (rDamage - 0.25) / (1 - 0.25));
  2588. var rFragsc = Math.max(0, Math.min(rDamagec + 0.2, (rFrags - 0.12) / (1 - 0.12)));
  2589. var rPlanesKilledc = Math.max(0, Math.min(rDamagec + 0.1, (rPlanesKilled - 0.15) / (1 - 0.15)));
  2590. var wr = 650 * rDamagec + 150 * rFragsc * rDamagec + 80 * rPlanesKilledc;
  2591. if(isNaN(wr)){wr = 0;}
  2592. return wr;
  2593. }
  2594. function doneEncyclopedia(url, response){
  2595. if(response.status && response.status == "error"){
  2596. errorEncyclopedia();
  2597. return;
  2598. }
  2599. Encyclopedia = response['data'];
  2600. Encyclopedia['null'] = [];
  2601. Encyclopedia['null']['name'] = '';
  2602. }
  2603. function errorEncyclopedia(url){
  2604. Encyclopedia = null;
  2605. console.log('Get Encyclopedia Error');
  2606. }
  2607. function findColorASC(value, stat_type, type){
  2608. if(colorStat[stat_type] === undefined){
  2609. return '';
  2610. }
  2611. if(type == 'main'){
  2612. if(isNaN(value) || parseFloat(value) <= parseFloat(colorStat[stat_type][0])){
  2613. return color['very_bad'];
  2614. }else if(parseFloat(value) <= parseFloat(colorStat[stat_type][1])){
  2615. return color['bad'];
  2616. }else if(parseFloat(value) <= parseFloat(colorStat[stat_type][2])){
  2617. return color['normal'];
  2618. }else if(parseFloat(value) <= parseFloat(colorStat[stat_type][3])){
  2619. return color['good'];
  2620. }else if(parseFloat(value) <= parseFloat(colorStat[stat_type][4])){
  2621. return color['very_good'];
  2622. }else if(parseFloat(value) <= parseFloat(colorStat[stat_type][5])){
  2623. return color['unique'];
  2624. }else{
  2625. return color['very_bad'];
  2626. }
  2627. }else{
  2628. return '';
  2629. }
  2630. }
  2631. function findColorDESC(value, stat_type, type){
  2632. if(type == 'main'){
  2633. var return_color = color['very_bad'];
  2634. if(isNaN(value)){
  2635. return_color = color['very_bad'];
  2636. }
  2637. if(parseFloat(value) <= parseFloat(colorStat[stat_type][0])){
  2638. return_color = color['very_bad'];
  2639. }
  2640. if(parseFloat(value) <= parseFloat(colorStat[stat_type][1])){
  2641. return_color = color['bad'];
  2642. }
  2643. if(parseFloat(value) <= parseFloat(colorStat[stat_type][2])){
  2644. return_color = color['normal'];
  2645. }
  2646. if(parseFloat(value) <= parseFloat(colorStat[stat_type][3])){
  2647. return_color = color['good'];
  2648. }
  2649. if(parseFloat(value) <= parseFloat(colorStat[stat_type][4])){
  2650. return_color = color['very_good'];
  2651. }
  2652. if(parseFloat(value) <= parseFloat(colorStat[stat_type][5])){
  2653. return_color = color['unique'];
  2654. }
  2655. return return_color;
  2656. }else{
  2657. return '';
  2658. }
  2659. }
  2660. function ASC(a){
  2661. return function (b, c){
  2662. if(a == 'account_name'){
  2663. return b[a].toLowerCase() < c[a].toLowerCase() ? -1 : b[a].toLowerCase() > c[a].toLowerCase() ? 1 : 0;
  2664. }else if(a == 'role_i18n'){
  2665. a = 'role_sort_num';
  2666. return parseFloat(b[a]) < parseFloat(c[a]) ? -1 : parseFloat(b[a]) > parseFloat(c[a]) ? 1 : 0;
  2667. }else{
  2668. var attr = a.split('.');
  2669. for(var i = 0; i < attr.length; i++){
  2670. b = b[attr[i]];
  2671. c = c[attr[i]];
  2672. }
  2673. return parseFloat(b) < parseFloat(c) ? -1 : parseFloat(b) > parseFloat(c) ? 1 : 0;
  2674. }
  2675. }
  2676. };
  2677. function DESC(a){
  2678. return function (b, c){
  2679. if(a == 'account_name'){
  2680. return b[a].toLowerCase() > c[a].toLowerCase() ? -1 : b[a].toLowerCase() < c[a].toLowerCase() ? 1 : 0;
  2681. }else if(a == 'role_i18n'){
  2682. a = 'role_sort_num';
  2683. return parseFloat(b[a]) > parseFloat(c[a]) ? -1 : parseFloat(b[a]) < parseFloat(c[a]) ? 1 : 0;
  2684. }else{
  2685. var attr = a.split('.');
  2686. for(var i = 0; i < attr.length; i++){
  2687. b = b[attr[i]];
  2688. c = c[attr[i]];
  2689. }
  2690. return parseFloat(b) > parseFloat(c) ? -1 : parseFloat(b) < parseFloat(c) ? 1 : 0;
  2691. }
  2692. }
  2693. };
  2694. function valueFormat(value){
  2695. if(isInt(value)){value = value.toString();}
  2696. var newValue = '';
  2697. var valueSplit = value.split('.');
  2698. var numChar = 0;
  2699. for(var i = valueSplit[0].length; i > 0; i--){
  2700. if(numChar < 3){
  2701. newValue = valueSplit[0].substr(i - 1, 1)+''+newValue;
  2702. numChar++;
  2703. }else{
  2704. newValue = valueSplit[0].substr(i - 1, 1)+''+localizationText['num-separator']+''+newValue;
  2705. numChar = 1;
  2706. }
  2707. }
  2708. if(valueSplit.length > 1){newValue += localizationText['num-fractional']+''+valueSplit[1];}
  2709. return newValue;
  2710. }
  2711. function isInt(value){
  2712. return !isNaN(value) && (function(x){return (x | 0) === x;})(parseFloat(value));
  2713. }
  2714. function htmlParseMemberStatistic(element){
  2715. var value = element.textContent.trim().replace(new RegExp(' ', 'g'), '');
  2716. value = value.replace(/[^0-9,.()% ]/g, "");
  2717. value = value.replace('%', '');
  2718. value = value.split(localizationText['num-separator']).join('');
  2719. value = value.replace(localizationText['num-fractional'], '.');
  2720. if(value.indexOf('(') > -1 && value.indexOf(')') > -1){
  2721. value = (value.split('('))[0];
  2722. }
  2723. return value;
  2724. }
  2725. function getJson(url, onDone, onError){
  2726. if(MaxProcess > Process){
  2727. Process++;
  2728. jQ.getJSON(url).done(function(result){
  2729. Process--;
  2730. onDone(url, result);
  2731. }).fail(function(jqxhr, textStatus, error){
  2732. Process--;
  2733. onError(url);
  2734. });
  2735. }else{
  2736. setTimeout(function(){getJson(url, onDone, onError);}, 1000);
  2737. }
  2738. }
  2739. function getApplicationId(){
  2740. return '7149a13b5f5fb7109c5b2400d31b7d42'.split("").reverse().join("");
  2741. }
  2742. function getUrlVars(url){
  2743. var vars = {};
  2744. var parts = url.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value){
  2745. vars[key] = value;
  2746. });
  2747. return vars;
  2748. }
  2749. function TimeToDate(time){
  2750. var date = new Date(time * 1000);
  2751. var seconds = date.getSeconds();
  2752. var minutes = date.getMinutes();
  2753. var hour = date.getHours();
  2754. var day = date.getDate();
  2755. var month = (date.getMonth() + 1);
  2756. var year = date.getFullYear();
  2757. if(seconds < 10){
  2758. seconds = '0'+seconds;
  2759. }
  2760. if(minutes < 10){
  2761. minutes = '0'+minutes;
  2762. }
  2763. if(hour < 10){
  2764. hour = '0'+hour;
  2765. }
  2766. if(day < 10){
  2767. day = '0'+day;
  2768. }
  2769. if(month < 10){
  2770. month = '0'+month;
  2771. }
  2772. return day+'.'+month+'.'+year+' '+hour+':'+minutes;
  2773. }
  2774. function dateDiffInDays(a, b){
  2775. var date1 = new Date(a);
  2776. var date2 = new Date(b);
  2777. if(b == null){
  2778. date2 = new Date();
  2779. }
  2780. var timeDiff = date2.getTime() - date1.getTime();
  2781. var diffDays = timeDiff / (1000 * 3600 * 24);
  2782. if(diffDays < 0){diffDays = 0;}
  2783. return (diffDays).toFixed(0);
  2784. }
  2785. function getUserScriptDeveloperBlock(){
  2786. var html = '' +
  2787. '<div class="div-link-block">' +
  2788. '<span id="userscriptwowsstatinfo" class="link-block hide-block">' +
  2789. 'UserScript WoWsStatInfo ' + VersionWoWsStatInfo +
  2790. '<div class="icon-link-block"></div>'+
  2791. '</span>' +
  2792. '</div>' +
  2793. '<div id="userscript-block" class="userscriptwowsstatinfo hide-block" style="text-align: center;">' +
  2794. '<span class="userscript-developer" align="center">' +
  2795. localizationText['userscript-developer'] +
  2796. ' <a target="_blank" style="color: #658C4C; font-weight: bold; border-bottom: 1px dotted #658C4C;" href="https://worldofwarships.ru/community/accounts/635939-/">Vov_chiK</a> ' +
  2797. localizationText['userscript-alliance'] +
  2798. ' <a target="_blank" style="color: #2CA8C7; font-weight: bold; border-bottom: 1px dotted #2CA8C7;" href="http://ru.wargaming.net/clans/wot/search/#wgsearch&search=Walkure&type=clans&offset=0&limit=10">Walkure</a>,' +
  2799. ' '+localizationText['userscript-support'] +
  2800. ' <a target="_blank" href="'+WoWsStatInfoHref+'">vzhabin.ru</a>' +
  2801. '<br /><br />' +
  2802. localizationText['userscript-topic']+' '+
  2803. '<a target="_blank" href="'+WoWsStatInfoLink+'">' +
  2804. WoWsStatInfoLinkName +
  2805. '</a>' +
  2806. '<br /><br />' +
  2807. '<font style="font-size: 16px; color: #658C4C;">'+localizationText['userscript-developer-support']+'</font><br />'+
  2808. '<font style="color: #2CA8C7;">Web-Money WMR</font> R295712009837 <br />'+
  2809. '<font style="color: #2CA8C7;">Web-Money WMZ</font> Z226959724402 <br />'+
  2810. '<font style="color: #2CA8C7;">Yandex Money</font> 41001290117791 <br />'+
  2811. '<font style="color: #2CA8C7;">RBK Money</font> RU353257918 <br />'+
  2812. '</span>' +
  2813. '</div>' +
  2814. '';
  2815. return html;
  2816. }
  2817. function onViewBlock(element){
  2818. if(null != element.getAttribute('id')){
  2819. var viewId = element.getAttribute('id');
  2820. var viewClassLink = element.getAttribute('class');
  2821. var viewBlock = document.getElementsByClassName(viewId)[0];
  2822. if(viewClassLink == 'link-block hide-block'){
  2823. element.setAttribute('class', 'link-block show-block');
  2824. viewBlock.setAttribute('class', viewBlock.getAttribute('class').replace('hide-block', 'show-block'));
  2825. setLocalStorage(viewId, 'show', false);
  2826. }else{
  2827. element.setAttribute('class', 'link-block hide-block');
  2828. viewBlock.setAttribute('class', viewBlock.getAttribute('class').replace('show-block', 'hide-block'));
  2829. setLocalStorage(viewId, 'hide', false);
  2830. }
  2831. }
  2832. }
  2833. function checkLocalStorage(){
  2834. try{
  2835. return 'localStorage' in window && window['localStorage'] !== null;
  2836. }catch (e){
  2837. return false;
  2838. }
  2839. }
  2840. function setLocalStorage(key, value, allPageHost){
  2841. if(checkLocalStorage()){
  2842. if(allPageHost){key = key+ClanId;}
  2843. window.localStorage.setItem(key, value);
  2844. }else{
  2845. setCookie(key, value, allPageHost);
  2846. }
  2847. }
  2848. function getLocalStorage(key, allPageHost){
  2849. var value = null;
  2850. if(checkLocalStorage()){
  2851. if(allPageHost){key = key+ClanId;}
  2852. value = window.localStorage.getItem(key);
  2853. }else{
  2854. value = getCookie(key);
  2855. }
  2856. return value;
  2857. }
  2858. function setCookie(c_name, value, allPageHost){
  2859. var exdate = new Date();
  2860. exdate.setDate(exdate.getDate() + 365);
  2861. if(allPageHost){
  2862. var c_value = escape(value) + ((365 == null) ? "" : "; expires="+exdate.toUTCString()+"; domain=" +window.location.hostname+"; path=/");
  2863. document.cookie = c_name + "=" + c_value;
  2864. }else{
  2865. var c_value = escape(value) + ((365 == null) ? "" : "; expires="+exdate.toUTCString());
  2866. document.cookie = c_name + "=" + c_value;
  2867. }
  2868. }
  2869. function getCookie(c_name){
  2870. var c_value = document.cookie;
  2871. var c_start = c_value.indexOf(" " + c_name + "=");
  2872. if(c_start == -1){
  2873. c_start = c_value.indexOf(c_name + "=");
  2874. }
  2875. if(c_start == -1){
  2876. c_value = null;
  2877. }else{
  2878. c_start = c_value.indexOf("=", c_start) + 1;
  2879. var c_end = c_value.indexOf(";", c_start);
  2880. if(c_end == -1){
  2881. c_end = c_value.length;
  2882. }
  2883. c_value = unescape(c_value.substring(c_start,c_end));
  2884. }
  2885. return c_value;
  2886. }
  2887. var WoWsStatInfoBase;
  2888. function openIndexedDB(){
  2889. //indexedDB.deleteDatabase('WoWsStatInfoBase');
  2890. var indexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB || window.OIndexedDB;
  2891. var openRequest = indexedDB.open("WoWsStatInfoBase", 1);
  2892. openRequest.onupgradeneeded = function(e){
  2893. console.log('IndexedDB onupgradeneeded');
  2894. var thisDB = e.target.result;
  2895. if(!thisDB.objectStoreNames.contains("WoWsStatInfoStore")){
  2896. thisDB.createObjectStore("WoWsStatInfoStore");
  2897. }
  2898. };
  2899. openRequest.onsuccess = function(e){
  2900. console.log('IndexedDB onsuccess');
  2901. WoWsStatInfoBase = e.target.result;
  2902. };
  2903. openRequest.onerror = function(e){
  2904. console.log('IndexedDB onerror');
  2905. console.log(e);
  2906. WoWsStatInfoBase = null;
  2907. };
  2908. }
  2909. function setIndexedDB(Key, Value, Done, Error){
  2910. if(WoWsStatInfoBase === undefined){
  2911. openIndexedDB();
  2912. setTimeout(function(){setIndexedDB(Key, Value, Done, Error);}, 2000);
  2913. }else if(WoWsStatInfoBase == null){
  2914. /* IndexedDB onerror */
  2915. }else{
  2916. var transaction = WoWsStatInfoBase.transaction(["WoWsStatInfoStore"], "readwrite");
  2917. var store = transaction.objectStore("WoWsStatInfoStore");
  2918. var request = store.put(Value, Key);
  2919. request.onerror = function(e){
  2920. console.log('onerror setIndexedDB...Key '+Key);
  2921. Error(Value);
  2922. };
  2923. request.onsuccess = function(e){
  2924. console.log('onsuccess setIndexedDB...Key '+Key);
  2925. Done(Value);
  2926. };
  2927. }
  2928. }
  2929. function getIndexedDB(Key, Done, Error){
  2930. if(WoWsStatInfoBase === undefined){
  2931. openIndexedDB();
  2932. setTimeout(function(){getIndexedDB(Key, Done, Error);}, 2000);
  2933. }else if(WoWsStatInfoBase == null){
  2934. /* IndexedDB onerror */
  2935. }else{
  2936. var transaction = WoWsStatInfoBase.transaction(["WoWsStatInfoStore"], "readonly");
  2937. var store = transaction.objectStore("WoWsStatInfoStore");
  2938. var request = store.get(Key);
  2939. request.onerror = function(e){
  2940. console.log('onerror getIndexedDB...Key '+Key);
  2941. Error(null);
  2942. };
  2943. request.onsuccess = function(e){
  2944. console.log('onsuccess getIndexedDB...Key '+Key);
  2945. Done(request.result ? request.result : null);
  2946. };
  2947. }
  2948. }
  2949. function delIndexedDB(Key){
  2950. if(WoWsStatInfoBase === undefined){
  2951. openIndexedDB();
  2952. setTimeout(function(){delIndexedDB(Key);}, 2000);
  2953. }else if(WoWsStatInfoBase == null){
  2954. /* IndexedDB onerror */
  2955. }else{
  2956. var transaction = WoWsStatInfoBase.transaction(["WoWsStatInfoStore"], "readwrite");
  2957. var store = transaction.objectStore("WoWsStatInfoStore");
  2958. store.delete(Key);
  2959. console.log('delIndexedDB...Key '+Key);
  2960. }
  2961. }
  2962. function onShowMessage(title, content, funcOk, OkText, viewCancel){
  2963. var ui_dialog_title = message.getElementsByClassName("wsi-ui-dialog-title")[0];
  2964. ui_dialog_title.innerHTML = title;
  2965. var popup = message.getElementsByClassName("wsi-popup")[0];
  2966. popup.innerHTML = content;
  2967. var button_inner = message.getElementsByClassName("wsi-button_inner")[0];
  2968. button_inner.innerHTML = OkText;
  2969. var link__cancel = message.getElementsByClassName("wsi-link__cancel")[0];
  2970. if(viewCancel){
  2971. link__cancel.style.display = 'inline';
  2972. }else{
  2973. link__cancel.style.display = 'none';
  2974. }
  2975. message.style.display = 'block';
  2976. messagebg.style.display = 'block';
  2977. message.style.marginLeft = '-'+(message.offsetWidth / 2)+'px';
  2978. //message.style.top = (window.scrollY + ((document.body.offsetHeight / 2) - (message.offsetHeight / 2)))+'px';
  2979. message.style.top = (window.scrollY + 50)+'px';
  2980. jQ('#userscript-message-ok').unbind('click');
  2981. jQ('#userscript-message-ok').click(funcOk);
  2982. jQ('#userscript-message-close').unbind('click');
  2983. jQ('#userscript-message-close').click(function(){onCloseMessage();});
  2984. jQ('#userscript-message-cancel').unbind('click');
  2985. jQ('#userscript-message-cancel').click(function(){onCloseMessage();});
  2986. }
  2987. function onCloseMessage(){
  2988. message.style.display = 'none';
  2989. messagebg.style.display = 'none';
  2990. }
  2991. function getLevelText(level){
  2992. if(1 == level){
  2993. return 'I';
  2994. }else if(2 == level){
  2995. return 'II';
  2996. }else if(3 == level){
  2997. return 'III';
  2998. }else if(4 == level){
  2999. return 'IV';
  3000. }else if(5 == level){
  3001. return 'V';
  3002. }else if(6 == level){
  3003. return 'VI';
  3004. }else if(7 == level){
  3005. return 'VII';
  3006. }else if(8 == level){
  3007. return 'VIII';
  3008. }else if(9 == level){
  3009. return 'IX';
  3010. }else if(10 == level){
  3011. return 'X';
  3012. }
  3013. return '-';
  3014. }
  3015. // Modify JSON.stringify to allow recursive and single-level arrays
  3016. (function(){
  3017. // Convert array to object
  3018. var convArrToObj = function(array){
  3019. var thisEleObj = new Object();
  3020. if(typeof array == "object"){
  3021. for(var i in array){
  3022. var thisEle = convArrToObj(array[i]);
  3023. thisEleObj[i] = thisEle;
  3024. }
  3025. }else {
  3026. thisEleObj = array;
  3027. }
  3028. return thisEleObj;
  3029. };
  3030. var oldJSONStringify = JSON.stringify;
  3031. JSON.stringify = function(input){
  3032. return oldJSONStringify(convArrToObj(input));
  3033. };
  3034. })();
  3035. function getRoleText(role){
  3036. var roleText = role;
  3037. if(localizationText[role] !== undefined){roleText = localizationText[role];}
  3038. return roleText;
  3039. }
  3040. function getRoleSortNum(role){
  3041. if (role == 'commander') return 0;
  3042. else if (role == 'executive_officer') return 1;
  3043. else if (role == 'personnel_officer') return 2;
  3044. else if (role == 'combat_officer') return 3;
  3045. else if (role == 'intelligence_officer') return 4;
  3046. else if (role == 'quartermaster') return 5;
  3047. else if (role == 'recruitment_officer') return 6;
  3048. else if (role == 'junior_officer') return 7;
  3049. else if (role == 'private') return 8;
  3050. else if (role == 'recruit') return 9;
  3051. else if (role == 'reservist') return 10;
  3052. else return 11;
  3053. }
  3054. function getlocalizationText(lang){
  3055. var localizationText = [];
  3056. {/* Русский */
  3057. localizationText['ru'] = [];
  3058. localizationText['ru']['num-separator'] = ' ';
  3059. localizationText['ru']['num-fractional'] = ',';
  3060. localizationText['ru']['Box'] = 'Оповещение';
  3061. localizationText['ru']['Ok'] = 'Ok';
  3062. localizationText['ru']['Cancel'] = 'Отмена';
  3063. localizationText['ru']['NewVersion'] = 'Вышла новая версия скрипта';
  3064. localizationText['ru']['NewUpdate'] = 'Пожалуйста, обновите скрипт';
  3065. localizationText['ru']['ErrorScript'] = 'Во время работы UserScript WoWsStatInfo '+VersionWoWsStatInfo+', возникла ошибка:';
  3066. localizationText['ru']['ErrorSendDeveloper'] = 'Сообщите об ошибке разработчику скрипта.';
  3067. localizationText['ru']['ErrorAPI'] = 'Не удалось получить данные.<br />Cуществует проблема в работе WG API.<br />Попробуйте обновить страницу или зайти позднее.';
  3068. localizationText['ru']['userscript-developer'] = 'Разработчик UserScript WoWsStatInfo:';
  3069. localizationText['ru']['userscript-alliance'] = 'член альянса';
  3070. localizationText['ru']['userscript-support'] = 'при поддержки проекта';
  3071. localizationText['ru']['userscript-topic'] = 'Тема на форуме:';
  3072. localizationText['ru']['userscript-developer-support'] = 'Поддержать автора скрипта:';
  3073. localizationText['ru']['search-clan-forum'] = 'Поиск клана...';
  3074. localizationText['ru']['profile-wows'] = 'Профиль в World of Warships';
  3075. localizationText['ru']['profile-clan'] = 'Клан';
  3076. localizationText['ru']['forum-profile'] = 'Профиль на форуме';
  3077. localizationText['ru']['role'] = 'Должность';
  3078. localizationText['ru']['clan-day'] = 'Количество дней в клане';
  3079. localizationText['ru']['charts'] = 'Диаграммы';
  3080. localizationText['ru']['generator-userbar'] = 'Создать подпись';
  3081. localizationText['ru']['userbar-bg'] = 'Выберите фон:';
  3082. localizationText['ru']['userbar-filters'] = 'Фильтр:';
  3083. localizationText['ru']['filters-all'] = 'Все';
  3084. localizationText['ru']['filters-clan'] = 'Клан';
  3085. localizationText['ru']['filters-noclassification'] = 'Нет классификации';
  3086. localizationText['ru']['filters-battleship'] = 'Линкоры';
  3087. localizationText['ru']['filters-aircarrier'] = 'Авианосцы';
  3088. localizationText['ru']['filters-cruiser'] = 'Крейсеры';
  3089. localizationText['ru']['filters-destroyer'] = 'Эсминцы';
  3090. localizationText['ru']['filters-japan'] = 'Япония';
  3091. localizationText['ru']['filters-ussr'] = 'CCCP';
  3092. localizationText['ru']['filters-germany'] = 'Германия';
  3093. localizationText['ru']['filters-uk'] = 'Великобритания';
  3094. localizationText['ru']['filters-usa'] = 'США';
  3095. localizationText['ru']['userbar-your-background'] = 'Загрузить свой фон';
  3096. localizationText['ru']['upload-submit'] = 'Загрузить';
  3097. localizationText['ru']['img-max-size'] = 'Максимальный размер: 150КБ';
  3098. localizationText['ru']['img-max-px'] = 'Разрешение изображения: 468х100';
  3099. localizationText['ru']['img-format'] = 'Формат: PNG';
  3100. localizationText['ru']['upload-verification'] = 'Фон будет обновлен после проверки.';
  3101. localizationText['ru']['pvp_solo'] = 'Соло';
  3102. localizationText['ru']['pvp_div'] = 'Отряд';
  3103. localizationText['ru']['title_battles'] = 'Количество боёв';
  3104. localizationText['ru']['title_wins_percents'] = 'Процент побед';
  3105. localizationText['ru']['title_avg_xp'] = 'Средний опыт за бой';
  3106. localizationText['ru']['title_avg_damage_dealt'] = 'Средний нанесённый урон за бой';
  3107. localizationText['ru']['title_kill_dead'] = 'Отношение уничтожил / убит';
  3108. localizationText['ru']['title_wr'] = 'WR';
  3109. localizationText['ru']['title_avg_battles_level'] = 'Средний уровень кораблей игрока в боях';
  3110. localizationText['ru']['title_avg_frags'] = 'Средние Уничтожено кораблей за бой';
  3111. localizationText['ru']['title_avg_planes_killed'] = 'Средние Уничтожено самолётов за бой';
  3112.  
  3113. localizationText['ru']['stat-table-1'] = 'Общие результаты';
  3114. localizationText['ru']['battles'] = 'Бои';
  3115. localizationText['ru']['wins'] = 'Победы';
  3116. localizationText['ru']['survived_battles'] = 'Выжил в боях';
  3117. localizationText['ru']['damage_dealt'] = 'Нанесённый урон';
  3118. localizationText['ru']['frags'] = 'Уничтожено кораблей';
  3119. localizationText['ru']['planes_killed'] = 'Уничтожено самолётов';
  3120. localizationText['ru']['capture_points'] = 'Захват базы';
  3121. localizationText['ru']['dropped_capture_points'] = 'Защита базы';
  3122.  
  3123. localizationText['ru']['stat-table-2'] = 'Средние показатели за бой';
  3124. localizationText['ru']['avg_xp'] = 'Опыт';
  3125. localizationText['ru']['avg_damage_dealt'] = 'Нанесённый урон';
  3126. localizationText['ru']['avg_frags'] = 'Уничтожено кораблей';
  3127. localizationText['ru']['avg_planes_killed'] = 'Уничтожено самолётов';
  3128. localizationText['ru']['avg_capture_points'] = 'Захват базы';
  3129. localizationText['ru']['avg_dropped_capture_points'] = 'Защита базы';
  3130.  
  3131. localizationText['ru']['stat-table-3'] = 'Рекордные показатели';
  3132. localizationText['ru']['max_xp'] = 'Опыт';
  3133. localizationText['ru']['max_damage_dealt'] = 'Нанесённый урон';
  3134. localizationText['ru']['max_frags_battle'] = 'Уничтожено кораблей';
  3135. localizationText['ru']['max_planes_killed'] = 'Уничтожено самолётов';
  3136. localizationText['ru']['stat-table-4'] = 'Дополнительные результаты';
  3137. localizationText['ru']['battles_days'] = 'Количество боев в день';
  3138. localizationText['ru']['max_ship_level'] = 'Максимальный уровень корабля';
  3139. localizationText['ru']['avg_battles_level'] = 'Средний уровень кораблей игрока в боях';
  3140. localizationText['ru']['number-ships-x'] = 'Количество кораблей 10 уровня';
  3141. localizationText['ru']['wr'] = 'WR';
  3142. localizationText['ru']['ships_stat'] = 'Расширенная статистика по технике';
  3143. localizationText['ru']['title_ships'] = 'Корабли';
  3144. localizationText['ru']['battleship'] = 'Линкоры';
  3145. localizationText['ru']['aircarrier'] = 'Авианосцы';
  3146. localizationText['ru']['cruiser'] = 'Крейсеры';
  3147. localizationText['ru']['destroyer'] = 'Эсминцы';
  3148. localizationText['ru']['block-link-clan-member-history'] = 'Блок "Изменений в составе клана"';
  3149. localizationText['ru']['link-clan-member-history'] = 'Изменения в составе клана';
  3150. localizationText['ru']['member-history-clear'] = 'Очистить историю';
  3151. localizationText['ru']['member-history-join'] = 'Вступил в клан %NAME%';
  3152. localizationText['ru']['member-history-leave'] = 'Покинул клан %NAME%';
  3153. localizationText['ru']['member-history-rename'] = '%OLDNAME% сменил ник на %NEWNAME%';
  3154. localizationText['ru']['member-history-rerole'] = '%NAME% сменил должность %OLDROLE% &rArr; %NEWROLE%';
  3155. localizationText['ru']['member-history-notchange'] = 'С момента установки скрипта WoWsStatInfo и последнего захода на страницу, изменений в составе клана не производились.';
  3156. localizationText['ru']['banned'] = 'Забанен';
  3157. localizationText['ru']['commander'] = 'Командующий';
  3158. localizationText['ru']['executive_officer'] = 'Заместитель командующего';
  3159. localizationText['ru']['personnel_officer'] = 'Офицер штаба';
  3160. localizationText['ru']['intelligence_officer'] = 'Офицер разведки';
  3161. localizationText['ru']['quartermaster'] = 'Офицер снабжения';
  3162. localizationText['ru']['recruitment_officer'] = 'Офицер по кадрам';
  3163. localizationText['ru']['junior_officer'] = 'Младший офицер';
  3164. localizationText['ru']['combat_officer'] = 'Командир подразделения';
  3165. localizationText['ru']['private'] = 'Боец';
  3166. localizationText['ru']['recruit'] = 'Новобранец';
  3167. localizationText['ru']['reservist'] = 'Резервист';
  3168. localizationText['ru']['get-settings-button'] = 'Настройка';
  3169. localizationText['ru']['set-settings-default'] = 'Настройки по умолчанию';
  3170. localizationText['ru']['table-setting-caption'] = 'Отображать в таблице "Статистика клана"';
  3171. localizationText['ru']['table-setting-structure'] = 'Порядок столбцов в таблице';
  3172. localizationText['ru']['statistic-clan-button-0'] = 'Статистика клана';
  3173. localizationText['ru']['statistic-clan-button-1'] = 'Состав клана';
  3174. localizationText['ru']['statistic-clan-load-text'] = 'Пожалуйста, подождите ...<br />Получение статистики состава';
  3175. localizationText['ru']['statistic-load-text-lost'] = '<br />Осталось &#8776;';
  3176. localizationText['ru']['statistic-load-text-min'] = 'мин.';
  3177. localizationText['ru']['statistic-load-text-sec'] = 'сек.';
  3178. localizationText['ru']['account_name'] = 'Имя игрока';
  3179. localizationText['ru']['role_i18n'] = 'Должность';
  3180. localizationText['ru']['clan_days'] = 'Дней в клане';
  3181. localizationText['ru']['info.last_battle_time'] = 'Время последнего боя';
  3182. localizationText['ru']['info.logout_at'] = 'Время окончания сессии';
  3183. localizationText['ru']['info.statistics.pvp.battles'] = 'Проведено боёв';
  3184. localizationText['ru']['info.statistics.pvp.wins'] = 'Победы';
  3185. localizationText['ru']['info.statistics.pvp.losses'] = 'Поражения';
  3186. localizationText['ru']['info.statistics.pvp.draws'] = 'Ничьи';
  3187. localizationText['ru']['info.statistics.pvp.survived_battles'] = 'Выжил в боях';
  3188. localizationText['ru']['info.statistics.pvp.survived_wins'] = 'Выжил в боях и победил';
  3189. localizationText['ru']['info.statistics.pvp.kill_dead'] = 'Уничтожил / Убит';
  3190. localizationText['ru']['info.statistics.pvp.xp'] = 'Суммарный опыт';
  3191. localizationText['ru']['info.statistics.pvp.damage_dealt'] = 'Нанесено дамага';
  3192. localizationText['ru']['info.statistics.pvp.frags'] = 'Потоплено кораблей';
  3193. localizationText['ru']['info.statistics.pvp.planes_killed'] = 'Уничтожено самолётов';
  3194. localizationText['ru']['info.statistics.pvp.capture_points'] = 'Очки захвата базы';
  3195. localizationText['ru']['info.statistics.pvp.dropped_capture_points'] = 'Очки защиты базы';
  3196. localizationText['ru']['info.statistics.pvp.avg_xp'] = 'Ср. опыт';
  3197. localizationText['ru']['info.statistics.pvp.avg_damage_dealt'] = 'Ср. урон';
  3198. localizationText['ru']['info.statistics.pvp.avg_frags'] = 'Ср. потоплено кораблей';
  3199. localizationText['ru']['info.statistics.pvp.avg_planes_killed'] = 'Ср. уничтожено самолётов';
  3200. localizationText['ru']['info.statistics.pvp.avg_capture_points'] = 'Ср. захвата базы';
  3201. localizationText['ru']['info.statistics.pvp.avg_dropped_capture_points'] = 'Ср. защиты базы';
  3202. localizationText['ru']['info.statistics.pvp.max_xp'] = 'Максимальный опыт';
  3203. localizationText['ru']['info.statistics.pvp.max_damage_dealt'] = 'Максимальный урон';
  3204. localizationText['ru']['info.statistics.pvp.max_frags_battle'] = 'Максимально потоплено кораблей';
  3205. localizationText['ru']['info.statistics.pvp.max_planes_killed'] = 'Максимально уничтожено самолётов';
  3206. localizationText['ru']['info.statistics.pvp.wins_percents'] = 'Процент побед';
  3207. localizationText['ru']['info.statistics.pvp.survived_battles_percents'] = 'Процент выживания';
  3208. localizationText['ru']['info.statistics.pvp.wr'] = 'WR';
  3209. localizationText['ru']['info.ships_x_level'] = '10 lvl';
  3210. localizationText['ru']['achieve_counter_1'] = 'количество полученных наград';
  3211. localizationText['ru']['achieve_counter_2'] = 'частота получения наград, количество боев необходимых для получения награды';
  3212. localizationText['ru']['to'] = 'до';
  3213. }
  3214. {/* English */
  3215. localizationText['en'] = [];
  3216. localizationText['en'] = jQ.extend([], localizationText['ru']);
  3217. localizationText['en']['num-separator'] = ',';
  3218. localizationText['en']['num-fractional'] = '.';
  3219.  
  3220. localizationText['en']['Box'] = 'Notification';
  3221. localizationText['en']['Ok'] = 'Ok';
  3222. localizationText['en']['Cancel'] = 'Cancel';
  3223. localizationText['en']['NewVersion'] = 'New version was released';
  3224. localizationText['en']['NewUpdate'] = 'Please, update the extension';
  3225. localizationText['en']['ErrorScript'] = 'An error occurred while running UserScript WoWsStatInfo '+VersionWoWsStatInfo+', script:';
  3226. localizationText['en']['ErrorSendDeveloper'] = 'Please, inform script developer about this error.';
  3227. localizationText['en']['ErrorAPI'] = 'Failed to get the data.<br />There exists a problem in the work of WG API.<br />Try refreshing the page, or go later.';
  3228. localizationText['en']['userscript-developer'] = 'Developer - UserScript WoWsStatInfo:';
  3229. localizationText['en']['userscript-alliance'] = 'аlliance member';
  3230. localizationText['en']['userscript-support'] = 'with the support of';
  3231. localizationText['en']['userscript-topic'] = 'Forum topic:';
  3232. localizationText['en']['userscript-developer-support'] = 'Ways to support the developer:';
  3233. localizationText['en']['search-clan-forum'] = 'Clan Search...';
  3234. localizationText['en']['profile-wows'] = 'World of Warships profile';
  3235. localizationText['en']['profile-clan'] = 'Clan';
  3236. localizationText['en']['forum-profile'] = 'Forum profile';
  3237. localizationText['en']['role'] = 'Alliance rank';
  3238. localizationText['en']['clan-day'] = 'Days in clan';
  3239. localizationText['en']['charts'] = 'Charts';
  3240. localizationText['en']['generator-userbar'] = 'Create signature';
  3241. localizationText['en']['userbar-bg'] = 'Choose a background:';
  3242. localizationText['en']['userbar-filters'] = 'Filters:';
  3243. localizationText['en']['filters-all'] = 'All';
  3244. localizationText['en']['filters-clan'] = 'Clan';
  3245. localizationText['en']['filters-noclassification'] = 'No Classification';
  3246. localizationText['en']['filters-battleship'] = 'Battleships';
  3247. localizationText['en']['filters-aircarrier'] = 'Aircraft carriers';
  3248. localizationText['en']['filters-cruiser'] = 'Cruisers';
  3249. localizationText['en']['filters-destroyer'] = 'Destroyers';
  3250. localizationText['en']['filters-japan'] = 'Japan';
  3251. localizationText['en']['filters-ussr'] = 'U.S.S.R.';
  3252. localizationText['en']['filters-germany'] = 'Germany';
  3253. localizationText['en']['filters-uk'] = 'U.K.';
  3254. localizationText['en']['filters-usa'] = 'U.S.A.';
  3255. localizationText['en']['userbar-your-background'] = 'Upload your background';
  3256. localizationText['en']['upload-submit'] = 'Upload';
  3257. localizationText['en']['img-max-size'] = 'Maximum size: 150 KB';
  3258. localizationText['en']['img-max-px'] = 'Image Resolution: 468x100';
  3259. localizationText['en']['img-format'] = 'Format: PNG';
  3260. localizationText['en']['upload-verification'] = 'Background will be updated after verification.';
  3261. localizationText['en']['pvp_solo'] = 'Solo';
  3262. localizationText['en']['pvp_div'] = 'Division';
  3263. localizationText['en']['title_battles'] = 'Battles Fought';
  3264. localizationText['en']['title_wins_percents'] = 'Victories / Battles';
  3265. localizationText['en']['title_avg_xp'] = 'AVERAGE EXPERIENCE PER BATTLE';
  3266. localizationText['en']['title_avg_damage_dealt'] = 'Average Damage Caused per Battle';
  3267. localizationText['en']['title_kill_dead'] = 'Kill / Death Ratio';
  3268. localizationText['en']['title_wr'] = 'WR';
  3269. localizationText['en']['title_avg_battles_level'] = 'Average tier of warships used by player';
  3270. localizationText['en']['title_avg_frags'] = 'Average Destroyed ships for battle';
  3271. localizationText['en']['title_avg_planes_killed'] = 'Average Destroyed aircraft for battle';
  3272.  
  3273. localizationText['en']['stat-table-1'] = 'Overall Results';
  3274. localizationText['en']['battles'] = 'Battles';
  3275. localizationText['en']['wins'] = 'Victories';
  3276. localizationText['en']['survived_battles'] = 'Battles survived';
  3277. localizationText['en']['damage_dealt'] = 'Damage caused';
  3278. localizationText['en']['frags'] = 'Warships destroyed';
  3279. localizationText['en']['planes_killed'] = 'Aircraft destroyed';
  3280. localizationText['en']['capture_points'] = 'Base capture';
  3281. localizationText['en']['dropped_capture_points'] = 'Base defense';
  3282.  
  3283. localizationText['en']['stat-table-2'] = 'Average Score per Battle';
  3284. localizationText['en']['avg_xp'] = 'Experience';
  3285. localizationText['en']['avg_damage_dealt'] = 'Damage caused';
  3286. localizationText['en']['avg_frags'] = 'Warships destroyed';
  3287. localizationText['en']['avg_planes_killed'] = 'Aircraft destroyed';
  3288. localizationText['en']['avg_capture_points'] = 'Base capture';
  3289. localizationText['en']['avg_dropped_capture_points'] = 'Base defense';
  3290.  
  3291. localizationText['en']['stat-table-3'] = 'Highest Score';
  3292. localizationText['en']['max_xp'] = 'Experience';
  3293. localizationText['en']['max_damage_dealt'] = 'Damage caused';
  3294. localizationText['en']['max_frags_battle'] = 'Warships destroyed';
  3295. localizationText['en']['max_planes_killed'] = 'Aircraft destroyed';
  3296. localizationText['en']['stat-table-4'] = 'Additional Results';
  3297. localizationText['en']['battles_days'] = 'Battles per day';
  3298. localizationText['en']['max_ship_level'] = 'The maximum tier of ship';
  3299. localizationText['en']['avg_battles_level'] = 'Average tier of warships used by player';
  3300. localizationText['en']['number-ships-x'] = 'Number of X Tier ships';
  3301. localizationText['en']['wr'] = 'WR';
  3302. localizationText['en']['ships_stat'] = 'Detailed Warship Statistics';
  3303. localizationText['en']['title_ships'] = 'Warships';
  3304. localizationText['en']['battleship'] = 'Battleships';
  3305. localizationText['en']['aircarrier'] = 'Aircraft carriers';
  3306. localizationText['en']['cruiser'] = 'Cruisers';
  3307. localizationText['en']['destroyer'] = 'Destroyers';
  3308. localizationText['en']['block-link-clan-member-history'] = '"Changes in clan members" section';
  3309. localizationText['en']['link-clan-member-history'] = 'Changes in clan members';
  3310. localizationText['en']['member-history-clear'] = 'Clear history';
  3311. localizationText['en']['member-history-join'] = 'Entered %NAME% clan';
  3312. localizationText['en']['member-history-leave'] = 'Left %NAME% clan';
  3313. localizationText['en']['member-history-rename'] = '%OLDNAME% has changed his nickname to %NEWNAME%';
  3314. localizationText['en']['member-history-rerole'] = '%NAME% has changed his position in clan rank: %OLDROLE% &rArr; %NEWROLE%';
  3315. localizationText['en']['member-history-notchange'] = 'Since installing WoWsStatInfo script and last entering on this page no changes in clan members were made.';
  3316. localizationText['en']['banned'] = 'Banned';
  3317. localizationText['en']['commander'] = 'Commander';
  3318. localizationText['en']['executive_officer'] = 'Executive Officer';
  3319. localizationText['en']['personnel_officer'] = 'Personnel Officer';
  3320. localizationText['en']['intelligence_officer'] = 'Intelligence Officer';
  3321. localizationText['en']['quartermaster'] = 'Quartermaster';
  3322. localizationText['en']['recruitment_officer'] = 'Recruitment Officer';
  3323. localizationText['en']['junior_officer'] = 'Junior Officer';
  3324. localizationText['en']['combat_officer'] = 'Combat Officer';
  3325. localizationText['en']['private'] = 'Private';
  3326. localizationText['en']['recruit'] = 'Recruit';
  3327. localizationText['en']['reservist'] = 'Reservist';
  3328.  
  3329. localizationText['en']['get-settings-button'] = 'Settings';
  3330. localizationText['en']['set-settings-default'] = 'The default settings';
  3331. localizationText['en']['table-setting-caption'] = 'View column table "Clan Statistics"';
  3332. localizationText['en']['table-setting-structure'] = 'Sort column table';
  3333. localizationText['en']['statistic-clan-button-0'] = 'Clan Statistics';
  3334. localizationText['en']['statistic-clan-button-1'] = 'Clan Composition';
  3335. localizationText['en']['statistic-clan-load-text'] = 'Please wait ...<br />Getting statistics';
  3336. localizationText['en']['statistic-load-text-lost'] = '<br />time remaining &#8776;';
  3337. localizationText['en']['statistic-load-text-min'] = 'min.';
  3338. localizationText['en']['statistic-load-text-sec'] = 'sec.';
  3339. localizationText['en']['account_name'] = 'Player name';
  3340. localizationText['en']['role_i18n'] = 'Role';
  3341. localizationText['en']['clan_days'] = 'Days in clan';
  3342. localizationText['en']['info.last_battle_time'] = 'Last battle time';
  3343. localizationText['en']['info.logout_at'] = 'End time of last game session';
  3344. localizationText['en']['info.statistics.pvp.battles'] = 'Battles';
  3345. localizationText['en']['info.statistics.pvp.wins'] = 'Victories';
  3346. localizationText['en']['info.statistics.pvp.losses'] = 'Defeats';
  3347. localizationText['en']['info.statistics.pvp.draws'] = 'Draws';
  3348. localizationText['en']['info.statistics.pvp.survived_battles'] = 'Battles survived';
  3349. localizationText['en']['info.statistics.pvp.survived_wins'] = 'Victories in battles survived';
  3350. localizationText['en']['info.statistics.pvp.kill_dead'] = 'Kill / Death';
  3351. localizationText['en']['info.statistics.pvp.xp'] = 'Total Experience';
  3352. localizationText['en']['info.statistics.pvp.damage_dealt'] = 'Damage caused';
  3353. localizationText['en']['info.statistics.pvp.frags'] = 'Warships destroyed';
  3354. localizationText['en']['info.statistics.pvp.planes_killed'] = 'Aircraft destroyed';
  3355. localizationText['en']['info.statistics.pvp.capture_points'] = 'Base capture points';
  3356. localizationText['en']['info.statistics.pvp.dropped_capture_points'] = 'Base defense points';
  3357. localizationText['en']['info.statistics.pvp.avg_xp'] = 'Avg experience';
  3358. localizationText['en']['info.statistics.pvp.avg_damage_dealt'] = 'Avg Damage caused';
  3359. localizationText['en']['info.statistics.pvp.avg_frags'] = 'Avg warships destroyed';
  3360. localizationText['en']['info.statistics.pvp.avg_planes_killed'] = 'Avg aircraft destroyed';
  3361. localizationText['en']['info.statistics.pvp.avg_capture_points'] = 'Avg Base capture';
  3362. localizationText['en']['info.statistics.pvp.avg_dropped_capture_points'] = 'Avg Base defense';
  3363. localizationText['en']['info.statistics.pvp.max_xp'] = 'Maximum experience';
  3364. localizationText['en']['info.statistics.pvp.max_damage_dealt'] = 'Maximum Damage caused';
  3365. localizationText['en']['info.statistics.pvp.max_frags_battle'] = 'Maximum warships destroyed';
  3366. localizationText['en']['info.statistics.pvp.max_planes_killed'] = 'Maximum aircraft destroyed';
  3367. localizationText['en']['info.statistics.pvp.wins_percents'] = 'Percent of victories';
  3368. localizationText['en']['info.statistics.pvp.survived_battles_percents'] = 'Percent of survived';
  3369. localizationText['en']['info.statistics.pvp.wr'] = 'WR';
  3370. localizationText['en']['info.ships_x_level'] = '10 lvl';
  3371. localizationText['en']['achieve_counter_1'] = 'the number of awards received';
  3372. localizationText['en']['achieve_counter_2'] = 'the frequency of receiving awards, the number of battles needed for award';
  3373. localizationText['en']['to'] = 'to';
  3374. }
  3375. {/* Français */
  3376. localizationText['fr'] = [];
  3377. localizationText['fr'] = jQ.extend([], localizationText['en']);
  3378. localizationText['fr']['num-separator'] = ' ';
  3379. localizationText['fr']['num-fractional'] = ',';
  3380. localizationText['fr']['pvp_solo'] = 'Solo';
  3381. localizationText['fr']['pvp_div'] = 'Division';
  3382. localizationText['fr']['title_battles'] = 'Batailles menées';
  3383. localizationText['fr']['title_wins_percents'] = 'Taux de victoires/batailles';
  3384. localizationText['fr']['title_avg_xp'] = 'EXPÉRIENCE MOYENNE PAR BATAILLE';
  3385. localizationText['fr']['title_avg_damage_dealt'] = 'Dégâts moyens causés par bataille';
  3386. localizationText['fr']['title_kill_dead'] = 'Taux des tués/morts';
  3387. localizationText['fr']['title_wr'] = 'WR';
  3388. localizationText['fr']['title_avg_battles_level'] = 'Niveau moyen de navires de guerre utilisée par le joueur';
  3389. localizationText['fr']['title_avg_frags'] = 'Navires détruits moyennes pour la bataille';
  3390. localizationText['fr']['title_avg_planes_killed'] = 'Avions détruits moyenne pour la lutte';
  3391.  
  3392. localizationText['fr']['stat-table-1'] = 'Résultats généraux';
  3393. localizationText['fr']['battles'] = 'Batailles';
  3394. localizationText['fr']['wins'] = 'Victoires';
  3395. localizationText['fr']['survived_battles'] = 'Batailles survécues';
  3396. localizationText['fr']['damage_dealt'] = 'Dégâts occasionnés';
  3397. localizationText['fr']['frags'] = 'Navires de guerre détruits';
  3398. localizationText['fr']['planes_killed'] = 'Avions détruits';
  3399. localizationText['fr']['capture_points'] = 'Points de capture';
  3400. localizationText['fr']['dropped_capture_points'] = 'Points de défense';
  3401.  
  3402. localizationText['fr']['stat-table-2'] = 'Score moyen par bataille';
  3403. localizationText['fr']['avg_xp'] = 'Expérience';
  3404. localizationText['fr']['avg_damage_dealt'] = 'Dégâts occasionnés';
  3405. localizationText['fr']['avg_frags'] = 'Navires de guerre détruits';
  3406. localizationText['fr']['avg_planes_killed'] = 'Avions détruits';
  3407. localizationText['fr']['avg_capture_points'] = 'Points de capture';
  3408. localizationText['fr']['avg_dropped_capture_points'] = 'Points de défense';
  3409.  
  3410. localizationText['fr']['stat-table-3'] = 'Score record';
  3411. localizationText['fr']['max_xp'] = 'Expérience';
  3412. localizationText['fr']['max_damage_dealt'] = 'Dégâts occasionnés';
  3413. localizationText['fr']['max_frags_battle'] = 'Navires de guerre détruits';
  3414. localizationText['fr']['max_planes_killed'] = 'Avions détruits';
  3415. localizationText['fr']['stat-table-4'] = 'Résultats supplémentaires';
  3416. localizationText['fr']['battles_days'] = 'Batailles par jour';
  3417. localizationText['fr']['max_ship_level'] = 'Le niveau maximum de navire';
  3418. localizationText['fr']['avg_battles_level'] = 'Niveau moyen de navires de guerre utilisée par le joueur';
  3419. localizationText['fr']['number-ships-x'] = 'Nombre de navires X Tier';
  3420. localizationText['fr']['wr'] = 'WR';
  3421. localizationText['fr']['ships_stat'] = 'Statistiques détaillées du navire';
  3422. localizationText['fr']['title_ships'] = 'Navires de guerre';
  3423. localizationText['fr']['battleship'] = 'Cuirassés';
  3424. localizationText['fr']['aircarrier'] = 'Porte-avions';
  3425. localizationText['fr']['cruiser'] = 'Croiseurs';
  3426. localizationText['fr']['destroyer'] = 'Destroyers';
  3427. }
  3428. {/* Deutsch */
  3429. localizationText['de'] = [];
  3430. localizationText['de'] = jQ.extend([], localizationText['en']);
  3431. localizationText['de']['num-separator'] = '.';
  3432. localizationText['de']['num-fractional'] = ',';
  3433. localizationText['de']['pvp_solo'] = 'Solo';
  3434. localizationText['de']['pvp_div'] = 'Division';
  3435. localizationText['de']['title_battles'] = 'Gekämpfte Gefechte';
  3436. localizationText['de']['title_wins_percents'] = 'Verhältnis Siege/Gefechte';
  3437. localizationText['de']['title_avg_xp'] = 'MITTLERE ERFAHRUNG JE GEFECHT';
  3438. localizationText['de']['title_avg_damage_dealt'] = 'Mittlerer verursachter Schaden je Gefecht';
  3439. localizationText['de']['title_kill_dead'] = 'Verhältnis Abschüsse/Verluste';
  3440. localizationText['de']['title_wr'] = 'WR';
  3441. localizationText['de']['title_avg_battles_level'] = 'Durchschnittliche Tier von Kriegsschiffen durch Spieler verwendet';
  3442. localizationText['de']['title_avg_frags'] = 'Durchschnittlich zerstörte Schiffe zum Kampf';
  3443. localizationText['de']['title_avg_planes_killed'] = 'Durchschnittlich zerstörte Flugzeug für den Kampf';
  3444.  
  3445. localizationText['de']['stat-table-1'] = 'Gesamtergebnisse';
  3446. localizationText['de']['battles'] = 'Gefechte';
  3447. localizationText['de']['wins'] = 'Siege';
  3448. localizationText['de']['survived_battles'] = 'Überlebte Gefechte';
  3449. localizationText['de']['damage_dealt'] = 'Schaden verursacht';
  3450. localizationText['de']['frags'] = 'Zerstörte Kriegsschiffe';
  3451. localizationText['de']['planes_killed'] = 'Flugzeuge abgeschossen';
  3452. localizationText['de']['capture_points'] = 'Basiseroberung';
  3453. localizationText['de']['dropped_capture_points'] = 'Basisverteidigung';
  3454.  
  3455. localizationText['de']['stat-table-2'] = 'Mittlere Punktzahl je Gefecht';
  3456. localizationText['de']['avg_xp'] = 'Erfahrung';
  3457. localizationText['de']['avg_damage_dealt'] = 'Schaden verursacht';
  3458. localizationText['de']['avg_frags'] = 'Zerstörte Kriegsschiffe';
  3459. localizationText['de']['avg_planes_killed'] = 'Flugzeuge abgeschossen';
  3460. localizationText['de']['avg_capture_points'] = 'Basiseroberung';
  3461. localizationText['de']['avg_dropped_capture_points'] = 'Basisverteidigung';
  3462.  
  3463. localizationText['de']['stat-table-3'] = 'Rekordpunktzahl';
  3464. localizationText['de']['max_xp'] = 'Erfahrung';
  3465. localizationText['de']['max_damage_dealt'] = 'Schaden verursacht';
  3466. localizationText['de']['max_frags_battle'] = 'Zerstörte Kriegsschiffe';
  3467. localizationText['de']['max_planes_killed'] = 'Flugzeuge abgeschossen';
  3468. localizationText['de']['stat-table-4'] = 'Weitere Ergebnisse';
  3469. localizationText['de']['battles_days'] = 'Battles pro Tag';
  3470. localizationText['de']['max_ship_level'] = 'Die maximale Stufe der Schiffs';
  3471. localizationText['de']['avg_battles_level'] = 'Durchschnittliche Tier von Kriegsschiffen durch Spieler verwendet';
  3472. localizationText['de']['number-ships-x'] = 'Anzahl der X Tier Schiffe';
  3473. localizationText['de']['wr'] = 'WR';
  3474. localizationText['de']['ships_stat'] = 'Detaillierte Schiffstatistik';
  3475. localizationText['de']['title_ships'] = 'Kriegsschiffe';
  3476. localizationText['de']['battleship'] = 'Schlachtschiffe';
  3477. localizationText['de']['aircarrier'] = 'Flugzeugträger';
  3478. localizationText['de']['cruiser'] = 'Kreuzer';
  3479. localizationText['de']['destroyer'] = 'Zerstörer';
  3480. }
  3481. {/* Türkçe */
  3482. localizationText['tr'] = [];
  3483. localizationText['tr'] = jQ.extend([], localizationText['en']);
  3484. localizationText['tr']['num-separator'] = '.';
  3485. localizationText['tr']['num-fractional'] = ',';
  3486. localizationText['tr']['pvp_solo'] = 'Solo';
  3487. localizationText['tr']['pvp_div'] = 'Bölünme';
  3488. localizationText['tr']['title_battles'] = 'Katılınan Savaşlar';
  3489. localizationText['tr']['title_wins_percents'] = 'Zaferler/Savaşlar';
  3490. localizationText['tr']['title_avg_xp'] = 'SAVAŞ BAŞINA ORTALAMA DENEYİM';
  3491. localizationText['tr']['title_avg_damage_dealt'] = 'Savaş Başına Ortalama Verilen Hasar';
  3492. localizationText['tr']['title_kill_dead'] = 'Yok Etme/Ölüm Oranı';
  3493. localizationText['tr']['title_wr'] = 'WR';
  3494. localizationText['tr']['title_avg_battles_level'] = 'Oyuncu tarafından kullanılan savaş gemilerinin ortalama katmanlı';
  3495. localizationText['tr']['title_avg_frags'] = 'Savaş için ortalama yıkılan gemiler';
  3496. localizationText['tr']['title_avg_planes_killed'] = 'Mücadele için ortalama tahrip uçaklar';
  3497.  
  3498. localizationText['tr']['stat-table-1'] = 'Genel Sonuçlar';
  3499. localizationText['tr']['battles'] = 'Savaşlar';
  3500. localizationText['tr']['wins'] = 'Zaferler';
  3501. localizationText['tr']['survived_battles'] = 'Canlı kalınan savaşlar';
  3502. localizationText['tr']['damage_dealt'] = 'Verilen hasar';
  3503. localizationText['tr']['frags'] = 'Yok edilen savaş gemileri';
  3504. localizationText['tr']['planes_killed'] = 'Yok edilen uçak';
  3505. localizationText['tr']['capture_points'] = 'Üs işgali';
  3506. localizationText['tr']['dropped_capture_points'] = 'Üs savunması';
  3507.  
  3508. localizationText['tr']['stat-table-2'] = 'Savaş Başına Ortalama Skor';
  3509. localizationText['tr']['avg_xp'] = 'Deneyim';
  3510. localizationText['tr']['avg_damage_dealt'] = 'Verilen hasar';
  3511. localizationText['tr']['avg_frags'] = 'Yok edilen savaş gemileri';
  3512. localizationText['tr']['avg_planes_killed'] = 'Yok edilen uçak';
  3513. localizationText['tr']['avg_capture_points'] = 'Üs işgali';
  3514. localizationText['tr']['avg_dropped_capture_points'] = 'Üs savunması';
  3515.  
  3516. localizationText['tr']['stat-table-3'] = 'En Yüksek Skor';
  3517. localizationText['tr']['max_xp'] = 'Deneyim';
  3518. localizationText['tr']['max_damage_dealt'] = 'Verilen hasar';
  3519. localizationText['tr']['max_frags_battle'] = 'Yok edilen savaş gemileri';
  3520. localizationText['tr']['max_planes_killed'] = 'Yok edilen uçak';
  3521. localizationText['tr']['stat-table-4'] = 'Ek Sonuçlar';
  3522. localizationText['tr']['battles_days'] = 'Günde Savaşları';
  3523. localizationText['tr']['max_ship_level'] = 'Geminin maksimum katmanlı';
  3524. localizationText['tr']['avg_battles_level'] = 'Oyuncu tarafından kullanılan savaş gemilerinin ortalama katmanlı';
  3525. localizationText['tr']['number-ships-x'] = 'X Tier gemilerin sayısı';
  3526. localizationText['tr']['wr'] = 'WR';
  3527. localizationText['tr']['ships_stat'] = 'Detaylı Gemi İstatistikleri';
  3528. localizationText['tr']['title_ships'] = 'Savaş Gemileri';
  3529. localizationText['tr']['battleship'] = 'Zırhlılar';
  3530. localizationText['tr']['aircarrier'] = 'Uçak gemileri';
  3531. localizationText['tr']['cruiser'] = 'Kruvazörler';
  3532. localizationText['tr']['destroyer'] = 'Muhripler';
  3533. }
  3534. {/* Español EU */
  3535. localizationText['es'] = [];
  3536. localizationText['es'] = jQ.extend([], localizationText['en']);
  3537. localizationText['es']['num-separator'] = '.';
  3538. localizationText['es']['num-fractional'] = ',';
  3539. localizationText['es']['pvp_solo'] = 'Solo';
  3540. localizationText['es']['pvp_div'] = 'División';
  3541. localizationText['es']['title_battles'] = 'Batallas jugadas';
  3542. localizationText['es']['title_wins_percents'] = 'Victorias/batallas';
  3543. localizationText['es']['title_avg_xp'] = 'EXPERIENCIA MEDIA POR BATALLA';
  3544. localizationText['es']['title_avg_damage_dealt'] = 'Daño medio causado por batalla';
  3545. localizationText['es']['title_kill_dead'] = 'Tasa muertos/muertes';
  3546. localizationText['es']['title_wr'] = 'WR';
  3547. localizationText['es']['title_avg_battles_level'] = 'Niveles promedio de los buques de guerra utilizado por jugador';
  3548. localizationText['es']['title_avg_frags'] = 'Promedio de barcos destruidos para la batalla';
  3549. localizationText['es']['title_avg_planes_killed'] = 'Aviones promedio destruido por la lucha';
  3550.  
  3551. localizationText['es']['stat-table-1'] = 'Resultados generales';
  3552. localizationText['es']['battles'] = 'Batallas';
  3553. localizationText['es']['wins'] = 'Victorias';
  3554. localizationText['es']['survived_battles'] = 'Batallas como superviviente';
  3555. localizationText['es']['damage_dealt'] = 'Daño causado';
  3556. localizationText['es']['frags'] = 'Barcos de guerra destruidos';
  3557. localizationText['es']['planes_killed'] = 'Aviones destruidos';
  3558. localizationText['es']['capture_points'] = 'Captura de base';
  3559. localizationText['es']['dropped_capture_points'] = 'Defensa de base';
  3560.  
  3561. localizationText['es']['stat-table-2'] = 'Puntuación media por batalla';
  3562. localizationText['es']['avg_xp'] = 'Experiencia';
  3563. localizationText['es']['avg_damage_dealt'] = 'Daño causado';
  3564. localizationText['es']['avg_frags'] = 'Barcos de guerra destruidos';
  3565. localizationText['es']['avg_planes_killed'] = 'Aviones destruidos';
  3566. localizationText['es']['avg_capture_points'] = 'Captura de base';
  3567. localizationText['es']['avg_dropped_capture_points'] = 'Defensa de base';
  3568.  
  3569. localizationText['es']['stat-table-3'] = 'En Yüksek Skor';
  3570. localizationText['es']['max_xp'] = 'Experiencia';
  3571. localizationText['es']['max_damage_dealt'] = 'Daño causado';
  3572. localizationText['es']['max_frags_battle'] = 'Barcos de guerra destruidos';
  3573. localizationText['es']['max_planes_killed'] = 'Aviones destruidos';
  3574. localizationText['es']['stat-table-4'] = 'Resultados adicionales';
  3575. localizationText['es']['battles_days'] = 'Batallas por día';
  3576. localizationText['es']['max_ship_level'] = 'El nivel máximo de la nave';
  3577. localizationText['es']['avg_battles_level'] = 'Niveles promedio de los buques de guerra utilizado por jugador';
  3578. localizationText['es']['number-ships-x'] = 'Número de buques de Nivel X';
  3579. localizationText['es']['wr'] = 'WR';
  3580. localizationText['es']['ships_stat'] = 'Estadísticas detalladas del barco';
  3581. localizationText['es']['title_ships'] = 'Barcos';
  3582. localizationText['es']['battleship'] = 'Acorazados';
  3583. localizationText['es']['aircarrier'] = 'Portaaviones';
  3584. localizationText['es']['cruiser'] = 'Cruceros';
  3585. localizationText['es']['destroyer'] = 'Destructores';
  3586. }
  3587. {/* Español NA */
  3588. localizationText['es-mx'] = [];
  3589. localizationText['es-mx'] = jQ.extend([], localizationText['en']);
  3590. localizationText['es-mx']['num-separator'] = ' ';
  3591. localizationText['es-mx']['num-fractional'] = '.';
  3592. localizationText['es-mx']['pvp_solo'] = 'Solo';
  3593. localizationText['es-mx']['pvp_div'] = 'División';
  3594. localizationText['es-mx']['title_battles'] = 'Batallas Luchadas';
  3595. localizationText['es-mx']['title_wins_percents'] = 'Victorias';
  3596. localizationText['es-mx']['title_avg_xp'] = 'EXPERIENCIA PROMEDIO POR BATALLA';
  3597. localizationText['es-mx']['title_avg_damage_dealt'] = 'Daño en Promedio Causado por Batalla';
  3598. localizationText['es-mx']['title_kill_dead'] = 'Radio de Destrucción / Muerte';
  3599. localizationText['es-mx']['title_wr'] = 'WR';
  3600. localizationText['es-mx']['title_avg_battles_level'] = 'Niveles promedio de los buques de guerra utilizado por jugador';
  3601. localizationText['es-mx']['title_avg_frags'] = 'Promedio de barcos destruidos para la batalla';
  3602. localizationText['es-mx']['title_avg_planes_killed'] = 'Aviones promedio destruido por la lucha';
  3603.  
  3604. localizationText['es-mx']['stat-table-1'] = 'Resultados en General';
  3605. localizationText['es-mx']['battles'] = 'Batallas';
  3606. localizationText['es-mx']['wins'] = 'Victorias';
  3607. localizationText['es-mx']['survived_battles'] = 'Batallas sobrevividas';
  3608. localizationText['es-mx']['damage_dealt'] = 'Daño causado';
  3609. localizationText['es-mx']['frags'] = 'Barcos de guerra destruidos';
  3610. localizationText['es-mx']['planes_killed'] = 'Aviones destruidos';
  3611. localizationText['es-mx']['capture_points'] = 'Captura de base';
  3612. localizationText['es-mx']['dropped_capture_points'] = 'Defensa de base';
  3613.  
  3614. localizationText['es-mx']['stat-table-2'] = 'Resultados promedio por batalla';
  3615. localizationText['es-mx']['avg_xp'] = 'XP';
  3616. localizationText['es-mx']['avg_damage_dealt'] = 'Daño causado';
  3617. localizationText['es-mx']['avg_frags'] = 'Barcos de guerra destruidos';
  3618. localizationText['es-mx']['avg_planes_killed'] = 'Aviones destruidos';
  3619. localizationText['es-mx']['avg_capture_points'] = 'Captura de base';
  3620. localizationText['es-mx']['avg_dropped_capture_points'] = 'Defensa de base';
  3621.  
  3622. localizationText['es-mx']['stat-table-3'] = 'Puntaje más Alto';
  3623. localizationText['es-mx']['max_xp'] = 'XP';
  3624. localizationText['es-mx']['max_damage_dealt'] = 'Daño causado';
  3625. localizationText['es-mx']['max_frags_battle'] = 'Barcos de guerra destruidos';
  3626. localizationText['es-mx']['max_planes_killed'] = 'Aviones destruidos';
  3627. localizationText['es-mx']['stat-table-4'] = 'Resultados adicionales';
  3628. localizationText['es-mx']['battles_days'] = 'Batallas por día';
  3629. localizationText['es-mx']['max_ship_level'] = 'El nivel máximo de la nave';
  3630. localizationText['es-mx']['avg_battles_level'] = 'Niveles promedio de los buques de guerra utilizado por jugador';
  3631. localizationText['es-mx']['number-ships-x'] = 'Número de buques de Nivel X';
  3632. localizationText['es-mx']['wr'] = 'WR';
  3633. localizationText['es-mx']['ships_stat'] = 'Estadísticas detalladas de los Barcos de Guerra';
  3634. localizationText['es-mx']['title_ships'] = 'Barcos de Guerra';
  3635. localizationText['es-mx']['battleship'] = 'Acorazados';
  3636. localizationText['es-mx']['aircarrier'] = 'Portaaviones';
  3637. localizationText['es-mx']['cruiser'] = 'Cruceros';
  3638. localizationText['es-mx']['destroyer'] = 'Destructores';
  3639. }
  3640. {/* Português */
  3641. localizationText['pt-br'] = [];
  3642. localizationText['pt-br'] = jQ.extend([], localizationText['en']);
  3643. localizationText['pt-br']['num-separator'] = '.';
  3644. localizationText['pt-br']['num-fractional'] = ',';
  3645. localizationText['pt-br']['pvp_solo'] = 'Solo';
  3646. localizationText['pt-br']['pvp_div'] = 'Divisão';
  3647. localizationText['pt-br']['title_battles'] = 'Batalhas Disputadas';
  3648. localizationText['pt-br']['title_wins_percents'] = 'Taxa de Vitórias/Batalhas';
  3649. localizationText['pt-br']['title_avg_xp'] = 'EXPERIÊNCIA MÉDIA POR BATALHA';
  3650. localizationText['pt-br']['title_avg_damage_dealt'] = 'Dano Médio Causado por Batalha';
  3651. localizationText['pt-br']['title_kill_dead'] = 'Taxa de Morte/Destruição';
  3652. localizationText['pt-br']['title_wr'] = 'WR';
  3653. localizationText['pt-br']['title_avg_battles_level'] = 'Nível médio de navios de guerra usados por jogador';
  3654. localizationText['pt-br']['title_avg_frags'] = 'Navios médios destruído por batalha';
  3655. localizationText['pt-br']['title_avg_planes_killed'] = 'Aeronaves média destruído para a luta';
  3656.  
  3657. localizationText['pt-br']['stat-table-1'] = 'Resultados Gerais';
  3658. localizationText['pt-br']['battles'] = 'Batalhas';
  3659. localizationText['pt-br']['wins'] = 'Vitórias';
  3660. localizationText['pt-br']['survived_battles'] = 'Batalhas Sobrevividas';
  3661. localizationText['pt-br']['damage_dealt'] = 'Dano Causado';
  3662. localizationText['pt-br']['frags'] = 'Navios Destruídos';
  3663. localizationText['pt-br']['planes_killed'] = 'Aeronaves Destruídas';
  3664. localizationText['pt-br']['capture_points'] = 'Captura de Base';
  3665. localizationText['pt-br']['dropped_capture_points'] = 'Defesa de Base';
  3666.  
  3667. localizationText['pt-br']['stat-table-2'] = 'Pontuação Média por Batalha';
  3668. localizationText['pt-br']['avg_xp'] = 'Experiência';
  3669. localizationText['pt-br']['avg_damage_dealt'] = 'Dano Causado';
  3670. localizationText['pt-br']['avg_frags'] = 'Navios Destruídos';
  3671. localizationText['pt-br']['avg_planes_killed'] = 'Aeronaves Destruídas';
  3672. localizationText['pt-br']['avg_capture_points'] = 'Captura de Base';
  3673. localizationText['pt-br']['avg_dropped_capture_points'] = 'Defesa de Base';
  3674.  
  3675. localizationText['pt-br']['stat-table-3'] = 'Pontuação Recorde';
  3676. localizationText['pt-br']['max_xp'] = 'Experiência';
  3677. localizationText['pt-br']['max_damage_dealt'] = 'Dano Causado';
  3678. localizationText['pt-br']['max_frags_battle'] = 'Navios Destruídos';
  3679. localizationText['pt-br']['max_planes_killed'] = 'Aeronaves Destruídas';
  3680. localizationText['pt-br']['stat-table-4'] = 'Resultados adicionais';
  3681. localizationText['pt-br']['battles_days'] = 'Batalhas por dia';
  3682. localizationText['pt-br']['max_ship_level'] = 'O nível máximo de navio';
  3683. localizationText['pt-br']['avg_battles_level'] = 'Nível médio de navios de guerra usados por jogador';
  3684. localizationText['pt-br']['number-ships-x'] = 'Número de X navios de Nível';
  3685. localizationText['pt-br']['wr'] = 'WR';
  3686. localizationText['pt-br']['ships_stat'] = 'Estatísticas Detalhadas de Navios';
  3687. localizationText['pt-br']['title_ships'] = 'Navios';
  3688. localizationText['pt-br']['battleship'] = 'Encouraçados';
  3689. localizationText['pt-br']['aircarrier'] = 'Porta-aviões';
  3690. localizationText['pt-br']['cruiser'] = 'Cruzadores';
  3691. localizationText['pt-br']['destroyer'] = 'Contratorpedeiros';
  3692. }
  3693. {/* Čeština */
  3694. localizationText['cs'] = [];
  3695. localizationText['cs'] = jQ.extend([], localizationText['en']);
  3696. localizationText['cs']['num-separator'] = ' ';
  3697. localizationText['cs']['num-fractional'] = ',';
  3698. localizationText['cs']['pvp_solo'] = 'Solo';
  3699. localizationText['cs']['pvp_div'] = 'Divize';
  3700. localizationText['cs']['title_battles'] = 'Odehráno bitev';
  3701. localizationText['cs']['title_wins_percents'] = 'Poměr Vítězství/Bitev';
  3702. localizationText['cs']['title_avg_xp'] = 'PRŮMĚRNÉ ZKUŠENOSTI ZA BITVU';
  3703. localizationText['cs']['title_avg_damage_dealt'] = 'Průměrné poškození způsobené za bitvu';
  3704. localizationText['cs']['title_kill_dead'] = 'Poměr Zabití/Smrtí';
  3705. localizationText['cs']['title_wr'] = 'WR';
  3706. localizationText['cs']['title_avg_battles_level'] = 'Průměrná vrstva válečných lodí používaný přehrávačem';
  3707. localizationText['cs']['title_avg_frags'] = 'Průměrné Zničené lodě pro boj';
  3708. localizationText['cs']['title_avg_planes_killed'] = 'Průměrná Zničená letadla pro boj';
  3709.  
  3710. localizationText['cs']['stat-table-1'] = 'Celkové výsledky';
  3711. localizationText['cs']['battles'] = 'Bitvy';
  3712. localizationText['cs']['wins'] = 'Vítězství';
  3713. localizationText['cs']['survived_battles'] = 'Přežito bitev';
  3714. localizationText['cs']['damage_dealt'] = 'Způsobené poškození';
  3715. localizationText['cs']['frags'] = 'Lodí zničeno';
  3716. localizationText['cs']['planes_killed'] = 'Letadel zničeno';
  3717. localizationText['cs']['capture_points'] = 'Body za obsazování základny';
  3718. localizationText['cs']['dropped_capture_points'] = 'Body za obranu základny';
  3719.  
  3720. localizationText['cs']['stat-table-2'] = 'Průměrné skóre za bitvu';
  3721. localizationText['cs']['avg_xp'] = 'Zkušenosti';
  3722. localizationText['cs']['avg_damage_dealt'] = 'Způsobené poškození';
  3723. localizationText['cs']['avg_frags'] = 'Lodí zničeno';
  3724. localizationText['cs']['avg_planes_killed'] = 'Letadel zničeno';
  3725. localizationText['cs']['avg_capture_points'] = 'Body za obsazování základny';
  3726. localizationText['cs']['avg_dropped_capture_points'] = 'Body za obranu základny';
  3727.  
  3728. localizationText['cs']['stat-table-3'] = 'Rekordní skóre';
  3729. localizationText['cs']['max_xp'] = 'Zkušenosti';
  3730. localizationText['cs']['max_damage_dealt'] = 'Způsobené poškození';
  3731. localizationText['cs']['max_frags_battle'] = 'Lodí zničeno';
  3732. localizationText['cs']['max_planes_killed'] = 'Letadel zničeno';
  3733. localizationText['cs']['stat-table-4'] = 'Další výsledky';
  3734. localizationText['cs']['battles_days'] = 'Bitvy za den';
  3735. localizationText['cs']['max_ship_level'] = 'Maximální vrstva lodi';
  3736. localizationText['cs']['avg_battles_level'] = 'Průměrná vrstva válečných lodí používaný přehrávačem';
  3737. localizationText['cs']['number-ships-x'] = 'Počet X Tier lodí';
  3738. localizationText['cs']['wr'] = 'WR';
  3739. localizationText['cs']['ships_stat'] = 'Podrobné statistiky lodě';
  3740. localizationText['cs']['title_ships'] = 'Lodě';
  3741. localizationText['cs']['battleship'] = 'Bitevní lodě';
  3742. localizationText['cs']['aircarrier'] = 'Letadlové lodě';
  3743. localizationText['cs']['cruiser'] = 'Křižníky';
  3744. localizationText['cs']['destroyer'] = 'Torpédoborce';
  3745. }
  3746. {/* Polski */
  3747. localizationText['pl'] = [];
  3748. localizationText['pl'] = jQ.extend([], localizationText['en']);
  3749. localizationText['pl']['num-separator'] = ' ';
  3750. localizationText['pl']['num-fractional'] = ',';
  3751. localizationText['pl']['pvp_solo'] = 'Solo';
  3752. localizationText['pl']['pvp_div'] = 'Podział';
  3753. localizationText['pl']['title_battles'] = 'Stoczone bitwy';
  3754. localizationText['pl']['title_wins_percents'] = 'Stosunek zwycięstw do wszystkich bitew';
  3755. localizationText['pl']['title_avg_xp'] = 'ŚREDNIE DOŚWIADCZENIE NA BITWĘ';
  3756. localizationText['pl']['title_avg_damage_dealt'] = 'Średnie uszkodzenia zadane na bitwę';
  3757. localizationText['pl']['title_kill_dead'] = 'Stosunek zniszczonych przeciwników/własnych zniszczeń';
  3758. localizationText['pl']['title_wr'] = 'WR';
  3759. localizationText['pl']['title_avg_battles_level'] = 'Průměrná vrstva válečných lodí používaný přehrávačem';
  3760. localizationText['pl']['title_avg_frags'] = 'Średnie Zniszczone statki do boju';
  3761. localizationText['pl']['title_avg_planes_killed'] = 'Średnia Zniszczony samolot do walki';
  3762.  
  3763. localizationText['pl']['stat-table-1'] = 'Ogólne wyniki';
  3764. localizationText['pl']['battles'] = 'Bitwy';
  3765. localizationText['pl']['wins'] = 'Zwycięstwa';
  3766. localizationText['pl']['survived_battles'] = 'Przetrwane bitwy';
  3767. localizationText['pl']['damage_dealt'] = 'Zadane uszkodzenia';
  3768. localizationText['pl']['frags'] = 'Zniszczone okręty';
  3769. localizationText['pl']['planes_killed'] = 'Zniszczone samoloty';
  3770. localizationText['pl']['capture_points'] = 'Zajęcie bazy';
  3771. localizationText['pl']['dropped_capture_points'] = 'Obrona bazy';
  3772.  
  3773. localizationText['pl']['stat-table-2'] = 'Średnie doświadczenie w bitwie';
  3774. localizationText['pl']['avg_xp'] = 'Doświadczenie';
  3775. localizationText['pl']['avg_damage_dealt'] = 'Zadane uszkodzenia';
  3776. localizationText['pl']['avg_frags'] = 'Zniszczone okręty';
  3777. localizationText['pl']['avg_planes_killed'] = 'Zniszczone samoloty';
  3778. localizationText['pl']['avg_capture_points'] = 'Zajęcie bazy';
  3779. localizationText['pl']['avg_dropped_capture_points'] = 'Obrona bazy';
  3780.  
  3781. localizationText['pl']['stat-table-3'] = 'Rekordowy wynik';
  3782. localizationText['pl']['max_xp'] = 'Doświadczenie';
  3783. localizationText['pl']['max_damage_dealt'] = 'Zadane uszkodzenia';
  3784. localizationText['pl']['max_frags_battle'] = 'Zniszczone okręty';
  3785. localizationText['pl']['max_planes_killed'] = 'Zniszczone samoloty';
  3786. localizationText['pl']['stat-table-4'] = 'Další výsledky';
  3787. localizationText['pl']['battles_days'] = 'Bitvy za den';
  3788. localizationText['pl']['max_ship_level'] = 'Maximální vrstva lodi';
  3789. localizationText['pl']['avg_battles_level'] = 'Průměrná vrstva válečných lodí používaný přehrávačem';
  3790. localizationText['pl']['number-ships-x'] = 'Ilość X statków Tier';
  3791. localizationText['pl']['wr'] = 'WR';
  3792. localizationText['pl']['ships_stat'] = 'Szczegółowe statystyki okrętu';
  3793. localizationText['pl']['title_ships'] = 'Okręty';
  3794. localizationText['pl']['battleship'] = 'Pancerniki';
  3795. localizationText['pl']['aircarrier'] = 'Lotniskowce';
  3796. localizationText['pl']['cruiser'] = 'Krążowniki';
  3797. localizationText['pl']['destroyer'] = 'Niszczyciele';
  3798. }
  3799. {/* 日本語 */
  3800. localizationText['ja'] = [];
  3801. localizationText['ja'] = jQ.extend([], localizationText['en']);
  3802. localizationText['ja']['num-separator'] = '';
  3803. localizationText['ja']['num-fractional'] = '.';
  3804. localizationText['ja']['pvp_solo'] = 'ソロ';
  3805. localizationText['ja']['pvp_div'] = '課';
  3806. localizationText['ja']['title_battles'] = '参加戦闘数';
  3807. localizationText['ja']['title_wins_percents'] = '勝利数/戦闘数';
  3808. localizationText['ja']['title_avg_xp'] = '1 戦あたりの平均経験値';
  3809. localizationText['ja']['title_avg_damage_dealt'] = '1 戦あたりの平均与ダメージ';
  3810. localizationText['ja']['title_kill_dead'] = 'キル/デス比';
  3811. localizationText['ja']['title_wr'] = 'WR';
  3812. localizationText['ja']['title_avg_battles_level'] = 'プレイヤーが使用する軍艦の平均ティア';
  3813. localizationText['ja']['title_avg_frags'] = '戦いの平均破壊された船';
  3814. localizationText['ja']['title_avg_planes_killed'] = '戦いの平均破壊された航空機';
  3815.  
  3816. localizationText['ja']['stat-table-1'] = '総合結果';
  3817. localizationText['ja']['battles'] = '戦闘数';
  3818. localizationText['ja']['wins'] = '勝利';
  3819. localizationText['ja']['survived_battles'] = '生還した戦闘数';
  3820. localizationText['ja']['damage_dealt'] = '与ダメージ';
  3821. localizationText['ja']['frags'] = '艦船撃沈';
  3822. localizationText['ja']['planes_killed'] = '航空機撃墜';
  3823. localizationText['ja']['capture_points'] = '陣地占領';
  3824. localizationText['ja']['dropped_capture_points'] = '陣地防衛';
  3825.  
  3826. localizationText['ja']['stat-table-2'] = '1 戦あたりの平均スコア';
  3827. localizationText['ja']['avg_xp'] = '経験値';
  3828. localizationText['ja']['avg_damage_dealt'] = '与ダメージ';
  3829. localizationText['ja']['avg_frags'] = '艦船撃沈';
  3830. localizationText['ja']['avg_planes_killed'] = '航空機撃墜';
  3831. localizationText['ja']['avg_capture_points'] = '陣地占領';
  3832. localizationText['ja']['avg_dropped_capture_points'] = '陣地防衛';
  3833.  
  3834. localizationText['ja']['stat-table-3'] = '最高スコア';
  3835. localizationText['ja']['max_xp'] = '経験値';
  3836. localizationText['ja']['max_damage_dealt'] = '与ダメージ';
  3837. localizationText['ja']['max_frags_battle'] = '艦船撃沈';
  3838. localizationText['ja']['max_planes_killed'] = '航空機撃墜';
  3839. localizationText['ja']['stat-table-4'] = '追加の結果';
  3840. localizationText['ja']['battles_days'] = '一日あたりの戦い';
  3841. localizationText['ja']['max_ship_level'] = '船の最大ティア';
  3842. localizationText['ja']['avg_battles_level'] = 'プレイヤーが使用する軍艦の平均ティア';
  3843. localizationText['ja']['number-ships-x'] = 'Xティア船の数';
  3844. localizationText['ja']['wr'] = 'WR';
  3845. localizationText['ja']['ships_stat'] = '艦の詳細戦績';
  3846. localizationText['ja']['title_ships'] = '艦';
  3847. localizationText['ja']['battleship'] = '戦艦';
  3848. localizationText['ja']['aircarrier'] = '航空母艦';
  3849. localizationText['ja']['cruiser'] = '巡洋艦';
  3850. localizationText['ja']['destroyer'] = '駆逐艦';
  3851. }
  3852. {/* ไทย */
  3853. localizationText['th'] = [];
  3854. localizationText['th'] = jQ.extend([], localizationText['en']);
  3855. localizationText['th']['num-separator'] = '';
  3856. localizationText['th']['num-fractional'] = '.';
  3857. localizationText['th']['pvp_solo'] = 'โซโล';
  3858. localizationText['th']['pvp_div'] = 'แผนก';
  3859. localizationText['th']['title_battles'] = 'การรบที่เข้าร่วม';
  3860. localizationText['th']['title_wins_percents'] = 'อัตราชัยชนะ/การรบ';
  3861. localizationText['th']['title_avg_xp'] = 'ค่าประสบการณ์โดยเฉลี่ยต่อการรบ';
  3862. localizationText['th']['title_avg_damage_dealt'] = 'ความเสียหายที่ทำโดยเฉลี่ยต่อการรบ';
  3863. localizationText['th']['title_kill_dead'] = 'อัตราสังหาร/เสียชีวิต';
  3864. localizationText['th']['title_wr'] = 'WR';
  3865. localizationText['th']['title_avg_battles_level'] = 'ชั้นเฉลี่ยของเรือรบที่ใช้โดยผู้เล่น';
  3866. localizationText['th']['title_avg_frags'] = 'เรือถูกทำลายเฉลี่ยสำหรับการต่อสู้';
  3867. localizationText['th']['title_avg_planes_killed'] = 'เครื่องบินถูกทำลายเฉลี่ยสำหรับการต่อสู้';
  3868.  
  3869. localizationText['th']['stat-table-1'] = 'ผลรวม';
  3870. localizationText['th']['battles'] = 'การรบ';
  3871. localizationText['th']['wins'] = 'ชัยชนะ';
  3872. localizationText['th']['survived_battles'] = 'จำนวนการรอดจากการรบ';
  3873. localizationText['th']['damage_dealt'] = 'ความเสียหายที่ทำ';
  3874. localizationText['th']['frags'] = 'เรือรบที่ถูกทำลาย';
  3875. localizationText['th']['planes_killed'] = 'เครื่องบินที่ถูกทำลาย';
  3876. localizationText['th']['capture_points'] = 'การยึดฐาน';
  3877. localizationText['th']['dropped_capture_points'] = 'การป้องกันฐาน';
  3878.  
  3879. localizationText['th']['stat-table-2'] = 'คะแนนเฉลี่ยต่อการรบ';
  3880. localizationText['th']['avg_xp'] = 'ค่าประสบการณ์';
  3881. localizationText['th']['avg_damage_dealt'] = 'ความเสียหายที่ทำ';
  3882. localizationText['th']['avg_frags'] = 'เรือรบที่ถูกทำลาย';
  3883. localizationText['th']['avg_planes_killed'] = 'เครื่องบินที่ถูกทำลาย';
  3884. localizationText['th']['avg_capture_points'] = 'การยึดฐาน';
  3885. localizationText['th']['avg_dropped_capture_points'] = 'การป้องกันฐาน';
  3886.  
  3887. localizationText['th']['stat-table-3'] = 'สถิติคะแนน';
  3888. localizationText['th']['max_xp'] = 'ค่าประสบการณ์';
  3889. localizationText['th']['max_damage_dealt'] = 'ความเสียหายที่ทำ';
  3890. localizationText['th']['max_frags_battle'] = 'เรือรบที่ถูกทำลาย';
  3891. localizationText['th']['max_planes_killed'] = 'เครื่องบินที่ถูกทำลาย';
  3892. localizationText['th']['stat-table-4'] = 'ผลเพิ่มเติม';
  3893. localizationText['th']['battles_days'] = 'สงครามต่อวัน';
  3894. localizationText['th']['max_ship_level'] = 'ชั้นสูงสุดของเรือ';
  3895. localizationText['th']['avg_battles_level'] = 'ชั้นเฉลี่ยของเรือรบที่ใช้โดยผู้เล่น';
  3896. localizationText['th']['number-ships-x'] = 'จำนวน X เรือชั้นที่';
  3897. localizationText['th']['wr'] = 'WR';
  3898. localizationText['th']['ships_stat'] = 'สถิติเรือรบโดยละเอียด';
  3899. localizationText['th']['title_ships'] = 'เรือรบ';
  3900. localizationText['th']['battleship'] = 'เรือประจัญบาน';
  3901. localizationText['th']['aircarrier'] = 'เรือบรรทุกเครื่องบิน';
  3902. localizationText['th']['cruiser'] = 'เรือลาดตระเวณ';
  3903. localizationText['th']['destroyer'] = 'เรือพิฆาต';
  3904. }
  3905. {/* Tiếng Việt */
  3906. localizationText['vi'] = [];
  3907. localizationText['vi'] = jQ.extend([], localizationText['en']);
  3908. localizationText['vi']['num-separator'] = '';
  3909. localizationText['vi']['num-fractional'] = ',';
  3910. localizationText['vi']['num-separator'] = '';
  3911. localizationText['vi']['num-fractional'] = '.';
  3912. localizationText['vi']['pvp_solo'] = 'Solo';
  3913. localizationText['vi']['pvp_div'] = 'Phòng';
  3914. localizationText['vi']['title_battles'] = 'Số trận Tham chiến';
  3915. localizationText['vi']['title_wins_percents'] = 'Chiến thắng / Số trận';
  3916. localizationText['vi']['title_avg_xp'] = 'KINH NGHIỆM TRUNG BÌNH MỖI TRẬN';
  3917. localizationText['vi']['title_avg_damage_dealt'] = 'Thiệt hại Gây ra Trung bình mỗi Trận';
  3918. localizationText['vi']['title_kill_dead'] = 'Tỷ lệ Tiêu diệt/Bị Tiêu diệt';
  3919. localizationText['vi']['title_wr'] = 'WR';
  3920. localizationText['vi']['title_avg_battles_level'] = 'Tier trung bình của các tàu chiến được sử dụng bởi người chơi';
  3921. localizationText['vi']['title_avg_frags'] = 'Tàu Trung bình bị phá hủy trong trận chiến';
  3922. localizationText['vi']['title_avg_planes_killed'] = 'Máy bay bị phá hủy trung bình cho cuộc chiến';
  3923.  
  3924. localizationText['vi']['stat-table-1'] = 'Kết quả Tổng quan';
  3925. localizationText['vi']['battles'] = 'Số trận';
  3926. localizationText['vi']['wins'] = 'Chiến thắng';
  3927. localizationText['vi']['survived_battles'] = 'Số trận sống sót';
  3928. localizationText['vi']['damage_dealt'] = 'Thiệt hại đã gây ra';
  3929. localizationText['vi']['frags'] = 'Tàu chiến đã tiêu diệt';
  3930. localizationText['vi']['planes_killed'] = 'Phi cơ đã tiêu diệt';
  3931. localizationText['vi']['capture_points'] = 'Chiếm căn cứ';
  3932. localizationText['vi']['dropped_capture_points'] = 'Phòng thủ căn cứ';
  3933.  
  3934. localizationText['vi']['stat-table-2'] = 'Điểm Trung bình mỗi Trận';
  3935. localizationText['vi']['avg_xp'] = 'Kinh nghiệm';
  3936. localizationText['vi']['avg_damage_dealt'] = 'Thiệt hại đã gây ra';
  3937. localizationText['vi']['avg_frags'] = 'Tàu chiến đã tiêu diệt';
  3938. localizationText['vi']['avg_planes_killed'] = 'Phi cơ đã tiêu diệt';
  3939. localizationText['vi']['avg_capture_points'] = 'Chiếm căn cứ';
  3940. localizationText['vi']['avg_dropped_capture_points'] = 'Phòng thủ căn cứ';
  3941.  
  3942. localizationText['vi']['stat-table-3'] = 'Điểm Kỷ lục';
  3943. localizationText['vi']['max_xp'] = 'Kinh nghiệm';
  3944. localizationText['vi']['max_damage_dealt'] = 'Thiệt hại đã gây ra';
  3945. localizationText['vi']['max_frags_battle'] = 'Tàu chiến đã tiêu diệt';
  3946. localizationText['vi']['max_planes_killed'] = 'Phi cơ đã tiêu diệt';
  3947. localizationText['vi']['stat-table-4'] = 'Kết quả bổ sung';
  3948. localizationText['vi']['battles_days'] = 'Trận chiến mỗi ngày';
  3949. localizationText['vi']['max_ship_level'] = 'Cấp tối đa của tàu';
  3950. localizationText['vi']['avg_battles_level'] = 'Tier trung bình của các tàu chiến được sử dụng bởi người chơi';
  3951. localizationText['vi']['number-ships-x'] = 'Số tàu Tier X';
  3952. localizationText['vi']['wr'] = 'WR';
  3953. localizationText['vi']['ships_stat'] = 'Thống kê Tàu chiến Chi tiết';
  3954. localizationText['vi']['title_ships'] = 'Tàu chiến';
  3955. localizationText['vi']['battleship'] = 'Thiết giáp hạm';
  3956. localizationText['vi']['aircarrier'] = 'Tàu sân bay';
  3957. localizationText['vi']['cruiser'] = 'Tuần dương hạm';
  3958. localizationText['vi']['destroyer'] = 'Khu trục hạm';
  3959. }
  3960. {/* 繁體中文 By chunhung 24/12/2015 */
  3961. localizationText['zh-tw'] = [];
  3962. localizationText['zh-tw'] = jQ.extend([], localizationText['en']);
  3963. localizationText['zh-tw']['num-separator'] = '';
  3964. localizationText['zh-tw']['num-fractional'] = '.';
  3965. localizationText['zh-tw']['Box'] = '通知';
  3966. localizationText['zh-tw']['Ok'] = '確定';
  3967. localizationText['zh-tw']['Cancel'] = '取消';
  3968. localizationText['zh-tw']['NewVersion'] = '新版本已經發佈';
  3969. localizationText['zh-tw']['NewUpdate'] = '請更新擴充功能';
  3970. localizationText['zh-tw']['ErrorScript'] = '運行時發生錯誤 UserScript WoWsStatInfo '+VersionWoWsStatInfo+', script:';
  3971. localizationText['zh-tw']['ErrorSendDeveloper'] = '請將此錯誤通知腳本開發者。';
  3972. localizationText['zh-tw']['ErrorAPI'] = '無法取得數據。<br />WG API 存在問題。<br />請嘗試重新載入頁面,或稍後再試。';
  3973. localizationText['zh-tw']['userscript-developer'] = 'Developer - UserScript WoWsStatInfo:';
  3974. localizationText['zh-tw']['userscript-alliance'] = 'аlliance member';
  3975. localizationText['zh-tw']['userscript-topic'] = 'Forum topic:';
  3976. localizationText['zh-tw']['userscript-developer-support'] = 'Ways to support the developer:';
  3977. localizationText['zh-tw']['search-clan-forum'] = 'Clan Search...';
  3978. localizationText['zh-tw']['profile-wows'] = 'World of Warships profile';
  3979. localizationText['zh-tw']['profile-clan'] = 'Clan';
  3980. localizationText['zh-tw']['forum-profile'] = 'Forum profile';
  3981. localizationText['zh-tw']['role'] = '位階';
  3982. localizationText['zh-tw']['clan-day'] = '待在公會的天數';
  3983. localizationText['zh-tw']['generator-userbar'] = '創建簽名檔';
  3984. localizationText['zh-tw']['userbar-bg'] = '選擇背景圖片:';
  3985. localizationText['zh-tw']['userbar-filters'] = '過濾器:';
  3986. localizationText['zh-tw']['filters-all'] = '全部';
  3987. localizationText['zh-tw']['filters-clan'] = '公會';
  3988. localizationText['zh-tw']['filters-noclassification'] = '未分類';
  3989. localizationText['zh-tw']['filters-battleship'] = '主力艦';
  3990. localizationText['zh-tw']['filters-aircarrier'] = '航空母艦';
  3991. localizationText['zh-tw']['filters-cruiser'] = '巡洋艦';
  3992. localizationText['zh-tw']['filters-destroyer'] = '驅逐艦';
  3993. localizationText['zh-tw']['filters-japan'] = '日本';
  3994. localizationText['zh-tw']['filters-ussr'] = '蘇聯';
  3995. localizationText['zh-tw']['filters-germany'] = '德國';
  3996. localizationText['zh-tw']['filters-uk'] = '英國';
  3997. localizationText['zh-tw']['filters-usa'] = '美國';
  3998. localizationText['zh-tw']['userbar-your-background'] = '上傳背景圖片';
  3999. localizationText['zh-tw']['upload-submit'] = '上傳';
  4000. localizationText['zh-tw']['img-max-size'] = '最大容量: 150 KB';
  4001. localizationText['zh-tw']['img-max-px'] = '圖片解析度: 468x100';
  4002. localizationText['zh-tw']['img-format'] = '圖片格式: PNG';
  4003. localizationText['zh-tw']['upload-verification'] = '背景圖片會在驗證後更新。';
  4004. localizationText['zh-tw']['pvp_solo'] = '單獨';
  4005. localizationText['zh-tw']['pvp_div'] = '分艦隊';
  4006. localizationText['zh-tw']['title_battles'] = '參與過戰鬥數';
  4007. localizationText['zh-tw']['title_wins_percents'] = '勝利數/戰鬥數比';
  4008. localizationText['zh-tw']['title_avg_xp'] = '平均每場經驗';
  4009. localizationText['zh-tw']['title_avg_damage_dealt'] = '平均每場造成的傷害';
  4010. localizationText['zh-tw']['title_kill_dead'] = '擊毀/死亡比';
  4011. localizationText['zh-tw']['title_wr'] = 'WR';
  4012. localizationText['zh-tw']['title_avg_battles_level'] = '玩家所用艦艇的平均階級';
  4013. localizationText['zh-tw']['title_avg_frags'] = '平均打掉船舶战斗';
  4014. localizationText['zh-tw']['title_avg_planes_killed'] = '为争平均架被毁飞机';
  4015.  
  4016. localizationText['zh-tw']['stat-table-1'] = '整體成績';
  4017. localizationText['zh-tw']['battles'] = '戰鬥數';
  4018. localizationText['zh-tw']['wins'] = '勝利數';
  4019. localizationText['zh-tw']['survived_battles'] = '存活數';
  4020. localizationText['zh-tw']['damage_dealt'] = '造成的傷害';
  4021. localizationText['zh-tw']['frags'] = '擊毀的艦艇數';
  4022. localizationText['zh-tw']['planes_killed'] = '擊毀飛機數';
  4023. localizationText['zh-tw']['capture_points'] = '佔領點數';
  4024. localizationText['zh-tw']['dropped_capture_points'] = '防禦點數';
  4025.  
  4026. localizationText['zh-tw']['stat-table-2'] = '平均每場戰鬥分數';
  4027. localizationText['zh-tw']['avg_xp'] = '經驗';
  4028. localizationText['zh-tw']['avg_damage_dealt'] = '造成的傷害';
  4029. localizationText['zh-tw']['avg_frags'] = '擊毀的艦艇數';
  4030. localizationText['zh-tw']['avg_planes_killed'] = '擊毀飛機數';
  4031. localizationText['zh-tw']['avg_capture_points'] = '佔領點數';
  4032. localizationText['zh-tw']['avg_dropped_capture_points'] = '防禦點數';
  4033.  
  4034. localizationText['zh-tw']['stat-table-3'] = '紀錄分數';
  4035. localizationText['zh-tw']['max_xp'] = '經驗';
  4036. localizationText['zh-tw']['max_damage_dealt'] = '造成的傷害';
  4037. localizationText['zh-tw']['max_frags_battle'] = '擊毀的艦艇數';
  4038. localizationText['zh-tw']['max_planes_killed'] = '擊毀飛機數';
  4039. localizationText['zh-tw']['stat-table-4'] = '其他結果';
  4040. localizationText['zh-tw']['battles_days'] = '每日戰鬥數';
  4041. localizationText['zh-tw']['max_ship_level'] = '最大艦艇階級';
  4042. localizationText['zh-tw']['avg_battles_level'] = '玩家所用艦艇的平均階級';
  4043. localizationText['zh-tw']['number-ships-x'] = '第X階艦艇數量';
  4044. localizationText['zh-tw']['wr'] = 'WR';
  4045. localizationText['zh-tw']['ships_stat'] = '詳細艦艇統計';
  4046. localizationText['zh-tw']['title_ships'] = '艦艇';
  4047. localizationText['zh-tw']['battleship'] = '主力艦';
  4048. localizationText['zh-tw']['aircarrier'] = '航空母艦';
  4049. localizationText['zh-tw']['cruiser'] = '巡洋艦';
  4050. localizationText['zh-tw']['destroyer'] = '驅逐艦';
  4051. localizationText['zh-tw']['block-link-clan-member-history'] = '「公會成員變化」分段';
  4052. localizationText['zh-tw']['link-clan-member-history'] = '公會成員變化';
  4053. localizationText['zh-tw']['member-history-clear'] = '清除歷史記錄';
  4054. localizationText['zh-tw']['member-history-join'] = '%NAME% 已加入公會';
  4055. localizationText['zh-tw']['member-history-leave'] = '%NAME% 已離開公會';
  4056. localizationText['zh-tw']['member-history-rename'] = '%OLDNAME% 已更改暱稱為 %NEWNAME%';
  4057. localizationText['zh-tw']['member-history-rerole'] = '%NAME% 位階已更變: %OLDROLE% &rArr; %NEWROLE%';
  4058. localizationText['zh-tw']['member-history-notchange'] = '自從安裝WoWsStatInfo腳本和上次進入本頁後,公會成員並無任何改變。';
  4059. localizationText['zh-tw']['banned'] = '被封禁';
  4060. localizationText['zh-tw']['commander'] = '指揮官';
  4061. localizationText['zh-tw']['executive_officer'] = '執行官';
  4062. localizationText['zh-tw']['personnel_officer'] = '人事官';
  4063. localizationText['zh-tw']['intelligence_officer'] = '情報官';
  4064. localizationText['zh-tw']['quartermaster'] = '軍需官';
  4065. localizationText['zh-tw']['recruitment_officer'] = '徵募官';
  4066. localizationText['zh-tw']['junior_officer'] = '下級軍官';
  4067. localizationText['zh-tw']['combat_officer'] = '作戰官';
  4068. localizationText['zh-tw']['private'] = '士兵';
  4069. localizationText['zh-tw']['recruit'] = '新兵';
  4070. localizationText['zh-tw']['reservist'] = '後備軍人';
  4071. localizationText['zh-tw']['get-settings-button'] = '設定';
  4072. localizationText['zh-tw']['set-settings-default'] = '預設';
  4073. localizationText['zh-tw']['table-setting-caption'] = '查看列表排序「公會統計」';
  4074. localizationText['zh-tw']['table-setting-structure'] = '列表排序';
  4075. localizationText['zh-tw']['statistic-clan-button-0'] = '公會統計';
  4076. localizationText['zh-tw']['statistic-clan-button-1'] = '公會架構';
  4077. localizationText['zh-tw']['statistic-clan-load-text'] = '請稍候 •••<br />正在獲取統計數據';
  4078. localizationText['zh-tw']['statistic-load-text-lost'] = '<br />剩餘時間 &#8776;';
  4079. localizationText['zh-tw']['statistic-load-text-min'] = '分';
  4080. localizationText['zh-tw']['statistic-load-text-sec'] = '秒';
  4081. localizationText['zh-tw']['account_name'] = '玩家名稱';
  4082. localizationText['zh-tw']['role_i18n'] = '位階';
  4083. localizationText['zh-tw']['clan_days'] = '待在公會的天數';
  4084. localizationText['zh-tw']['info.last_battle_time'] = '上次戰鬥時間';
  4085. localizationText['zh-tw']['info.logout_at'] = '上次遊戲完結時間';
  4086. localizationText['zh-tw']['info.statistics.pvp.battles'] = '戰鬥數';
  4087. localizationText['zh-tw']['info.statistics.pvp.wins'] = '勝利數';
  4088. localizationText['zh-tw']['info.statistics.pvp.losses'] = '失敗數';
  4089. localizationText['zh-tw']['info.statistics.pvp.draws'] = '平手數';
  4090. localizationText['zh-tw']['info.statistics.pvp.survived_battles'] = '存活數';
  4091. localizationText['zh-tw']['info.statistics.pvp.survived_wins'] = '勝利並存活數';
  4092. localizationText['zh-tw']['info.statistics.pvp.kill_dead'] = '擊毀/死亡比';
  4093. localizationText['zh-tw']['info.statistics.pvp.xp'] = '總經驗';
  4094. localizationText['zh-tw']['info.statistics.pvp.damage_dealt'] = '造成的傷害';
  4095. localizationText['zh-tw']['info.statistics.pvp.frags'] = '擊毀的艦艇數';
  4096. localizationText['zh-tw']['info.statistics.pvp.planes_killed'] = '擊毀飛機數';
  4097. localizationText['zh-tw']['info.statistics.pvp.capture_points'] = '佔領點數';
  4098. localizationText['zh-tw']['info.statistics.pvp.dropped_capture_points'] = '防禦點數';
  4099. localizationText['zh-tw']['info.statistics.pvp.avg_xp'] = '平均經驗';
  4100. localizationText['zh-tw']['info.statistics.pvp.avg_damage_dealt'] = '平均造成傷害';
  4101. localizationText['zh-tw']['info.statistics.pvp.avg_frags'] = '平均擊毀艦艇數';
  4102. localizationText['zh-tw']['info.statistics.pvp.avg_planes_killed'] = '平均擊毀飛機數';
  4103. localizationText['zh-tw']['info.statistics.pvp.avg_capture_points'] = '平均佔領點數';
  4104. localizationText['zh-tw']['info.statistics.pvp.avg_dropped_capture_points'] = '平均防禦點數';
  4105. localizationText['zh-tw']['info.statistics.pvp.max_xp'] = '最大經驗';
  4106. localizationText['zh-tw']['info.statistics.pvp.max_damage_dealt'] = '最大造成傷害';
  4107. localizationText['zh-tw']['info.statistics.pvp.max_frags_battle'] = '最大擊毀的艦艇數';
  4108. localizationText['zh-tw']['info.statistics.pvp.max_planes_killed'] = '最大擊毀飛機數';
  4109. localizationText['zh-tw']['info.statistics.pvp.wins_percents'] = '勝利率';
  4110. localizationText['zh-tw']['info.statistics.pvp.survived_battles_percents'] = '存活率';
  4111. localizationText['zh-tw']['info.statistics.pvp.wr'] = 'WR';
  4112. localizationText['zh-tw']['info.ships_x_level'] = '10 lvl';
  4113. }
  4114. return localizationText[lang];
  4115. }
  4116. if(window.location.href.indexOf("accounts") > -1 && window.location.href.split('/').length >= 8 && window.location.href.split('/')[6].match(/[0-9]+/) != null){
  4117. // Javascript plotting library for jQuery, version 0.8.3.
  4118. // the actual Flot code
  4119. (function($) {
  4120.  
  4121. // Cache the prototype hasOwnProperty for faster access
  4122.  
  4123. var hasOwnProperty = Object.prototype.hasOwnProperty;
  4124.  
  4125. // A shim to provide 'detach' to jQuery versions prior to 1.4. Using a DOM
  4126. // operation produces the same effect as detach, i.e. removing the element
  4127. // without touching its jQuery data.
  4128.  
  4129. // Do not merge this into Flot 0.9, since it requires jQuery 1.4.4+.
  4130.  
  4131. if (!$.fn.detach) {
  4132. $.fn.detach = function() {
  4133. return this.each(function() {
  4134. if (this.parentNode) {
  4135. this.parentNode.removeChild( this );
  4136. }
  4137. });
  4138. };
  4139. }
  4140.  
  4141. ///////////////////////////////////////////////////////////////////////////
  4142. // The Canvas object is a wrapper around an HTML5 <canvas> tag.
  4143. //
  4144. // @constructor
  4145. // @param {string} cls List of classes to apply to the canvas.
  4146. // @param {element} container Element onto which to append the canvas.
  4147. //
  4148. // Requiring a container is a little iffy, but unfortunately canvas
  4149. // operations don't work unless the canvas is attached to the DOM.
  4150.  
  4151. function Canvas(cls, container) {
  4152.  
  4153. var element = container.children("." + cls)[0];
  4154.  
  4155. if (element == null) {
  4156.  
  4157. element = document.createElement("canvas");
  4158. element.className = cls;
  4159.  
  4160. $(element).css({ direction: "ltr", position: "absolute", left: 0, top: 0 })
  4161. .appendTo(container);
  4162.  
  4163. // If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas
  4164.  
  4165. if (!element.getContext) {
  4166. if (window.G_vmlCanvasManager) {
  4167. element = window.G_vmlCanvasManager.initElement(element);
  4168. } else {
  4169. throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");
  4170. }
  4171. }
  4172. }
  4173.  
  4174. this.element = element;
  4175.  
  4176. var context = this.context = element.getContext("2d");
  4177.  
  4178. // Determine the screen's ratio of physical to device-independent
  4179. // pixels. This is the ratio between the canvas width that the browser
  4180. // advertises and the number of pixels actually present in that space.
  4181.  
  4182. // The iPhone 4, for example, has a device-independent width of 320px,
  4183. // but its screen is actually 640px wide. It therefore has a pixel
  4184. // ratio of 2, while most normal devices have a ratio of 1.
  4185.  
  4186. var devicePixelRatio = window.devicePixelRatio || 1,
  4187. backingStoreRatio =
  4188. context.webkitBackingStorePixelRatio ||
  4189. context.mozBackingStorePixelRatio ||
  4190. context.msBackingStorePixelRatio ||
  4191. context.oBackingStorePixelRatio ||
  4192. context.backingStorePixelRatio || 1;
  4193.  
  4194. this.pixelRatio = devicePixelRatio / backingStoreRatio;
  4195.  
  4196. // Size the canvas to match the internal dimensions of its container
  4197.  
  4198. this.resize(container.width(), container.height());
  4199.  
  4200. // Collection of HTML div layers for text overlaid onto the canvas
  4201.  
  4202. this.textContainer = null;
  4203. this.text = {};
  4204.  
  4205. // Cache of text fragments and metrics, so we can avoid expensively
  4206. // re-calculating them when the plot is re-rendered in a loop.
  4207.  
  4208. this._textCache = {};
  4209. }
  4210.  
  4211. // Resizes the canvas to the given dimensions.
  4212. //
  4213. // @param {number} width New width of the canvas, in pixels.
  4214. // @param {number} width New height of the canvas, in pixels.
  4215.  
  4216. Canvas.prototype.resize = function(width, height) {
  4217.  
  4218. if (width <= 0 || height <= 0) {
  4219. throw new Error("Invalid dimensions for plot, width = " + width + ", height = " + height);
  4220. }
  4221.  
  4222. var element = this.element,
  4223. context = this.context,
  4224. pixelRatio = this.pixelRatio;
  4225.  
  4226. // Resize the canvas, increasing its density based on the display's
  4227. // pixel ratio; basically giving it more pixels without increasing the
  4228. // size of its element, to take advantage of the fact that retina
  4229. // displays have that many more pixels in the same advertised space.
  4230.  
  4231. // Resizing should reset the state (excanvas seems to be buggy though)
  4232.  
  4233. if (this.width != width) {
  4234. element.width = width * pixelRatio;
  4235. element.style.width = width + "px";
  4236. this.width = width;
  4237. }
  4238.  
  4239. if (this.height != height) {
  4240. element.height = height * pixelRatio;
  4241. element.style.height = height + "px";
  4242. this.height = height;
  4243. }
  4244.  
  4245. // Save the context, so we can reset in case we get replotted. The
  4246. // restore ensure that we're really back at the initial state, and
  4247. // should be safe even if we haven't saved the initial state yet.
  4248.  
  4249. context.restore();
  4250. context.save();
  4251.  
  4252. // Scale the coordinate space to match the display density; so even though we
  4253. // may have twice as many pixels, we still want lines and other drawing to
  4254. // appear at the same size; the extra pixels will just make them crisper.
  4255.  
  4256. context.scale(pixelRatio, pixelRatio);
  4257. };
  4258.  
  4259. // Clears the entire canvas area, not including any overlaid HTML text
  4260.  
  4261. Canvas.prototype.clear = function() {
  4262. this.context.clearRect(0, 0, this.width, this.height);
  4263. };
  4264.  
  4265. // Finishes rendering the canvas, including managing the text overlay.
  4266.  
  4267. Canvas.prototype.render = function() {
  4268.  
  4269. var cache = this._textCache;
  4270.  
  4271. // For each text layer, add elements marked as active that haven't
  4272. // already been rendered, and remove those that are no longer active.
  4273.  
  4274. for (var layerKey in cache) {
  4275. if (hasOwnProperty.call(cache, layerKey)) {
  4276.  
  4277. var layer = this.getTextLayer(layerKey),
  4278. layerCache = cache[layerKey];
  4279.  
  4280. layer.hide();
  4281.  
  4282. for (var styleKey in layerCache) {
  4283. if (hasOwnProperty.call(layerCache, styleKey)) {
  4284. var styleCache = layerCache[styleKey];
  4285. for (var key in styleCache) {
  4286. if (hasOwnProperty.call(styleCache, key)) {
  4287.  
  4288. var positions = styleCache[key].positions;
  4289.  
  4290. for (var i = 0, position; position = positions[i]; i++) {
  4291. if (position.active) {
  4292. if (!position.rendered) {
  4293. layer.append(position.element);
  4294. position.rendered = true;
  4295. }
  4296. } else {
  4297. positions.splice(i--, 1);
  4298. if (position.rendered) {
  4299. position.element.detach();
  4300. }
  4301. }
  4302. }
  4303.  
  4304. if (positions.length == 0) {
  4305. delete styleCache[key];
  4306. }
  4307. }
  4308. }
  4309. }
  4310. }
  4311.  
  4312. layer.show();
  4313. }
  4314. }
  4315. };
  4316.  
  4317. // Creates (if necessary) and returns the text overlay container.
  4318. //
  4319. // @param {string} classes String of space-separated CSS classes used to
  4320. // uniquely identify the text layer.
  4321. // @return {object} The jQuery-wrapped text-layer div.
  4322.  
  4323. Canvas.prototype.getTextLayer = function(classes) {
  4324.  
  4325. var layer = this.text[classes];
  4326.  
  4327. // Create the text layer if it doesn't exist
  4328.  
  4329. if (layer == null) {
  4330.  
  4331. // Create the text layer container, if it doesn't exist
  4332.  
  4333. if (this.textContainer == null) {
  4334. this.textContainer = $("<div class='flot-text'></div>")
  4335. .css({
  4336. position: "absolute",
  4337. top: 0,
  4338. left: 0,
  4339. bottom: 0,
  4340. right: 0,
  4341. 'font-size': "smaller",
  4342. color: "#545454"
  4343. })
  4344. .insertAfter(this.element);
  4345. }
  4346.  
  4347. layer = this.text[classes] = $("<div></div>")
  4348. .addClass(classes)
  4349. .css({
  4350. position: "absolute",
  4351. top: 0,
  4352. left: 0,
  4353. bottom: 0,
  4354. right: 0
  4355. })
  4356. .appendTo(this.textContainer);
  4357. }
  4358.  
  4359. return layer;
  4360. };
  4361.  
  4362. // Creates (if necessary) and returns a text info object.
  4363. //
  4364. // The object looks like this:
  4365. //
  4366. // {
  4367. // width: Width of the text's wrapper div.
  4368. // height: Height of the text's wrapper div.
  4369. // element: The jQuery-wrapped HTML div containing the text.
  4370. // positions: Array of positions at which this text is drawn.
  4371. // }
  4372. //
  4373. // The positions array contains objects that look like this:
  4374. //
  4375. // {
  4376. // active: Flag indicating whether the text should be visible.
  4377. // rendered: Flag indicating whether the text is currently visible.
  4378. // element: The jQuery-wrapped HTML div containing the text.
  4379. // x: X coordinate at which to draw the text.
  4380. // y: Y coordinate at which to draw the text.
  4381. // }
  4382. //
  4383. // Each position after the first receives a clone of the original element.
  4384. //
  4385. // The idea is that that the width, height, and general 'identity' of the
  4386. // text is constant no matter where it is placed; the placements are a
  4387. // secondary property.
  4388. //
  4389. // Canvas maintains a cache of recently-used text info objects; getTextInfo
  4390. // either returns the cached element or creates a new entry.
  4391. //
  4392. // @param {string} layer A string of space-separated CSS classes uniquely
  4393. // identifying the layer containing this text.
  4394. // @param {string} text Text string to retrieve info for.
  4395. // @param {(string|object)=} font Either a string of space-separated CSS
  4396. // classes or a font-spec object, defining the text's font and style.
  4397. // @param {number=} angle Angle at which to rotate the text, in degrees.
  4398. // Angle is currently unused, it will be implemented in the future.
  4399. // @param {number=} width Maximum width of the text before it wraps.
  4400. // @return {object} a text info object.
  4401.  
  4402. Canvas.prototype.getTextInfo = function(layer, text, font, angle, width) {
  4403.  
  4404. var textStyle, layerCache, styleCache, info;
  4405.  
  4406. // Cast the value to a string, in case we were given a number or such
  4407.  
  4408. text = "" + text;
  4409.  
  4410. // If the font is a font-spec object, generate a CSS font definition
  4411.  
  4412. if (typeof font === "object") {
  4413. textStyle = font.style + " " + font.variant + " " + font.weight + " " + font.size + "px/" + font.lineHeight + "px " + font.family;
  4414. } else {
  4415. textStyle = font;
  4416. }
  4417.  
  4418. // Retrieve (or create) the cache for the text's layer and styles
  4419.  
  4420. layerCache = this._textCache[layer];
  4421.  
  4422. if (layerCache == null) {
  4423. layerCache = this._textCache[layer] = {};
  4424. }
  4425.  
  4426. styleCache = layerCache[textStyle];
  4427.  
  4428. if (styleCache == null) {
  4429. styleCache = layerCache[textStyle] = {};
  4430. }
  4431.  
  4432. info = styleCache[text];
  4433.  
  4434. // If we can't find a matching element in our cache, create a new one
  4435.  
  4436. if (info == null) {
  4437.  
  4438. var element = $("<div></div>").html(text)
  4439. .css({
  4440. position: "absolute",
  4441. 'max-width': width,
  4442. top: -9999
  4443. })
  4444. .appendTo(this.getTextLayer(layer));
  4445.  
  4446. if (typeof font === "object") {
  4447. element.css({
  4448. font: textStyle,
  4449. color: font.color
  4450. });
  4451. } else if (typeof font === "string") {
  4452. element.addClass(font);
  4453. }
  4454.  
  4455. info = styleCache[text] = {
  4456. width: element.outerWidth(true),
  4457. height: element.outerHeight(true),
  4458. element: element,
  4459. positions: []
  4460. };
  4461.  
  4462. element.detach();
  4463. }
  4464.  
  4465. return info;
  4466. };
  4467.  
  4468. // Adds a text string to the canvas text overlay.
  4469. //
  4470. // The text isn't drawn immediately; it is marked as rendering, which will
  4471. // result in its addition to the canvas on the next render pass.
  4472. //
  4473. // @param {string} layer A string of space-separated CSS classes uniquely
  4474. // identifying the layer containing this text.
  4475. // @param {number} x X coordinate at which to draw the text.
  4476. // @param {number} y Y coordinate at which to draw the text.
  4477. // @param {string} text Text string to draw.
  4478. // @param {(string|object)=} font Either a string of space-separated CSS
  4479. // classes or a font-spec object, defining the text's font and style.
  4480. // @param {number=} angle Angle at which to rotate the text, in degrees.
  4481. // Angle is currently unused, it will be implemented in the future.
  4482. // @param {number=} width Maximum width of the text before it wraps.
  4483. // @param {string=} halign Horizontal alignment of the text; either "left",
  4484. // "center" or "right".
  4485. // @param {string=} valign Vertical alignment of the text; either "top",
  4486. // "middle" or "bottom".
  4487.  
  4488. Canvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {
  4489.  
  4490. var info = this.getTextInfo(layer, text, font, angle, width),
  4491. positions = info.positions;
  4492.  
  4493. // Tweak the div's position to match the text's alignment
  4494.  
  4495. if (halign == "center") {
  4496. x -= info.width / 2;
  4497. } else if (halign == "right") {
  4498. x -= info.width;
  4499. }
  4500.  
  4501. if (valign == "middle") {
  4502. y -= info.height / 2;
  4503. } else if (valign == "bottom") {
  4504. y -= info.height;
  4505. }
  4506.  
  4507. // Determine whether this text already exists at this position.
  4508. // If so, mark it for inclusion in the next render pass.
  4509.  
  4510. for (var i = 0, position; position = positions[i]; i++) {
  4511. if (position.x == x && position.y == y) {
  4512. position.active = true;
  4513. return;
  4514. }
  4515. }
  4516.  
  4517. // If the text doesn't exist at this position, create a new entry
  4518.  
  4519. // For the very first position we'll re-use the original element,
  4520. // while for subsequent ones we'll clone it.
  4521.  
  4522. position = {
  4523. active: true,
  4524. rendered: false,
  4525. element: positions.length ? info.element.clone() : info.element,
  4526. x: x,
  4527. y: y
  4528. };
  4529.  
  4530. positions.push(position);
  4531.  
  4532. // Move the element to its final position within the container
  4533.  
  4534. position.element.css({
  4535. top: Math.round(y),
  4536. left: Math.round(x),
  4537. 'text-align': halign // In case the text wraps
  4538. });
  4539. };
  4540.  
  4541. // Removes one or more text strings from the canvas text overlay.
  4542. //
  4543. // If no parameters are given, all text within the layer is removed.
  4544. //
  4545. // Note that the text is not immediately removed; it is simply marked as
  4546. // inactive, which will result in its removal on the next render pass.
  4547. // This avoids the performance penalty for 'clear and redraw' behavior,
  4548. // where we potentially get rid of all text on a layer, but will likely
  4549. // add back most or all of it later, as when redrawing axes, for example.
  4550. //
  4551. // @param {string} layer A string of space-separated CSS classes uniquely
  4552. // identifying the layer containing this text.
  4553. // @param {number=} x X coordinate of the text.
  4554. // @param {number=} y Y coordinate of the text.
  4555. // @param {string=} text Text string to remove.
  4556. // @param {(string|object)=} font Either a string of space-separated CSS
  4557. // classes or a font-spec object, defining the text's font and style.
  4558. // @param {number=} angle Angle at which the text is rotated, in degrees.
  4559. // Angle is currently unused, it will be implemented in the future.
  4560.  
  4561. Canvas.prototype.removeText = function(layer, x, y, text, font, angle) {
  4562. if (text == null) {
  4563. var layerCache = this._textCache[layer];
  4564. if (layerCache != null) {
  4565. for (var styleKey in layerCache) {
  4566. if (hasOwnProperty.call(layerCache, styleKey)) {
  4567. var styleCache = layerCache[styleKey];
  4568. for (var key in styleCache) {
  4569. if (hasOwnProperty.call(styleCache, key)) {
  4570. var positions = styleCache[key].positions;
  4571. for (var i = 0, position; position = positions[i]; i++) {
  4572. position.active = false;
  4573. }
  4574. }
  4575. }
  4576. }
  4577. }
  4578. }
  4579. } else {
  4580. var positions = this.getTextInfo(layer, text, font, angle).positions;
  4581. for (var i = 0, position; position = positions[i]; i++) {
  4582. if (position.x == x && position.y == y) {
  4583. position.active = false;
  4584. }
  4585. }
  4586. }
  4587. };
  4588.  
  4589. ///////////////////////////////////////////////////////////////////////////
  4590. // The top-level container for the entire plot.
  4591.  
  4592. function Plot(placeholder, data_, options_, plugins) {
  4593. // data is on the form:
  4594. // [ series1, series2 ... ]
  4595. // where series is either just the data as [ [x1, y1], [x2, y2], ... ]
  4596. // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label", ... }
  4597.  
  4598. var series = [],
  4599. options = {
  4600. // the color theme used for graphs
  4601. colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"],
  4602. legend: {
  4603. show: true,
  4604. noColumns: 1, // number of colums in legend table
  4605. labelFormatter: null, // fn: string -> string
  4606. labelBoxBorderColor: "#ccc", // border color for the little label boxes
  4607. container: null, // container (as jQuery object) to put legend in, null means default on top of graph
  4608. position: "ne", // position of default legend container within plot
  4609. margin: 5, // distance from grid edge to default legend container within plot
  4610. backgroundColor: null, // null means auto-detect
  4611. backgroundOpacity: 0.85, // set to 0 to avoid background
  4612. sorted: null // default to no legend sorting
  4613. },
  4614. xaxis: {
  4615. show: null, // null = auto-detect, true = always, false = never
  4616. position: "bottom", // or "top"
  4617. mode: null, // null or "time"
  4618. font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: "italic", weight: "bold", family: "sans-serif", variant: "small-caps" }
  4619. color: null, // base color, labels, ticks
  4620. tickColor: null, // possibly different color of ticks, e.g. "rgba(0,0,0,0.15)"
  4621. transform: null, // null or f: number -> number to transform axis
  4622. inverseTransform: null, // if transform is set, this should be the inverse function
  4623. min: null, // min. value to show, null means set automatically
  4624. max: null, // max. value to show, null means set automatically
  4625. autoscaleMargin: null, // margin in % to add if auto-setting min/max
  4626. ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks
  4627. tickFormatter: null, // fn: number -> string
  4628. labelWidth: null, // size of tick labels in pixels
  4629. labelHeight: null,
  4630. reserveSpace: null, // whether to reserve space even if axis isn't shown
  4631. tickLength: null, // size in pixels of ticks, or "full" for whole line
  4632. alignTicksWithAxis: null, // axis number or null for no sync
  4633. tickDecimals: null, // no. of decimals, null means auto
  4634. tickSize: null, // number or [number, "unit"]
  4635. minTickSize: null // number or [number, "unit"]
  4636. },
  4637. yaxis: {
  4638. autoscaleMargin: 0.02,
  4639. position: "left" // or "right"
  4640. },
  4641. xaxes: [],
  4642. yaxes: [],
  4643. series: {
  4644. points: {
  4645. show: false,
  4646. radius: 3,
  4647. lineWidth: 2, // in pixels
  4648. fill: true,
  4649. fillColor: "#ffffff",
  4650. symbol: "circle" // or callback
  4651. },
  4652. lines: {
  4653. // we don't put in show: false so we can see
  4654. // whether lines were actively disabled
  4655. lineWidth: 2, // in pixels
  4656. fill: false,
  4657. fillColor: null,
  4658. steps: false
  4659. // Omit 'zero', so we can later default its value to
  4660. // match that of the 'fill' option.
  4661. },
  4662. bars: {
  4663. show: false,
  4664. lineWidth: 2, // in pixels
  4665. barWidth: 1, // in units of the x axis
  4666. fill: true,
  4667. fillColor: null,
  4668. align: "left", // "left", "right", or "center"
  4669. horizontal: false,
  4670. zero: true
  4671. },
  4672. shadowSize: 3,
  4673. highlightColor: null
  4674. },
  4675. grid: {
  4676. show: true,
  4677. aboveData: false,
  4678. color: "#545454", // primary color used for outline and labels
  4679. backgroundColor: null, // null for transparent, else color
  4680. borderColor: null, // set if different from the grid color
  4681. tickColor: null, // color for the ticks, e.g. "rgba(0,0,0,0.15)"
  4682. margin: 0, // distance from the canvas edge to the grid
  4683. labelMargin: 5, // in pixels
  4684. axisMargin: 8, // in pixels
  4685. borderWidth: 2, // in pixels
  4686. minBorderMargin: null, // in pixels, null means taken from points radius
  4687. markings: null, // array of ranges or fn: axes -> array of ranges
  4688. markingsColor: "#f4f4f4",
  4689. markingsLineWidth: 2,
  4690. // interactive stuff
  4691. clickable: false,
  4692. hoverable: false,
  4693. autoHighlight: true, // highlight in case mouse is near
  4694. mouseActiveRadius: 10 // how far the mouse can be away to activate an item
  4695. },
  4696. interaction: {
  4697. redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow
  4698. },
  4699. hooks: {}
  4700. },
  4701. surface = null, // the canvas for the plot itself
  4702. overlay = null, // canvas for interactive stuff on top of plot
  4703. eventHolder = null, // jQuery object that events should be bound to
  4704. ctx = null, octx = null,
  4705. xaxes = [], yaxes = [],
  4706. plotOffset = { left: 0, right: 0, top: 0, bottom: 0},
  4707. plotWidth = 0, plotHeight = 0,
  4708. hooks = {
  4709. processOptions: [],
  4710. processRawData: [],
  4711. processDatapoints: [],
  4712. processOffset: [],
  4713. drawBackground: [],
  4714. drawSeries: [],
  4715. draw: [],
  4716. bindEvents: [],
  4717. drawOverlay: [],
  4718. shutdown: []
  4719. },
  4720. plot = this;
  4721.  
  4722. // public functions
  4723. plot.setData = setData;
  4724. plot.setupGrid = setupGrid;
  4725. plot.draw = draw;
  4726. plot.getPlaceholder = function() { return placeholder; };
  4727. plot.getCanvas = function() { return surface.element; };
  4728. plot.getPlotOffset = function() { return plotOffset; };
  4729. plot.width = function () { return plotWidth; };
  4730. plot.height = function () { return plotHeight; };
  4731. plot.offset = function () {
  4732. var o = eventHolder.offset();
  4733. o.left += plotOffset.left;
  4734. o.top += plotOffset.top;
  4735. return o;
  4736. };
  4737. plot.getData = function () { return series; };
  4738. plot.getAxes = function () {
  4739. var res = {}, i;
  4740. $.each(xaxes.concat(yaxes), function (_, axis) {
  4741. if (axis)
  4742. res[axis.direction + (axis.n != 1 ? axis.n : "") + "axis"] = axis;
  4743. });
  4744. return res;
  4745. };
  4746. plot.getXAxes = function () { return xaxes; };
  4747. plot.getYAxes = function () { return yaxes; };
  4748. plot.c2p = canvasToAxisCoords;
  4749. plot.p2c = axisToCanvasCoords;
  4750. plot.getOptions = function () { return options; };
  4751. plot.highlight = highlight;
  4752. plot.unhighlight = unhighlight;
  4753. plot.triggerRedrawOverlay = triggerRedrawOverlay;
  4754. plot.pointOffset = function(point) {
  4755. return {
  4756. left: parseInt(xaxes[axisNumber(point, "x") - 1].p2c(+point.x) + plotOffset.left, 10),
  4757. top: parseInt(yaxes[axisNumber(point, "y") - 1].p2c(+point.y) + plotOffset.top, 10)
  4758. };
  4759. };
  4760. plot.shutdown = shutdown;
  4761. plot.destroy = function () {
  4762. shutdown();
  4763. placeholder.removeData("plot").empty();
  4764.  
  4765. series = [];
  4766. options = null;
  4767. surface = null;
  4768. overlay = null;
  4769. eventHolder = null;
  4770. ctx = null;
  4771. octx = null;
  4772. xaxes = [];
  4773. yaxes = [];
  4774. hooks = null;
  4775. highlights = [];
  4776. plot = null;
  4777. };
  4778. plot.resize = function () {
  4779. var width = placeholder.width(),
  4780. height = placeholder.height();
  4781. surface.resize(width, height);
  4782. overlay.resize(width, height);
  4783. };
  4784.  
  4785. // public attributes
  4786. plot.hooks = hooks;
  4787.  
  4788. // initialize
  4789. initPlugins(plot);
  4790. parseOptions(options_);
  4791. setupCanvases();
  4792. setData(data_);
  4793. setupGrid();
  4794. draw();
  4795. bindEvents();
  4796.  
  4797.  
  4798. function executeHooks(hook, args) {
  4799. args = [plot].concat(args);
  4800. for (var i = 0; i < hook.length; ++i)
  4801. hook[i].apply(this, args);
  4802. }
  4803.  
  4804. function initPlugins() {
  4805.  
  4806. // References to key classes, allowing plugins to modify them
  4807.  
  4808. var classes = {
  4809. Canvas: Canvas
  4810. };
  4811.  
  4812. for (var i = 0; i < plugins.length; ++i) {
  4813. var p = plugins[i];
  4814. p.init(plot, classes);
  4815. if (p.options)
  4816. $.extend(true, options, p.options);
  4817. }
  4818. }
  4819.  
  4820. function parseOptions(opts) {
  4821.  
  4822. $.extend(true, options, opts);
  4823.  
  4824. // $.extend merges arrays, rather than replacing them. When less
  4825. // colors are provided than the size of the default palette, we
  4826. // end up with those colors plus the remaining defaults, which is
  4827. // not expected behavior; avoid it by replacing them here.
  4828.  
  4829. if (opts && opts.colors) {
  4830. options.colors = opts.colors;
  4831. }
  4832.  
  4833. if (options.xaxis.color == null)
  4834. options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
  4835. if (options.yaxis.color == null)
  4836. options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();
  4837.  
  4838. if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility
  4839. options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;
  4840. if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility
  4841. options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;
  4842.  
  4843. if (options.grid.borderColor == null)
  4844. options.grid.borderColor = options.grid.color;
  4845. if (options.grid.tickColor == null)
  4846. options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();
  4847.  
  4848. // Fill in defaults for axis options, including any unspecified
  4849. // font-spec fields, if a font-spec was provided.
  4850.  
  4851. // If no x/y axis options were provided, create one of each anyway,
  4852. // since the rest of the code assumes that they exist.
  4853.  
  4854. var i, axisOptions, axisCount,
  4855. fontSize = placeholder.css("font-size"),
  4856. fontSizeDefault = fontSize ? +fontSize.replace("px", "") : 13,
  4857. fontDefaults = {
  4858. style: placeholder.css("font-style"),
  4859. size: Math.round(0.8 * fontSizeDefault),
  4860. variant: placeholder.css("font-variant"),
  4861. weight: placeholder.css("font-weight"),
  4862. family: placeholder.css("font-family")
  4863. };
  4864.  
  4865. axisCount = options.xaxes.length || 1;
  4866. for (i = 0; i < axisCount; ++i) {
  4867.  
  4868. axisOptions = options.xaxes[i];
  4869. if (axisOptions && !axisOptions.tickColor) {
  4870. axisOptions.tickColor = axisOptions.color;
  4871. }
  4872.  
  4873. axisOptions = $.extend(true, {}, options.xaxis, axisOptions);
  4874. options.xaxes[i] = axisOptions;
  4875.  
  4876. if (axisOptions.font) {
  4877. axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
  4878. if (!axisOptions.font.color) {
  4879. axisOptions.font.color = axisOptions.color;
  4880. }
  4881. if (!axisOptions.font.lineHeight) {
  4882. axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
  4883. }
  4884. }
  4885. }
  4886.  
  4887. axisCount = options.yaxes.length || 1;
  4888. for (i = 0; i < axisCount; ++i) {
  4889.  
  4890. axisOptions = options.yaxes[i];
  4891. if (axisOptions && !axisOptions.tickColor) {
  4892. axisOptions.tickColor = axisOptions.color;
  4893. }
  4894.  
  4895. axisOptions = $.extend(true, {}, options.yaxis, axisOptions);
  4896. options.yaxes[i] = axisOptions;
  4897.  
  4898. if (axisOptions.font) {
  4899. axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);
  4900. if (!axisOptions.font.color) {
  4901. axisOptions.font.color = axisOptions.color;
  4902. }
  4903. if (!axisOptions.font.lineHeight) {
  4904. axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);
  4905. }
  4906. }
  4907. }
  4908.  
  4909. // backwards compatibility, to be removed in future
  4910. if (options.xaxis.noTicks && options.xaxis.ticks == null)
  4911. options.xaxis.ticks = options.xaxis.noTicks;
  4912. if (options.yaxis.noTicks && options.yaxis.ticks == null)
  4913. options.yaxis.ticks = options.yaxis.noTicks;
  4914. if (options.x2axis) {
  4915. options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);
  4916. options.xaxes[1].position = "top";
  4917. // Override the inherit to allow the axis to auto-scale
  4918. if (options.x2axis.min == null) {
  4919. options.xaxes[1].min = null;
  4920. }
  4921. if (options.x2axis.max == null) {
  4922. options.xaxes[1].max = null;
  4923. }
  4924. }
  4925. if (options.y2axis) {
  4926. options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);
  4927. options.yaxes[1].position = "right";
  4928. // Override the inherit to allow the axis to auto-scale
  4929. if (options.y2axis.min == null) {
  4930. options.yaxes[1].min = null;
  4931. }
  4932. if (options.y2axis.max == null) {
  4933. options.yaxes[1].max = null;
  4934. }
  4935. }
  4936. if (options.grid.coloredAreas)
  4937. options.grid.markings = options.grid.coloredAreas;
  4938. if (options.grid.coloredAreasColor)
  4939. options.grid.markingsColor = options.grid.coloredAreasColor;
  4940. if (options.lines)
  4941. $.extend(true, options.series.lines, options.lines);
  4942. if (options.points)
  4943. $.extend(true, options.series.points, options.points);
  4944. if (options.bars)
  4945. $.extend(true, options.series.bars, options.bars);
  4946. if (options.shadowSize != null)
  4947. options.series.shadowSize = options.shadowSize;
  4948. if (options.highlightColor != null)
  4949. options.series.highlightColor = options.highlightColor;
  4950.  
  4951. // save options on axes for future reference
  4952. for (i = 0; i < options.xaxes.length; ++i)
  4953. getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];
  4954. for (i = 0; i < options.yaxes.length; ++i)
  4955. getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];
  4956.  
  4957. // add hooks from options
  4958. for (var n in hooks)
  4959. if (options.hooks[n] && options.hooks[n].length)
  4960. hooks[n] = hooks[n].concat(options.hooks[n]);
  4961.  
  4962. executeHooks(hooks.processOptions, [options]);
  4963. }
  4964.  
  4965. function setData(d) {
  4966. series = parseData(d);
  4967. fillInSeriesOptions();
  4968. processData();
  4969. }
  4970.  
  4971. function parseData(d) {
  4972. var res = [];
  4973. for (var i = 0; i < d.length; ++i) {
  4974. var s = $.extend(true, {}, options.series);
  4975.  
  4976. if (d[i].data != null) {
  4977. s.data = d[i].data; // move the data instead of deep-copy
  4978. delete d[i].data;
  4979.  
  4980. $.extend(true, s, d[i]);
  4981.  
  4982. d[i].data = s.data;
  4983. }
  4984. else
  4985. s.data = d[i];
  4986. res.push(s);
  4987. }
  4988.  
  4989. return res;
  4990. }
  4991.  
  4992. function axisNumber(obj, coord) {
  4993. var a = obj[coord + "axis"];
  4994. if (typeof a == "object") // if we got a real axis, extract number
  4995. a = a.n;
  4996. if (typeof a != "number")
  4997. a = 1; // default to first axis
  4998. return a;
  4999. }
  5000.  
  5001. function allAxes() {
  5002. // return flat array without annoying null entries
  5003. return $.grep(xaxes.concat(yaxes), function (a) { return a; });
  5004. }
  5005.  
  5006. function canvasToAxisCoords(pos) {
  5007. // return an object with x/y corresponding to all used axes
  5008. var res = {}, i, axis;
  5009. for (i = 0; i < xaxes.length; ++i) {
  5010. axis = xaxes[i];
  5011. if (axis && axis.used)
  5012. res["x" + axis.n] = axis.c2p(pos.left);
  5013. }
  5014.  
  5015. for (i = 0; i < yaxes.length; ++i) {
  5016. axis = yaxes[i];
  5017. if (axis && axis.used)
  5018. res["y" + axis.n] = axis.c2p(pos.top);
  5019. }
  5020.  
  5021. if (res.x1 !== undefined)
  5022. res.x = res.x1;
  5023. if (res.y1 !== undefined)
  5024. res.y = res.y1;
  5025.  
  5026. return res;
  5027. }
  5028.  
  5029. function axisToCanvasCoords(pos) {
  5030. // get canvas coords from the first pair of x/y found in pos
  5031. var res = {}, i, axis, key;
  5032.  
  5033. for (i = 0; i < xaxes.length; ++i) {
  5034. axis = xaxes[i];
  5035. if (axis && axis.used) {
  5036. key = "x" + axis.n;
  5037. if (pos[key] == null && axis.n == 1)
  5038. key = "x";
  5039.  
  5040. if (pos[key] != null) {
  5041. res.left = axis.p2c(pos[key]);
  5042. break;
  5043. }
  5044. }
  5045. }
  5046.  
  5047. for (i = 0; i < yaxes.length; ++i) {
  5048. axis = yaxes[i];
  5049. if (axis && axis.used) {
  5050. key = "y" + axis.n;
  5051. if (pos[key] == null && axis.n == 1)
  5052. key = "y";
  5053.  
  5054. if (pos[key] != null) {
  5055. res.top = axis.p2c(pos[key]);
  5056. break;
  5057. }
  5058. }
  5059. }
  5060.  
  5061. return res;
  5062. }
  5063.  
  5064. function getOrCreateAxis(axes, number) {
  5065. if (!axes[number - 1])
  5066. axes[number - 1] = {
  5067. n: number, // save the number for future reference
  5068. direction: axes == xaxes ? "x" : "y",
  5069. options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)
  5070. };
  5071.  
  5072. return axes[number - 1];
  5073. }
  5074.  
  5075. function fillInSeriesOptions() {
  5076.  
  5077. var neededColors = series.length, maxIndex = -1, i;
  5078.  
  5079. // Subtract the number of series that already have fixed colors or
  5080. // color indexes from the number that we still need to generate.
  5081.  
  5082. for (i = 0; i < series.length; ++i) {
  5083. var sc = series[i].color;
  5084. if (sc != null) {
  5085. neededColors--;
  5086. if (typeof sc == "number" && sc > maxIndex) {
  5087. maxIndex = sc;
  5088. }
  5089. }
  5090. }
  5091.  
  5092. // If any of the series have fixed color indexes, then we need to
  5093. // generate at least as many colors as the highest index.
  5094.  
  5095. if (neededColors <= maxIndex) {
  5096. neededColors = maxIndex + 1;
  5097. }
  5098.  
  5099. // Generate all the colors, using first the option colors and then
  5100. // variations on those colors once they're exhausted.
  5101.  
  5102. var c, colors = [], colorPool = options.colors,
  5103. colorPoolSize = colorPool.length, variation = 0;
  5104.  
  5105. for (i = 0; i < neededColors; i++) {
  5106.  
  5107. c = $.color.parse(colorPool[i % colorPoolSize] || "#666");
  5108.  
  5109. // Each time we exhaust the colors in the pool we adjust
  5110. // a scaling factor used to produce more variations on
  5111. // those colors. The factor alternates negative/positive
  5112. // to produce lighter/darker colors.
  5113.  
  5114. // Reset the variation after every few cycles, or else
  5115. // it will end up producing only white or black colors.
  5116.  
  5117. if (i % colorPoolSize == 0 && i) {
  5118. if (variation >= 0) {
  5119. if (variation < 0.5) {
  5120. variation = -variation - 0.2;
  5121. } else variation = 0;
  5122. } else variation = -variation;
  5123. }
  5124.  
  5125. colors[i] = c.scale('rgb', 1 + variation);
  5126. }
  5127.  
  5128. // Finalize the series options, filling in their colors
  5129.  
  5130. var colori = 0, s;
  5131. for (i = 0; i < series.length; ++i) {
  5132. s = series[i];
  5133.  
  5134. // assign colors
  5135. if (s.color == null) {
  5136. s.color = colors[colori].toString();
  5137. ++colori;
  5138. }
  5139. else if (typeof s.color == "number")
  5140. s.color = colors[s.color].toString();
  5141.  
  5142. // turn on lines automatically in case nothing is set
  5143. if (s.lines.show == null) {
  5144. var v, show = true;
  5145. for (v in s)
  5146. if (s[v] && s[v].show) {
  5147. show = false;
  5148. break;
  5149. }
  5150. if (show)
  5151. s.lines.show = true;
  5152. }
  5153.  
  5154. // If nothing was provided for lines.zero, default it to match
  5155. // lines.fill, since areas by default should extend to zero.
  5156.  
  5157. if (s.lines.zero == null) {
  5158. s.lines.zero = !!s.lines.fill;
  5159. }
  5160.  
  5161. // setup axes
  5162. s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, "x"));
  5163. s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, "y"));
  5164. }
  5165. }
  5166.  
  5167. function processData() {
  5168. var topSentry = Number.POSITIVE_INFINITY,
  5169. bottomSentry = Number.NEGATIVE_INFINITY,
  5170. fakeInfinity = Number.MAX_VALUE,
  5171. i, j, k, m, length,
  5172. s, points, ps, x, y, axis, val, f, p,
  5173. data, format;
  5174.  
  5175. function updateAxis(axis, min, max) {
  5176. if (min < axis.datamin && min != -fakeInfinity)
  5177. axis.datamin = min;
  5178. if (max > axis.datamax && max != fakeInfinity)
  5179. axis.datamax = max;
  5180. }
  5181.  
  5182. $.each(allAxes(), function (_, axis) {
  5183. // init axis
  5184. axis.datamin = topSentry;
  5185. axis.datamax = bottomSentry;
  5186. axis.used = false;
  5187. });
  5188.  
  5189. for (i = 0; i < series.length; ++i) {
  5190. s = series[i];
  5191. s.datapoints = { points: [] };
  5192.  
  5193. executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);
  5194. }
  5195.  
  5196. // first pass: clean and copy data
  5197. for (i = 0; i < series.length; ++i) {
  5198. s = series[i];
  5199.  
  5200. data = s.data;
  5201. format = s.datapoints.format;
  5202.  
  5203. if (!format) {
  5204. format = [];
  5205. // find out how to copy
  5206. format.push({ x: true, number: true, required: true });
  5207. format.push({ y: true, number: true, required: true });
  5208.  
  5209. if (s.bars.show || (s.lines.show && s.lines.fill)) {
  5210. var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));
  5211. format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });
  5212. if (s.bars.horizontal) {
  5213. delete format[format.length - 1].y;
  5214. format[format.length - 1].x = true;
  5215. }
  5216. }
  5217.  
  5218. s.datapoints.format = format;
  5219. }
  5220.  
  5221. if (s.datapoints.pointsize != null)
  5222. continue; // already filled in
  5223.  
  5224. s.datapoints.pointsize = format.length;
  5225.  
  5226. ps = s.datapoints.pointsize;
  5227. points = s.datapoints.points;
  5228.  
  5229. var insertSteps = s.lines.show && s.lines.steps;
  5230. s.xaxis.used = s.yaxis.used = true;
  5231.  
  5232. for (j = k = 0; j < data.length; ++j, k += ps) {
  5233. p = data[j];
  5234.  
  5235. var nullify = p == null;
  5236. if (!nullify) {
  5237. for (m = 0; m < ps; ++m) {
  5238. val = p[m];
  5239. f = format[m];
  5240.  
  5241. if (f) {
  5242. if (f.number && val != null) {
  5243. val = +val; // convert to number
  5244. if (isNaN(val))
  5245. val = null;
  5246. else if (val == Infinity)
  5247. val = fakeInfinity;
  5248. else if (val == -Infinity)
  5249. val = -fakeInfinity;
  5250. }
  5251.  
  5252. if (val == null) {
  5253. if (f.required)
  5254. nullify = true;
  5255.  
  5256. if (f.defaultValue != null)
  5257. val = f.defaultValue;
  5258. }
  5259. }
  5260.  
  5261. points[k + m] = val;
  5262. }
  5263. }
  5264.  
  5265. if (nullify) {
  5266. for (m = 0; m < ps; ++m) {
  5267. val = points[k + m];
  5268. if (val != null) {
  5269. f = format[m];
  5270. // extract min/max info
  5271. if (f.autoscale !== false) {
  5272. if (f.x) {
  5273. updateAxis(s.xaxis, val, val);
  5274. }
  5275. if (f.y) {
  5276. updateAxis(s.yaxis, val, val);
  5277. }
  5278. }
  5279. }
  5280. points[k + m] = null;
  5281. }
  5282. }
  5283. else {
  5284. // a little bit of line specific stuff that
  5285. // perhaps shouldn't be here, but lacking
  5286. // better means...
  5287. if (insertSteps && k > 0
  5288. && points[k - ps] != null
  5289. && points[k - ps] != points[k]
  5290. && points[k - ps + 1] != points[k + 1]) {
  5291. // copy the point to make room for a middle point
  5292. for (m = 0; m < ps; ++m)
  5293. points[k + ps + m] = points[k + m];
  5294.  
  5295. // middle point has same y
  5296. points[k + 1] = points[k - ps + 1];
  5297.  
  5298. // we've added a point, better reflect that
  5299. k += ps;
  5300. }
  5301. }
  5302. }
  5303. }
  5304.  
  5305. // give the hooks a chance to run
  5306. for (i = 0; i < series.length; ++i) {
  5307. s = series[i];
  5308.  
  5309. executeHooks(hooks.processDatapoints, [ s, s.datapoints]);
  5310. }
  5311.  
  5312. // second pass: find datamax/datamin for auto-scaling
  5313. for (i = 0; i < series.length; ++i) {
  5314. s = series[i];
  5315. points = s.datapoints.points;
  5316. ps = s.datapoints.pointsize;
  5317. format = s.datapoints.format;
  5318.  
  5319. var xmin = topSentry, ymin = topSentry,
  5320. xmax = bottomSentry, ymax = bottomSentry;
  5321.  
  5322. for (j = 0; j < points.length; j += ps) {
  5323. if (points[j] == null)
  5324. continue;
  5325.  
  5326. for (m = 0; m < ps; ++m) {
  5327. val = points[j + m];
  5328. f = format[m];
  5329. if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)
  5330. continue;
  5331.  
  5332. if (f.x) {
  5333. if (val < xmin)
  5334. xmin = val;
  5335. if (val > xmax)
  5336. xmax = val;
  5337. }
  5338. if (f.y) {
  5339. if (val < ymin)
  5340. ymin = val;
  5341. if (val > ymax)
  5342. ymax = val;
  5343. }
  5344. }
  5345. }
  5346.  
  5347. if (s.bars.show) {
  5348. // make sure we got room for the bar on the dancing floor
  5349. var delta;
  5350.  
  5351. switch (s.bars.align) {
  5352. case "left":
  5353. delta = 0;
  5354. break;
  5355. case "right":
  5356. delta = -s.bars.barWidth;
  5357. break;
  5358. default:
  5359. delta = -s.bars.barWidth / 2;
  5360. }
  5361.  
  5362. if (s.bars.horizontal) {
  5363. ymin += delta;
  5364. ymax += delta + s.bars.barWidth;
  5365. }
  5366. else {
  5367. xmin += delta;
  5368. xmax += delta + s.bars.barWidth;
  5369. }
  5370. }
  5371.  
  5372. updateAxis(s.xaxis, xmin, xmax);
  5373. updateAxis(s.yaxis, ymin, ymax);
  5374. }
  5375.  
  5376. $.each(allAxes(), function (_, axis) {
  5377. if (axis.datamin == topSentry)
  5378. axis.datamin = null;
  5379. if (axis.datamax == bottomSentry)
  5380. axis.datamax = null;
  5381. });
  5382. }
  5383.  
  5384. function setupCanvases() {
  5385.  
  5386. // Make sure the placeholder is clear of everything except canvases
  5387. // from a previous plot in this container that we'll try to re-use.
  5388.  
  5389. placeholder.css("padding", 0) // padding messes up the positioning
  5390. .children().filter(function(){
  5391. return !$(this).hasClass("flot-overlay") && !$(this).hasClass('flot-base');
  5392. }).remove();
  5393.  
  5394. if (placeholder.css("position") == 'static')
  5395. placeholder.css("position", "relative"); // for positioning labels and overlay
  5396.  
  5397. surface = new Canvas("flot-base", placeholder);
  5398. overlay = new Canvas("flot-overlay", placeholder); // overlay canvas for interactive features
  5399.  
  5400. ctx = surface.context;
  5401. octx = overlay.context;
  5402.  
  5403. // define which element we're listening for events on
  5404. eventHolder = $(overlay.element).unbind();
  5405.  
  5406. // If we're re-using a plot object, shut down the old one
  5407.  
  5408. var existing = placeholder.data("plot");
  5409.  
  5410. if (existing) {
  5411. existing.shutdown();
  5412. overlay.clear();
  5413. }
  5414.  
  5415. // save in case we get replotted
  5416. placeholder.data("plot", plot);
  5417. }
  5418.  
  5419. function bindEvents() {
  5420. // bind events
  5421. if (options.grid.hoverable) {
  5422. eventHolder.mousemove(onMouseMove);
  5423.  
  5424. // Use bind, rather than .mouseleave, because we officially
  5425. // still support jQuery 1.2.6, which doesn't define a shortcut
  5426. // for mouseenter or mouseleave. This was a bug/oversight that
  5427. // was fixed somewhere around 1.3.x. We can return to using
  5428. // .mouseleave when we drop support for 1.2.6.
  5429.  
  5430. eventHolder.bind("mouseleave", onMouseLeave);
  5431. }
  5432.  
  5433. if (options.grid.clickable)
  5434. eventHolder.click(onClick);
  5435.  
  5436. executeHooks(hooks.bindEvents, [eventHolder]);
  5437. }
  5438.  
  5439. function shutdown() {
  5440. if (redrawTimeout)
  5441. clearTimeout(redrawTimeout);
  5442.  
  5443. eventHolder.unbind("mousemove", onMouseMove);
  5444. eventHolder.unbind("mouseleave", onMouseLeave);
  5445. eventHolder.unbind("click", onClick);
  5446.  
  5447. executeHooks(hooks.shutdown, [eventHolder]);
  5448. }
  5449.  
  5450. function setTransformationHelpers(axis) {
  5451. // set helper functions on the axis, assumes plot area
  5452. // has been computed already
  5453.  
  5454. function identity(x) { return x; }
  5455.  
  5456. var s, m, t = axis.options.transform || identity,
  5457. it = axis.options.inverseTransform;
  5458.  
  5459. // precompute how much the axis is scaling a point
  5460. // in canvas space
  5461. if (axis.direction == "x") {
  5462. s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));
  5463. m = Math.min(t(axis.max), t(axis.min));
  5464. }
  5465. else {
  5466. s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));
  5467. s = -s;
  5468. m = Math.max(t(axis.max), t(axis.min));
  5469. }
  5470.  
  5471. // data point to canvas coordinate
  5472. if (t == identity) // slight optimization
  5473. axis.p2c = function (p) { return (p - m) * s; };
  5474. else
  5475. axis.p2c = function (p) { return (t(p) - m) * s; };
  5476. // canvas coordinate to data point
  5477. if (!it)
  5478. axis.c2p = function (c) { return m + c / s; };
  5479. else
  5480. axis.c2p = function (c) { return it(m + c / s); };
  5481. }
  5482.  
  5483. function measureTickLabels(axis) {
  5484.  
  5485. var opts = axis.options,
  5486. ticks = axis.ticks || [],
  5487. labelWidth = opts.labelWidth || 0,
  5488. labelHeight = opts.labelHeight || 0,
  5489. maxWidth = labelWidth || (axis.direction == "x" ? Math.floor(surface.width / (ticks.length || 1)) : null),
  5490. legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
  5491. layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
  5492. font = opts.font || "flot-tick-label tickLabel";
  5493.  
  5494. for (var i = 0; i < ticks.length; ++i) {
  5495.  
  5496. var t = ticks[i];
  5497.  
  5498. if (!t.label)
  5499. continue;
  5500.  
  5501. var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);
  5502.  
  5503. labelWidth = Math.max(labelWidth, info.width);
  5504. labelHeight = Math.max(labelHeight, info.height);
  5505. }
  5506.  
  5507. axis.labelWidth = opts.labelWidth || labelWidth;
  5508. axis.labelHeight = opts.labelHeight || labelHeight;
  5509. }
  5510.  
  5511. function allocateAxisBoxFirstPhase(axis) {
  5512. // find the bounding box of the axis by looking at label
  5513. // widths/heights and ticks, make room by diminishing the
  5514. // plotOffset; this first phase only looks at one
  5515. // dimension per axis, the other dimension depends on the
  5516. // other axes so will have to wait
  5517.  
  5518. var lw = axis.labelWidth,
  5519. lh = axis.labelHeight,
  5520. pos = axis.options.position,
  5521. isXAxis = axis.direction === "x",
  5522. tickLength = axis.options.tickLength,
  5523. axisMargin = options.grid.axisMargin,
  5524. padding = options.grid.labelMargin,
  5525. innermost = true,
  5526. outermost = true,
  5527. first = true,
  5528. found = false;
  5529.  
  5530. // Determine the axis's position in its direction and on its side
  5531.  
  5532. $.each(isXAxis ? xaxes : yaxes, function(i, a) {
  5533. if (a && (a.show || a.reserveSpace)) {
  5534. if (a === axis) {
  5535. found = true;
  5536. } else if (a.options.position === pos) {
  5537. if (found) {
  5538. outermost = false;
  5539. } else {
  5540. innermost = false;
  5541. }
  5542. }
  5543. if (!found) {
  5544. first = false;
  5545. }
  5546. }
  5547. });
  5548.  
  5549. // The outermost axis on each side has no margin
  5550.  
  5551. if (outermost) {
  5552. axisMargin = 0;
  5553. }
  5554.  
  5555. // The ticks for the first axis in each direction stretch across
  5556.  
  5557. if (tickLength == null) {
  5558. tickLength = first ? "full" : 5;
  5559. }
  5560.  
  5561. if (!isNaN(+tickLength))
  5562. padding += +tickLength;
  5563.  
  5564. if (isXAxis) {
  5565. lh += padding;
  5566.  
  5567. if (pos == "bottom") {
  5568. plotOffset.bottom += lh + axisMargin;
  5569. axis.box = { top: surface.height - plotOffset.bottom, height: lh };
  5570. }
  5571. else {
  5572. axis.box = { top: plotOffset.top + axisMargin, height: lh };
  5573. plotOffset.top += lh + axisMargin;
  5574. }
  5575. }
  5576. else {
  5577. lw += padding;
  5578.  
  5579. if (pos == "left") {
  5580. axis.box = { left: plotOffset.left + axisMargin, width: lw };
  5581. plotOffset.left += lw + axisMargin;
  5582. }
  5583. else {
  5584. plotOffset.right += lw + axisMargin;
  5585. axis.box = { left: surface.width - plotOffset.right, width: lw };
  5586. }
  5587. }
  5588.  
  5589. // save for future reference
  5590. axis.position = pos;
  5591. axis.tickLength = tickLength;
  5592. axis.box.padding = padding;
  5593. axis.innermost = innermost;
  5594. }
  5595.  
  5596. function allocateAxisBoxSecondPhase(axis) {
  5597. // now that all axis boxes have been placed in one
  5598. // dimension, we can set the remaining dimension coordinates
  5599. if (axis.direction == "x") {
  5600. axis.box.left = plotOffset.left - axis.labelWidth / 2;
  5601. axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;
  5602. }
  5603. else {
  5604. axis.box.top = plotOffset.top - axis.labelHeight / 2;
  5605. axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;
  5606. }
  5607. }
  5608.  
  5609. function adjustLayoutForThingsStickingOut() {
  5610. // possibly adjust plot offset to ensure everything stays
  5611. // inside the canvas and isn't clipped off
  5612.  
  5613. var minMargin = options.grid.minBorderMargin,
  5614. axis, i;
  5615.  
  5616. // check stuff from the plot (FIXME: this should just read
  5617. // a value from the series, otherwise it's impossible to
  5618. // customize)
  5619. if (minMargin == null) {
  5620. minMargin = 0;
  5621. for (i = 0; i < series.length; ++i)
  5622. minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));
  5623. }
  5624.  
  5625. var margins = {
  5626. left: minMargin,
  5627. right: minMargin,
  5628. top: minMargin,
  5629. bottom: minMargin
  5630. };
  5631.  
  5632. // check axis labels, note we don't check the actual
  5633. // labels but instead use the overall width/height to not
  5634. // jump as much around with replots
  5635. $.each(allAxes(), function (_, axis) {
  5636. if (axis.reserveSpace && axis.ticks && axis.ticks.length) {
  5637. if (axis.direction === "x") {
  5638. margins.left = Math.max(margins.left, axis.labelWidth / 2);
  5639. margins.right = Math.max(margins.right, axis.labelWidth / 2);
  5640. } else {
  5641. margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);
  5642. margins.top = Math.max(margins.top, axis.labelHeight / 2);
  5643. }
  5644. }
  5645. });
  5646.  
  5647. plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));
  5648. plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));
  5649. plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));
  5650. plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));
  5651. }
  5652.  
  5653. function setupGrid() {
  5654. var i, axes = allAxes(), showGrid = options.grid.show;
  5655.  
  5656. // Initialize the plot's offset from the edge of the canvas
  5657.  
  5658. for (var a in plotOffset) {
  5659. var margin = options.grid.margin || 0;
  5660. plotOffset[a] = typeof margin == "number" ? margin : margin[a] || 0;
  5661. }
  5662.  
  5663. executeHooks(hooks.processOffset, [plotOffset]);
  5664.  
  5665. // If the grid is visible, add its border width to the offset
  5666.  
  5667. for (var a in plotOffset) {
  5668. if(typeof(options.grid.borderWidth) == "object") {
  5669. plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;
  5670. }
  5671. else {
  5672. plotOffset[a] += showGrid ? options.grid.borderWidth : 0;
  5673. }
  5674. }
  5675.  
  5676. $.each(axes, function (_, axis) {
  5677. var axisOpts = axis.options;
  5678. axis.show = axisOpts.show == null ? axis.used : axisOpts.show;
  5679. axis.reserveSpace = axisOpts.reserveSpace == null ? axis.show : axisOpts.reserveSpace;
  5680. setRange(axis);
  5681. });
  5682.  
  5683. if (showGrid) {
  5684.  
  5685. var allocatedAxes = $.grep(axes, function (axis) {
  5686. return axis.show || axis.reserveSpace;
  5687. });
  5688.  
  5689. $.each(allocatedAxes, function (_, axis) {
  5690. // make the ticks
  5691. setupTickGeneration(axis);
  5692. setTicks(axis);
  5693. snapRangeToTicks(axis, axis.ticks);
  5694. // find labelWidth/Height for axis
  5695. measureTickLabels(axis);
  5696. });
  5697.  
  5698. // with all dimensions calculated, we can compute the
  5699. // axis bounding boxes, start from the outside
  5700. // (reverse order)
  5701. for (i = allocatedAxes.length - 1; i >= 0; --i)
  5702. allocateAxisBoxFirstPhase(allocatedAxes[i]);
  5703.  
  5704. // make sure we've got enough space for things that
  5705. // might stick out
  5706. adjustLayoutForThingsStickingOut();
  5707.  
  5708. $.each(allocatedAxes, function (_, axis) {
  5709. allocateAxisBoxSecondPhase(axis);
  5710. });
  5711. }
  5712.  
  5713. plotWidth = surface.width - plotOffset.left - plotOffset.right;
  5714. plotHeight = surface.height - plotOffset.bottom - plotOffset.top;
  5715.  
  5716. // now we got the proper plot dimensions, we can compute the scaling
  5717. $.each(axes, function (_, axis) {
  5718. setTransformationHelpers(axis);
  5719. });
  5720.  
  5721. if (showGrid) {
  5722. drawAxisLabels();
  5723. }
  5724.  
  5725. insertLegend();
  5726. }
  5727.  
  5728. function setRange(axis) {
  5729. var opts = axis.options,
  5730. min = +(opts.min != null ? opts.min : axis.datamin),
  5731. max = +(opts.max != null ? opts.max : axis.datamax),
  5732. delta = max - min;
  5733.  
  5734. if (delta == 0.0) {
  5735. // degenerate case
  5736. var widen = max == 0 ? 1 : 0.01;
  5737.  
  5738. if (opts.min == null)
  5739. min -= widen;
  5740. // always widen max if we couldn't widen min to ensure we
  5741. // don't fall into min == max which doesn't work
  5742. if (opts.max == null || opts.min != null)
  5743. max += widen;
  5744. }
  5745. else {
  5746. // consider autoscaling
  5747. var margin = opts.autoscaleMargin;
  5748. if (margin != null) {
  5749. if (opts.min == null) {
  5750. min -= delta * margin;
  5751. // make sure we don't go below zero if all values
  5752. // are positive
  5753. if (min < 0 && axis.datamin != null && axis.datamin >= 0)
  5754. min = 0;
  5755. }
  5756. if (opts.max == null) {
  5757. max += delta * margin;
  5758. if (max > 0 && axis.datamax != null && axis.datamax <= 0)
  5759. max = 0;
  5760. }
  5761. }
  5762. }
  5763. axis.min = min;
  5764. axis.max = max;
  5765. }
  5766.  
  5767. function setupTickGeneration(axis) {
  5768. var opts = axis.options;
  5769.  
  5770. // estimate number of ticks
  5771. var noTicks;
  5772. if (typeof opts.ticks == "number" && opts.ticks > 0)
  5773. noTicks = opts.ticks;
  5774. else
  5775. // heuristic based on the model a*sqrt(x) fitted to
  5776. // some data points that seemed reasonable
  5777. noTicks = 0.3 * Math.sqrt(axis.direction == "x" ? surface.width : surface.height);
  5778.  
  5779. var delta = (axis.max - axis.min) / noTicks,
  5780. dec = -Math.floor(Math.log(delta) / Math.LN10),
  5781. maxDec = opts.tickDecimals;
  5782.  
  5783. if (maxDec != null && dec > maxDec) {
  5784. dec = maxDec;
  5785. }
  5786.  
  5787. var magn = Math.pow(10, -dec),
  5788. norm = delta / magn, // norm is between 1.0 and 10.0
  5789. size;
  5790.  
  5791. if (norm < 1.5) {
  5792. size = 1;
  5793. } else if (norm < 3) {
  5794. size = 2;
  5795. // special case for 2.5, requires an extra decimal
  5796. if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {
  5797. size = 2.5;
  5798. ++dec;
  5799. }
  5800. } else if (norm < 7.5) {
  5801. size = 5;
  5802. } else {
  5803. size = 10;
  5804. }
  5805.  
  5806. size *= magn;
  5807.  
  5808. if (opts.minTickSize != null && size < opts.minTickSize) {
  5809. size = opts.minTickSize;
  5810. }
  5811.  
  5812. axis.delta = delta;
  5813. axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);
  5814. axis.tickSize = opts.tickSize || size;
  5815.  
  5816. // Time mode was moved to a plug-in in 0.8, and since so many people use it
  5817. // we'll add an especially friendly reminder to make sure they included it.
  5818.  
  5819. if (opts.mode == "time" && !axis.tickGenerator) {
  5820. throw new Error("Time mode requires the flot.time plugin.");
  5821. }
  5822.  
  5823. // Flot supports base-10 axes; any other mode else is handled by a plug-in,
  5824. // like flot.time.js.
  5825.  
  5826. if (!axis.tickGenerator) {
  5827.  
  5828. axis.tickGenerator = function (axis) {
  5829.  
  5830. var ticks = [],
  5831. start = floorInBase(axis.min, axis.tickSize),
  5832. i = 0,
  5833. v = Number.NaN,
  5834. prev;
  5835.  
  5836. do {
  5837. prev = v;
  5838. v = start + i * axis.tickSize;
  5839. ticks.push(v);
  5840. ++i;
  5841. } while (v < axis.max && v != prev);
  5842. return ticks;
  5843. };
  5844.  
  5845. axis.tickFormatter = function (value, axis) {
  5846.  
  5847. var factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;
  5848. var formatted = "" + Math.round(value * factor) / factor;
  5849.  
  5850. // If tickDecimals was specified, ensure that we have exactly that
  5851. // much precision; otherwise default to the value's own precision.
  5852.  
  5853. if (axis.tickDecimals != null) {
  5854. var decimal = formatted.indexOf(".");
  5855. var precision = decimal == -1 ? 0 : formatted.length - decimal - 1;
  5856. if (precision < axis.tickDecimals) {
  5857. return (precision ? formatted : formatted + ".") + ("" + factor).substr(1, axis.tickDecimals - precision);
  5858. }
  5859. }
  5860.  
  5861. return formatted;
  5862. };
  5863. }
  5864.  
  5865. if ($.isFunction(opts.tickFormatter))
  5866. axis.tickFormatter = function (v, axis) { return "" + opts.tickFormatter(v, axis); };
  5867.  
  5868. if (opts.alignTicksWithAxis != null) {
  5869. var otherAxis = (axis.direction == "x" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];
  5870. if (otherAxis && otherAxis.used && otherAxis != axis) {
  5871. // consider snapping min/max to outermost nice ticks
  5872. var niceTicks = axis.tickGenerator(axis);
  5873. if (niceTicks.length > 0) {
  5874. if (opts.min == null)
  5875. axis.min = Math.min(axis.min, niceTicks[0]);
  5876. if (opts.max == null && niceTicks.length > 1)
  5877. axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);
  5878. }
  5879.  
  5880. axis.tickGenerator = function (axis) {
  5881. // copy ticks, scaled to this axis
  5882. var ticks = [], v, i;
  5883. for (i = 0; i < otherAxis.ticks.length; ++i) {
  5884. v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);
  5885. v = axis.min + v * (axis.max - axis.min);
  5886. ticks.push(v);
  5887. }
  5888. return ticks;
  5889. };
  5890.  
  5891. // we might need an extra decimal since forced
  5892. // ticks don't necessarily fit naturally
  5893. if (!axis.mode && opts.tickDecimals == null) {
  5894. var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),
  5895. ts = axis.tickGenerator(axis);
  5896.  
  5897. // only proceed if the tick interval rounded
  5898. // with an extra decimal doesn't give us a
  5899. // zero at end
  5900. if (!(ts.length > 1 && /\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))
  5901. axis.tickDecimals = extraDec;
  5902. }
  5903. }
  5904. }
  5905. }
  5906.  
  5907. function setTicks(axis) {
  5908. var oticks = axis.options.ticks, ticks = [];
  5909. if (oticks == null || (typeof oticks == "number" && oticks > 0))
  5910. ticks = axis.tickGenerator(axis);
  5911. else if (oticks) {
  5912. if ($.isFunction(oticks))
  5913. // generate the ticks
  5914. ticks = oticks(axis);
  5915. else
  5916. ticks = oticks;
  5917. }
  5918.  
  5919. // clean up/labelify the supplied ticks, copy them over
  5920. var i, v;
  5921. axis.ticks = [];
  5922. for (i = 0; i < ticks.length; ++i) {
  5923. var label = null;
  5924. var t = ticks[i];
  5925. if (typeof t == "object") {
  5926. v = +t[0];
  5927. if (t.length > 1)
  5928. label = t[1];
  5929. }
  5930. else
  5931. v = +t;
  5932. if (label == null)
  5933. label = axis.tickFormatter(v, axis);
  5934. if (!isNaN(v))
  5935. axis.ticks.push({ v: v, label: label });
  5936. }
  5937. }
  5938.  
  5939. function snapRangeToTicks(axis, ticks) {
  5940. if (axis.options.autoscaleMargin && ticks.length > 0) {
  5941. // snap to ticks
  5942. if (axis.options.min == null)
  5943. axis.min = Math.min(axis.min, ticks[0].v);
  5944. if (axis.options.max == null && ticks.length > 1)
  5945. axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);
  5946. }
  5947. }
  5948.  
  5949. function draw() {
  5950.  
  5951. surface.clear();
  5952.  
  5953. executeHooks(hooks.drawBackground, [ctx]);
  5954.  
  5955. var grid = options.grid;
  5956.  
  5957. // draw background, if any
  5958. if (grid.show && grid.backgroundColor)
  5959. drawBackground();
  5960.  
  5961. if (grid.show && !grid.aboveData) {
  5962. drawGrid();
  5963. }
  5964.  
  5965. for (var i = 0; i < series.length; ++i) {
  5966. executeHooks(hooks.drawSeries, [ctx, series[i]]);
  5967. drawSeries(series[i]);
  5968. }
  5969.  
  5970. executeHooks(hooks.draw, [ctx]);
  5971.  
  5972. if (grid.show && grid.aboveData) {
  5973. drawGrid();
  5974. }
  5975.  
  5976. surface.render();
  5977.  
  5978. // A draw implies that either the axes or data have changed, so we
  5979. // should probably update the overlay highlights as well.
  5980.  
  5981. triggerRedrawOverlay();
  5982. }
  5983.  
  5984. function extractRange(ranges, coord) {
  5985. var axis, from, to, key, axes = allAxes();
  5986.  
  5987. for (var i = 0; i < axes.length; ++i) {
  5988. axis = axes[i];
  5989. if (axis.direction == coord) {
  5990. key = coord + axis.n + "axis";
  5991. if (!ranges[key] && axis.n == 1)
  5992. key = coord + "axis"; // support x1axis as xaxis
  5993. if (ranges[key]) {
  5994. from = ranges[key].from;
  5995. to = ranges[key].to;
  5996. break;
  5997. }
  5998. }
  5999. }
  6000.  
  6001. // backwards-compat stuff - to be removed in future
  6002. if (!ranges[key]) {
  6003. axis = coord == "x" ? xaxes[0] : yaxes[0];
  6004. from = ranges[coord + "1"];
  6005. to = ranges[coord + "2"];
  6006. }
  6007.  
  6008. // auto-reverse as an added bonus
  6009. if (from != null && to != null && from > to) {
  6010. var tmp = from;
  6011. from = to;
  6012. to = tmp;
  6013. }
  6014.  
  6015. return { from: from, to: to, axis: axis };
  6016. }
  6017.  
  6018. function drawBackground() {
  6019. ctx.save();
  6020. ctx.translate(plotOffset.left, plotOffset.top);
  6021.  
  6022. ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)");
  6023. ctx.fillRect(0, 0, plotWidth, plotHeight);
  6024. ctx.restore();
  6025. }
  6026.  
  6027. function drawGrid() {
  6028. var i, axes, bw, bc;
  6029.  
  6030. ctx.save();
  6031. ctx.translate(plotOffset.left, plotOffset.top);
  6032.  
  6033. // draw markings
  6034. var markings = options.grid.markings;
  6035. if (markings) {
  6036. if ($.isFunction(markings)) {
  6037. axes = plot.getAxes();
  6038. // xmin etc. is backwards compatibility, to be
  6039. // removed in the future
  6040. axes.xmin = axes.xaxis.min;
  6041. axes.xmax = axes.xaxis.max;
  6042. axes.ymin = axes.yaxis.min;
  6043. axes.ymax = axes.yaxis.max;
  6044.  
  6045. markings = markings(axes);
  6046. }
  6047.  
  6048. for (i = 0; i < markings.length; ++i) {
  6049. var m = markings[i],
  6050. xrange = extractRange(m, "x"),
  6051. yrange = extractRange(m, "y");
  6052.  
  6053. // fill in missing
  6054. if (xrange.from == null)
  6055. xrange.from = xrange.axis.min;
  6056. if (xrange.to == null)
  6057. xrange.to = xrange.axis.max;
  6058. if (yrange.from == null)
  6059. yrange.from = yrange.axis.min;
  6060. if (yrange.to == null)
  6061. yrange.to = yrange.axis.max;
  6062.  
  6063. // clip
  6064. if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||
  6065. yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)
  6066. continue;
  6067.  
  6068. xrange.from = Math.max(xrange.from, xrange.axis.min);
  6069. xrange.to = Math.min(xrange.to, xrange.axis.max);
  6070. yrange.from = Math.max(yrange.from, yrange.axis.min);
  6071. yrange.to = Math.min(yrange.to, yrange.axis.max);
  6072.  
  6073. var xequal = xrange.from === xrange.to,
  6074. yequal = yrange.from === yrange.to;
  6075.  
  6076. if (xequal && yequal) {
  6077. continue;
  6078. }
  6079.  
  6080. // then draw
  6081. xrange.from = Math.floor(xrange.axis.p2c(xrange.from));
  6082. xrange.to = Math.floor(xrange.axis.p2c(xrange.to));
  6083. yrange.from = Math.floor(yrange.axis.p2c(yrange.from));
  6084. yrange.to = Math.floor(yrange.axis.p2c(yrange.to));
  6085.  
  6086. if (xequal || yequal) {
  6087. var lineWidth = m.lineWidth || options.grid.markingsLineWidth,
  6088. subPixel = lineWidth % 2 ? 0.5 : 0;
  6089. ctx.beginPath();
  6090. ctx.strokeStyle = m.color || options.grid.markingsColor;
  6091. ctx.lineWidth = lineWidth;
  6092. if (xequal) {
  6093. ctx.moveTo(xrange.to + subPixel, yrange.from);
  6094. ctx.lineTo(xrange.to + subPixel, yrange.to);
  6095. } else {
  6096. ctx.moveTo(xrange.from, yrange.to + subPixel);
  6097. ctx.lineTo(xrange.to, yrange.to + subPixel);
  6098. }
  6099. ctx.stroke();
  6100. } else {
  6101. ctx.fillStyle = m.color || options.grid.markingsColor;
  6102. ctx.fillRect(xrange.from, yrange.to,
  6103. xrange.to - xrange.from,
  6104. yrange.from - yrange.to);
  6105. }
  6106. }
  6107. }
  6108.  
  6109. // draw the ticks
  6110. axes = allAxes();
  6111. bw = options.grid.borderWidth;
  6112.  
  6113. for (var j = 0; j < axes.length; ++j) {
  6114. var axis = axes[j], box = axis.box,
  6115. t = axis.tickLength, x, y, xoff, yoff;
  6116. if (!axis.show || axis.ticks.length == 0)
  6117. continue;
  6118.  
  6119. ctx.lineWidth = 1;
  6120.  
  6121. // find the edges
  6122. if (axis.direction == "x") {
  6123. x = 0;
  6124. if (t == "full")
  6125. y = (axis.position == "top" ? 0 : plotHeight);
  6126. else
  6127. y = box.top - plotOffset.top + (axis.position == "top" ? box.height : 0);
  6128. }
  6129. else {
  6130. y = 0;
  6131. if (t == "full")
  6132. x = (axis.position == "left" ? 0 : plotWidth);
  6133. else
  6134. x = box.left - plotOffset.left + (axis.position == "left" ? box.width : 0);
  6135. }
  6136.  
  6137. // draw tick bar
  6138. if (!axis.innermost) {
  6139. ctx.strokeStyle = axis.options.color;
  6140. ctx.beginPath();
  6141. xoff = yoff = 0;
  6142. if (axis.direction == "x")
  6143. xoff = plotWidth + 1;
  6144. else
  6145. yoff = plotHeight + 1;
  6146.  
  6147. if (ctx.lineWidth == 1) {
  6148. if (axis.direction == "x") {
  6149. y = Math.floor(y) + 0.5;
  6150. } else {
  6151. x = Math.floor(x) + 0.5;
  6152. }
  6153. }
  6154.  
  6155. ctx.moveTo(x, y);
  6156. ctx.lineTo(x + xoff, y + yoff);
  6157. ctx.stroke();
  6158. }
  6159.  
  6160. // draw ticks
  6161.  
  6162. ctx.strokeStyle = axis.options.tickColor;
  6163.  
  6164. ctx.beginPath();
  6165. for (i = 0; i < axis.ticks.length; ++i) {
  6166. var v = axis.ticks[i].v;
  6167.  
  6168. xoff = yoff = 0;
  6169.  
  6170. if (isNaN(v) || v < axis.min || v > axis.max
  6171. // skip those lying on the axes if we got a border
  6172. || (t == "full"
  6173. && ((typeof bw == "object" && bw[axis.position] > 0) || bw > 0)
  6174. && (v == axis.min || v == axis.max)))
  6175. continue;
  6176.  
  6177. if (axis.direction == "x") {
  6178. x = axis.p2c(v);
  6179. yoff = t == "full" ? -plotHeight : t;
  6180.  
  6181. if (axis.position == "top")
  6182. yoff = -yoff;
  6183. }
  6184. else {
  6185. y = axis.p2c(v);
  6186. xoff = t == "full" ? -plotWidth : t;
  6187.  
  6188. if (axis.position == "left")
  6189. xoff = -xoff;
  6190. }
  6191.  
  6192. if (ctx.lineWidth == 1) {
  6193. if (axis.direction == "x")
  6194. x = Math.floor(x) + 0.5;
  6195. else
  6196. y = Math.floor(y) + 0.5;
  6197. }
  6198.  
  6199. ctx.moveTo(x, y);
  6200. ctx.lineTo(x + xoff, y + yoff);
  6201. }
  6202.  
  6203. ctx.stroke();
  6204. }
  6205.  
  6206.  
  6207. // draw border
  6208. if (bw) {
  6209. // If either borderWidth or borderColor is an object, then draw the border
  6210. // line by line instead of as one rectangle
  6211. bc = options.grid.borderColor;
  6212. if(typeof bw == "object" || typeof bc == "object") {
  6213. if (typeof bw !== "object") {
  6214. bw = {top: bw, right: bw, bottom: bw, left: bw};
  6215. }
  6216. if (typeof bc !== "object") {
  6217. bc = {top: bc, right: bc, bottom: bc, left: bc};
  6218. }
  6219.  
  6220. if (bw.top > 0) {
  6221. ctx.strokeStyle = bc.top;
  6222. ctx.lineWidth = bw.top;
  6223. ctx.beginPath();
  6224. ctx.moveTo(0 - bw.left, 0 - bw.top/2);
  6225. ctx.lineTo(plotWidth, 0 - bw.top/2);
  6226. ctx.stroke();
  6227. }
  6228.  
  6229. if (bw.right > 0) {
  6230. ctx.strokeStyle = bc.right;
  6231. ctx.lineWidth = bw.right;
  6232. ctx.beginPath();
  6233. ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);
  6234. ctx.lineTo(plotWidth + bw.right / 2, plotHeight);
  6235. ctx.stroke();
  6236. }
  6237.  
  6238. if (bw.bottom > 0) {
  6239. ctx.strokeStyle = bc.bottom;
  6240. ctx.lineWidth = bw.bottom;
  6241. ctx.beginPath();
  6242. ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);
  6243. ctx.lineTo(0, plotHeight + bw.bottom / 2);
  6244. ctx.stroke();
  6245. }
  6246.  
  6247. if (bw.left > 0) {
  6248. ctx.strokeStyle = bc.left;
  6249. ctx.lineWidth = bw.left;
  6250. ctx.beginPath();
  6251. ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);
  6252. ctx.lineTo(0- bw.left/2, 0);
  6253. ctx.stroke();
  6254. }
  6255. }
  6256. else {
  6257. ctx.lineWidth = bw;
  6258. ctx.strokeStyle = options.grid.borderColor;
  6259. ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);
  6260. }
  6261. }
  6262.  
  6263. ctx.restore();
  6264. }
  6265.  
  6266. function drawAxisLabels() {
  6267.  
  6268. $.each(allAxes(), function (_, axis) {
  6269. var box = axis.box,
  6270. legacyStyles = axis.direction + "Axis " + axis.direction + axis.n + "Axis",
  6271. layer = "flot-" + axis.direction + "-axis flot-" + axis.direction + axis.n + "-axis " + legacyStyles,
  6272. font = axis.options.font || "flot-tick-label tickLabel",
  6273. tick, x, y, halign, valign;
  6274.  
  6275. // Remove text before checking for axis.show and ticks.length;
  6276. // otherwise plugins, like flot-tickrotor, that draw their own
  6277. // tick labels will end up with both theirs and the defaults.
  6278.  
  6279. surface.removeText(layer);
  6280.  
  6281. if (!axis.show || axis.ticks.length == 0)
  6282. return;
  6283.  
  6284. for (var i = 0; i < axis.ticks.length; ++i) {
  6285.  
  6286. tick = axis.ticks[i];
  6287. if (!tick.label || tick.v < axis.min || tick.v > axis.max)
  6288. continue;
  6289.  
  6290. if (axis.direction == "x") {
  6291. halign = "center";
  6292. x = plotOffset.left + axis.p2c(tick.v);
  6293. if (axis.position == "bottom") {
  6294. y = box.top + box.padding;
  6295. } else {
  6296. y = box.top + box.height - box.padding;
  6297. valign = "bottom";
  6298. }
  6299. } else {
  6300. valign = "middle";
  6301. y = plotOffset.top + axis.p2c(tick.v);
  6302. if (axis.position == "left") {
  6303. x = box.left + box.width - box.padding;
  6304. halign = "right";
  6305. } else {
  6306. x = box.left + box.padding;
  6307. }
  6308. }
  6309.  
  6310. surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);
  6311. }
  6312. });
  6313. }
  6314.  
  6315. function drawSeries(series) {
  6316. if (series.lines.show)
  6317. drawSeriesLines(series);
  6318. if (series.bars.show)
  6319. drawSeriesBars(series);
  6320. if (series.points.show)
  6321. drawSeriesPoints(series);
  6322. }
  6323.  
  6324. function drawSeriesLines(series) {
  6325. function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {
  6326. var points = datapoints.points,
  6327. ps = datapoints.pointsize,
  6328. prevx = null, prevy = null;
  6329.  
  6330. ctx.beginPath();
  6331. for (var i = ps; i < points.length; i += ps) {
  6332. var x1 = points[i - ps], y1 = points[i - ps + 1],
  6333. x2 = points[i], y2 = points[i + 1];
  6334.  
  6335. if (x1 == null || x2 == null)
  6336. continue;
  6337.  
  6338. // clip with ymin
  6339. if (y1 <= y2 && y1 < axisy.min) {
  6340. if (y2 < axisy.min)
  6341. continue; // line segment is outside
  6342. // compute new intersection point
  6343. x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
  6344. y1 = axisy.min;
  6345. }
  6346. else if (y2 <= y1 && y2 < axisy.min) {
  6347. if (y1 < axisy.min)
  6348. continue;
  6349. x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
  6350. y2 = axisy.min;
  6351. }
  6352.  
  6353. // clip with ymax
  6354. if (y1 >= y2 && y1 > axisy.max) {
  6355. if (y2 > axisy.max)
  6356. continue;
  6357. x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
  6358. y1 = axisy.max;
  6359. }
  6360. else if (y2 >= y1 && y2 > axisy.max) {
  6361. if (y1 > axisy.max)
  6362. continue;
  6363. x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
  6364. y2 = axisy.max;
  6365. }
  6366.  
  6367. // clip with xmin
  6368. if (x1 <= x2 && x1 < axisx.min) {
  6369. if (x2 < axisx.min)
  6370. continue;
  6371. y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
  6372. x1 = axisx.min;
  6373. }
  6374. else if (x2 <= x1 && x2 < axisx.min) {
  6375. if (x1 < axisx.min)
  6376. continue;
  6377. y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
  6378. x2 = axisx.min;
  6379. }
  6380.  
  6381. // clip with xmax
  6382. if (x1 >= x2 && x1 > axisx.max) {
  6383. if (x2 > axisx.max)
  6384. continue;
  6385. y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
  6386. x1 = axisx.max;
  6387. }
  6388. else if (x2 >= x1 && x2 > axisx.max) {
  6389. if (x1 > axisx.max)
  6390. continue;
  6391. y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
  6392. x2 = axisx.max;
  6393. }
  6394.  
  6395. if (x1 != prevx || y1 != prevy)
  6396. ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);
  6397.  
  6398. prevx = x2;
  6399. prevy = y2;
  6400. ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);
  6401. }
  6402. ctx.stroke();
  6403. }
  6404.  
  6405. function plotLineArea(datapoints, axisx, axisy) {
  6406. var points = datapoints.points,
  6407. ps = datapoints.pointsize,
  6408. bottom = Math.min(Math.max(0, axisy.min), axisy.max),
  6409. i = 0, top, areaOpen = false,
  6410. ypos = 1, segmentStart = 0, segmentEnd = 0;
  6411.  
  6412. // we process each segment in two turns, first forward
  6413. // direction to sketch out top, then once we hit the
  6414. // end we go backwards to sketch the bottom
  6415. while (true) {
  6416. if (ps > 0 && i > points.length + ps)
  6417. break;
  6418.  
  6419. i += ps; // ps is negative if going backwards
  6420.  
  6421. var x1 = points[i - ps],
  6422. y1 = points[i - ps + ypos],
  6423. x2 = points[i], y2 = points[i + ypos];
  6424.  
  6425. if (areaOpen) {
  6426. if (ps > 0 && x1 != null && x2 == null) {
  6427. // at turning point
  6428. segmentEnd = i;
  6429. ps = -ps;
  6430. ypos = 2;
  6431. continue;
  6432. }
  6433.  
  6434. if (ps < 0 && i == segmentStart + ps) {
  6435. // done with the reverse sweep
  6436. ctx.fill();
  6437. areaOpen = false;
  6438. ps = -ps;
  6439. ypos = 1;
  6440. i = segmentStart = segmentEnd + ps;
  6441. continue;
  6442. }
  6443. }
  6444.  
  6445. if (x1 == null || x2 == null)
  6446. continue;
  6447.  
  6448. // clip x values
  6449.  
  6450. // clip with xmin
  6451. if (x1 <= x2 && x1 < axisx.min) {
  6452. if (x2 < axisx.min)
  6453. continue;
  6454. y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
  6455. x1 = axisx.min;
  6456. }
  6457. else if (x2 <= x1 && x2 < axisx.min) {
  6458. if (x1 < axisx.min)
  6459. continue;
  6460. y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;
  6461. x2 = axisx.min;
  6462. }
  6463.  
  6464. // clip with xmax
  6465. if (x1 >= x2 && x1 > axisx.max) {
  6466. if (x2 > axisx.max)
  6467. continue;
  6468. y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
  6469. x1 = axisx.max;
  6470. }
  6471. else if (x2 >= x1 && x2 > axisx.max) {
  6472. if (x1 > axisx.max)
  6473. continue;
  6474. y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;
  6475. x2 = axisx.max;
  6476. }
  6477.  
  6478. if (!areaOpen) {
  6479. // open area
  6480. ctx.beginPath();
  6481. ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));
  6482. areaOpen = true;
  6483. }
  6484.  
  6485. // now first check the case where both is outside
  6486. if (y1 >= axisy.max && y2 >= axisy.max) {
  6487. ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));
  6488. ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));
  6489. continue;
  6490. }
  6491. else if (y1 <= axisy.min && y2 <= axisy.min) {
  6492. ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));
  6493. ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));
  6494. continue;
  6495. }
  6496.  
  6497. // else it's a bit more complicated, there might
  6498. // be a flat maxed out rectangle first, then a
  6499. // triangular cutout or reverse; to find these
  6500. // keep track of the current x values
  6501. var x1old = x1, x2old = x2;
  6502.  
  6503. // clip the y values, without shortcutting, we
  6504. // go through all cases in turn
  6505.  
  6506. // clip with ymin
  6507. if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {
  6508. x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
  6509. y1 = axisy.min;
  6510. }
  6511. else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {
  6512. x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;
  6513. y2 = axisy.min;
  6514. }
  6515.  
  6516. // clip with ymax
  6517. if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {
  6518. x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
  6519. y1 = axisy.max;
  6520. }
  6521. else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {
  6522. x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;
  6523. y2 = axisy.max;
  6524. }
  6525.  
  6526. // if the x value was changed we got a rectangle
  6527. // to fill
  6528. if (x1 != x1old) {
  6529. ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));
  6530. // it goes to (x1, y1), but we fill that below
  6531. }
  6532.  
  6533. // fill triangular section, this sometimes result
  6534. // in redundant points if (x1, y1) hasn't changed
  6535. // from previous line to, but we just ignore that
  6536. ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));
  6537. ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
  6538.  
  6539. // fill the other rectangle if it's there
  6540. if (x2 != x2old) {
  6541. ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));
  6542. ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));
  6543. }
  6544. }
  6545. }
  6546.  
  6547. ctx.save();
  6548. ctx.translate(plotOffset.left, plotOffset.top);
  6549. ctx.lineJoin = "round";
  6550.  
  6551. var lw = series.lines.lineWidth,
  6552. sw = series.shadowSize;
  6553. // FIXME: consider another form of shadow when filling is turned on
  6554. if (lw > 0 && sw > 0) {
  6555. // draw shadow as a thick and thin line with transparency
  6556. ctx.lineWidth = sw;
  6557. ctx.strokeStyle = "rgba(0,0,0,0.1)";
  6558. // position shadow at angle from the mid of line
  6559. var angle = Math.PI/18;
  6560. plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);
  6561. ctx.lineWidth = sw/2;
  6562. plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);
  6563. }
  6564.  
  6565. ctx.lineWidth = lw;
  6566. ctx.strokeStyle = series.color;
  6567. var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);
  6568. if (fillStyle) {
  6569. ctx.fillStyle = fillStyle;
  6570. plotLineArea(series.datapoints, series.xaxis, series.yaxis);
  6571. }
  6572.  
  6573. if (lw > 0)
  6574. plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);
  6575. ctx.restore();
  6576. }
  6577.  
  6578. function drawSeriesPoints(series) {
  6579. function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {
  6580. var points = datapoints.points, ps = datapoints.pointsize;
  6581.  
  6582. for (var i = 0; i < points.length; i += ps) {
  6583. var x = points[i], y = points[i + 1];
  6584. if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
  6585. continue;
  6586.  
  6587. ctx.beginPath();
  6588. x = axisx.p2c(x);
  6589. y = axisy.p2c(y) + offset;
  6590. if (symbol == "circle")
  6591. ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);
  6592. else
  6593. symbol(ctx, x, y, radius, shadow);
  6594. ctx.closePath();
  6595.  
  6596. if (fillStyle) {
  6597. ctx.fillStyle = fillStyle;
  6598. ctx.fill();
  6599. }
  6600. ctx.stroke();
  6601. }
  6602. }
  6603.  
  6604. ctx.save();
  6605. ctx.translate(plotOffset.left, plotOffset.top);
  6606.  
  6607. var lw = series.points.lineWidth,
  6608. sw = series.shadowSize,
  6609. radius = series.points.radius,
  6610. symbol = series.points.symbol;
  6611.  
  6612. // If the user sets the line width to 0, we change it to a very
  6613. // small value. A line width of 0 seems to force the default of 1.
  6614. // Doing the conditional here allows the shadow setting to still be
  6615. // optional even with a lineWidth of 0.
  6616.  
  6617. if( lw == 0 )
  6618. lw = 0.0001;
  6619.  
  6620. if (lw > 0 && sw > 0) {
  6621. // draw shadow in two steps
  6622. var w = sw / 2;
  6623. ctx.lineWidth = w;
  6624. ctx.strokeStyle = "rgba(0,0,0,0.1)";
  6625. plotPoints(series.datapoints, radius, null, w + w/2, true,
  6626. series.xaxis, series.yaxis, symbol);
  6627.  
  6628. ctx.strokeStyle = "rgba(0,0,0,0.2)";
  6629. plotPoints(series.datapoints, radius, null, w/2, true,
  6630. series.xaxis, series.yaxis, symbol);
  6631. }
  6632.  
  6633. ctx.lineWidth = lw;
  6634. ctx.strokeStyle = series.color;
  6635. plotPoints(series.datapoints, radius,
  6636. getFillStyle(series.points, series.color), 0, false,
  6637. series.xaxis, series.yaxis, symbol);
  6638. ctx.restore();
  6639. }
  6640.  
  6641. function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {
  6642. var left, right, bottom, top,
  6643. drawLeft, drawRight, drawTop, drawBottom,
  6644. tmp;
  6645.  
  6646. // in horizontal mode, we start the bar from the left
  6647. // instead of from the bottom so it appears to be
  6648. // horizontal rather than vertical
  6649. if (horizontal) {
  6650. drawBottom = drawRight = drawTop = true;
  6651. drawLeft = false;
  6652. left = b;
  6653. right = x;
  6654. top = y + barLeft;
  6655. bottom = y + barRight;
  6656.  
  6657. // account for negative bars
  6658. if (right < left) {
  6659. tmp = right;
  6660. right = left;
  6661. left = tmp;
  6662. drawLeft = true;
  6663. drawRight = false;
  6664. }
  6665. }
  6666. else {
  6667. drawLeft = drawRight = drawTop = true;
  6668. drawBottom = false;
  6669. left = x + barLeft;
  6670. right = x + barRight;
  6671. bottom = b;
  6672. top = y;
  6673.  
  6674. // account for negative bars
  6675. if (top < bottom) {
  6676. tmp = top;
  6677. top = bottom;
  6678. bottom = tmp;
  6679. drawBottom = true;
  6680. drawTop = false;
  6681. }
  6682. }
  6683.  
  6684. // clip
  6685. if (right < axisx.min || left > axisx.max ||
  6686. top < axisy.min || bottom > axisy.max)
  6687. return;
  6688.  
  6689. if (left < axisx.min) {
  6690. left = axisx.min;
  6691. drawLeft = false;
  6692. }
  6693.  
  6694. if (right > axisx.max) {
  6695. right = axisx.max;
  6696. drawRight = false;
  6697. }
  6698.  
  6699. if (bottom < axisy.min) {
  6700. bottom = axisy.min;
  6701. drawBottom = false;
  6702. }
  6703.  
  6704. if (top > axisy.max) {
  6705. top = axisy.max;
  6706. drawTop = false;
  6707. }
  6708.  
  6709. left = axisx.p2c(left);
  6710. bottom = axisy.p2c(bottom);
  6711. right = axisx.p2c(right);
  6712. top = axisy.p2c(top);
  6713.  
  6714. // fill the bar
  6715. if (fillStyleCallback) {
  6716. c.fillStyle = fillStyleCallback(bottom, top);
  6717. c.fillRect(left, top, right - left, bottom - top)
  6718. }
  6719.  
  6720. // draw outline
  6721. if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {
  6722. c.beginPath();
  6723.  
  6724. // FIXME: inline moveTo is buggy with excanvas
  6725. c.moveTo(left, bottom);
  6726. if (drawLeft)
  6727. c.lineTo(left, top);
  6728. else
  6729. c.moveTo(left, top);
  6730. if (drawTop)
  6731. c.lineTo(right, top);
  6732. else
  6733. c.moveTo(right, top);
  6734. if (drawRight)
  6735. c.lineTo(right, bottom);
  6736. else
  6737. c.moveTo(right, bottom);
  6738. if (drawBottom)
  6739. c.lineTo(left, bottom);
  6740. else
  6741. c.moveTo(left, bottom);
  6742. c.stroke();
  6743. }
  6744. }
  6745.  
  6746. function drawSeriesBars(series) {
  6747. function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {
  6748. var points = datapoints.points, ps = datapoints.pointsize;
  6749.  
  6750. for (var i = 0; i < points.length; i += ps) {
  6751. if (points[i] == null)
  6752. continue;
  6753. drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);
  6754. }
  6755. }
  6756.  
  6757. ctx.save();
  6758. ctx.translate(plotOffset.left, plotOffset.top);
  6759.  
  6760. // FIXME: figure out a way to add shadows (for instance along the right edge)
  6761. ctx.lineWidth = series.bars.lineWidth;
  6762. ctx.strokeStyle = series.color;
  6763.  
  6764. var barLeft;
  6765.  
  6766. switch (series.bars.align) {
  6767. case "left":
  6768. barLeft = 0;
  6769. break;
  6770. case "right":
  6771. barLeft = -series.bars.barWidth;
  6772. break;
  6773. default:
  6774. barLeft = -series.bars.barWidth / 2;
  6775. }
  6776.  
  6777. var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;
  6778. plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);
  6779. ctx.restore();
  6780. }
  6781.  
  6782. function getFillStyle(filloptions, seriesColor, bottom, top) {
  6783. var fill = filloptions.fill;
  6784. if (!fill)
  6785. return null;
  6786.  
  6787. if (filloptions.fillColor)
  6788. return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);
  6789.  
  6790. var c = $.color.parse(seriesColor);
  6791. c.a = typeof fill == "number" ? fill : 0.4;
  6792. c.normalize();
  6793. return c.toString();
  6794. }
  6795.  
  6796. function insertLegend() {
  6797.  
  6798. if (options.legend.container != null) {
  6799. $(options.legend.container).html("");
  6800. } else {
  6801. placeholder.find(".legend").remove();
  6802. }
  6803.  
  6804. if (!options.legend.show) {
  6805. return;
  6806. }
  6807.  
  6808. var fragments = [], entries = [], rowStarted = false,
  6809. lf = options.legend.labelFormatter, s, label;
  6810.  
  6811. // Build a list of legend entries, with each having a label and a color
  6812.  
  6813. for (var i = 0; i < series.length; ++i) {
  6814. s = series[i];
  6815. if (s.label) {
  6816. label = lf ? lf(s.label, s) : s.label;
  6817. if (label) {
  6818. entries.push({
  6819. label: label,
  6820. color: s.color
  6821. });
  6822. }
  6823. }
  6824. }
  6825.  
  6826. // Sort the legend using either the default or a custom comparator
  6827.  
  6828. if (options.legend.sorted) {
  6829. if ($.isFunction(options.legend.sorted)) {
  6830. entries.sort(options.legend.sorted);
  6831. } else if (options.legend.sorted == "reverse") {
  6832. entries.reverse();
  6833. } else {
  6834. var ascending = options.legend.sorted != "descending";
  6835. entries.sort(function(a, b) {
  6836. return a.label == b.label ? 0 : (
  6837. (a.label < b.label) != ascending ? 1 : -1 // Logical XOR
  6838. );
  6839. });
  6840. }
  6841. }
  6842.  
  6843. // Generate markup for the list of entries, in their final order
  6844.  
  6845. for (var i = 0; i < entries.length; ++i) {
  6846.  
  6847. var entry = entries[i];
  6848.  
  6849. if (i % options.legend.noColumns == 0) {
  6850. if (rowStarted)
  6851. fragments.push('</tr>');
  6852. fragments.push('<tr>');
  6853. rowStarted = true;
  6854. }
  6855.  
  6856. fragments.push(
  6857. '<td class="legendColorBox"><div style="border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px"><div style="width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden"></div></div></td>' +
  6858. '<td class="legendLabel">' + entry.label + '</td>'
  6859. );
  6860. }
  6861.  
  6862. if (rowStarted)
  6863. fragments.push('</tr>');
  6864.  
  6865. if (fragments.length == 0)
  6866. return;
  6867.  
  6868. var table = '<table style="font-size:smaller;color:' + options.grid.color + '">' + fragments.join("") + '</table>';
  6869. if (options.legend.container != null)
  6870. $(options.legend.container).html(table);
  6871. else {
  6872. var pos = "",
  6873. p = options.legend.position,
  6874. m = options.legend.margin;
  6875. if (m[0] == null)
  6876. m = [m, m];
  6877. if (p.charAt(0) == "n")
  6878. pos += 'top:' + (m[1] + plotOffset.top) + 'px;';
  6879. else if (p.charAt(0) == "s")
  6880. pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';
  6881. if (p.charAt(1) == "e")
  6882. pos += 'right:' + (m[0] + plotOffset.right) + 'px;';
  6883. else if (p.charAt(1) == "w")
  6884. pos += 'left:' + (m[0] + plotOffset.left) + 'px;';
  6885. var legend = $('<div class="legend">' + table.replace('style="', 'style="position:absolute;' + pos +';') + '</div>').appendTo(placeholder);
  6886. if (options.legend.backgroundOpacity != 0.0) {
  6887. // put in the transparent background
  6888. // separately to avoid blended labels and
  6889. // label boxes
  6890. var c = options.legend.backgroundColor;
  6891. if (c == null) {
  6892. c = options.grid.backgroundColor;
  6893. if (c && typeof c == "string")
  6894. c = $.color.parse(c);
  6895. else
  6896. c = $.color.extract(legend, 'background-color');
  6897. c.a = 1;
  6898. c = c.toString();
  6899. }
  6900. var div = legend.children();
  6901. $('<div style="position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);
  6902. }
  6903. }
  6904. }
  6905.  
  6906.  
  6907. // interactive features
  6908.  
  6909. var highlights = [],
  6910. redrawTimeout = null;
  6911.  
  6912. // returns the data item the mouse is over, or null if none is found
  6913. function findNearbyItem(mouseX, mouseY, seriesFilter) {
  6914. var maxDistance = options.grid.mouseActiveRadius,
  6915. smallestDistance = maxDistance * maxDistance + 1,
  6916. item = null, foundPoint = false, i, j, ps;
  6917.  
  6918. for (i = series.length - 1; i >= 0; --i) {
  6919. if (!seriesFilter(series[i]))
  6920. continue;
  6921.  
  6922. var s = series[i],
  6923. axisx = s.xaxis,
  6924. axisy = s.yaxis,
  6925. points = s.datapoints.points,
  6926. mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster
  6927. my = axisy.c2p(mouseY),
  6928. maxx = maxDistance / axisx.scale,
  6929. maxy = maxDistance / axisy.scale;
  6930.  
  6931. ps = s.datapoints.pointsize;
  6932. // with inverse transforms, we can't use the maxx/maxy
  6933. // optimization, sadly
  6934. if (axisx.options.inverseTransform)
  6935. maxx = Number.MAX_VALUE;
  6936. if (axisy.options.inverseTransform)
  6937. maxy = Number.MAX_VALUE;
  6938.  
  6939. if (s.lines.show || s.points.show) {
  6940. for (j = 0; j < points.length; j += ps) {
  6941. var x = points[j], y = points[j + 1];
  6942. if (x == null)
  6943. continue;
  6944.  
  6945. // For points and lines, the cursor must be within a
  6946. // certain distance to the data point
  6947. if (x - mx > maxx || x - mx < -maxx ||
  6948. y - my > maxy || y - my < -maxy)
  6949. continue;
  6950.  
  6951. // We have to calculate distances in pixels, not in
  6952. // data units, because the scales of the axes may be different
  6953. var dx = Math.abs(axisx.p2c(x) - mouseX),
  6954. dy = Math.abs(axisy.p2c(y) - mouseY),
  6955. dist = dx * dx + dy * dy; // we save the sqrt
  6956.  
  6957. // use <= to ensure last point takes precedence
  6958. // (last generally means on top of)
  6959. if (dist < smallestDistance) {
  6960. smallestDistance = dist;
  6961. item = [i, j / ps];
  6962. }
  6963. }
  6964. }
  6965.  
  6966. if (s.bars.show && !item) { // no other point can be nearby
  6967.  
  6968. var barLeft, barRight;
  6969.  
  6970. switch (s.bars.align) {
  6971. case "left":
  6972. barLeft = 0;
  6973. break;
  6974. case "right":
  6975. barLeft = -s.bars.barWidth;
  6976. break;
  6977. default:
  6978. barLeft = -s.bars.barWidth / 2;
  6979. }
  6980.  
  6981. barRight = barLeft + s.bars.barWidth;
  6982.  
  6983. for (j = 0; j < points.length; j += ps) {
  6984. var x = points[j], y = points[j + 1], b = points[j + 2];
  6985. if (x == null)
  6986. continue;
  6987.  
  6988. // for a bar graph, the cursor must be inside the bar
  6989. if (series[i].bars.horizontal ?
  6990. (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&
  6991. my >= y + barLeft && my <= y + barRight) :
  6992. (mx >= x + barLeft && mx <= x + barRight &&
  6993. my >= Math.min(b, y) && my <= Math.max(b, y)))
  6994. item = [i, j / ps];
  6995. }
  6996. }
  6997. }
  6998.  
  6999. if (item) {
  7000. i = item[0];
  7001. j = item[1];
  7002. ps = series[i].datapoints.pointsize;
  7003.  
  7004. return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),
  7005. dataIndex: j,
  7006. series: series[i],
  7007. seriesIndex: i };
  7008. }
  7009.  
  7010. return null;
  7011. }
  7012.  
  7013. function onMouseMove(e) {
  7014. if (options.grid.hoverable)
  7015. triggerClickHoverEvent("plothover", e,
  7016. function (s) { return s["hoverable"] != false; });
  7017. }
  7018.  
  7019. function onMouseLeave(e) {
  7020. if (options.grid.hoverable)
  7021. triggerClickHoverEvent("plothover", e,
  7022. function (s) { return false; });
  7023. }
  7024.  
  7025. function onClick(e) {
  7026. triggerClickHoverEvent("plotclick", e,
  7027. function (s) { return s["clickable"] != false; });
  7028. }
  7029.  
  7030. // trigger click or hover event (they send the same parameters
  7031. // so we share their code)
  7032. function triggerClickHoverEvent(eventname, event, seriesFilter) {
  7033. var offset = eventHolder.offset(),
  7034. canvasX = event.pageX - offset.left - plotOffset.left,
  7035. canvasY = event.pageY - offset.top - plotOffset.top,
  7036. pos = canvasToAxisCoords({ left: canvasX, top: canvasY });
  7037.  
  7038. pos.pageX = event.pageX;
  7039. pos.pageY = event.pageY;
  7040.  
  7041. var item = findNearbyItem(canvasX, canvasY, seriesFilter);
  7042.  
  7043. if (item) {
  7044. // fill in mouse pos for any listeners out there
  7045. item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);
  7046. item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);
  7047. }
  7048.  
  7049. if (options.grid.autoHighlight) {
  7050. // clear auto-highlights
  7051. for (var i = 0; i < highlights.length; ++i) {
  7052. var h = highlights[i];
  7053. if (h.auto == eventname &&
  7054. !(item && h.series == item.series &&
  7055. h.point[0] == item.datapoint[0] &&
  7056. h.point[1] == item.datapoint[1]))
  7057. unhighlight(h.series, h.point);
  7058. }
  7059.  
  7060. if (item)
  7061. highlight(item.series, item.datapoint, eventname);
  7062. }
  7063.  
  7064. placeholder.trigger(eventname, [ pos, item ]);
  7065. }
  7066.  
  7067. function triggerRedrawOverlay() {
  7068. var t = options.interaction.redrawOverlayInterval;
  7069. if (t == -1) { // skip event queue
  7070. drawOverlay();
  7071. return;
  7072. }
  7073.  
  7074. if (!redrawTimeout)
  7075. redrawTimeout = setTimeout(drawOverlay, t);
  7076. }
  7077.  
  7078. function drawOverlay() {
  7079. redrawTimeout = null;
  7080.  
  7081. // draw highlights
  7082. octx.save();
  7083. overlay.clear();
  7084. octx.translate(plotOffset.left, plotOffset.top);
  7085.  
  7086. var i, hi;
  7087. for (i = 0; i < highlights.length; ++i) {
  7088. hi = highlights[i];
  7089.  
  7090. if (hi.series.bars.show)
  7091. drawBarHighlight(hi.series, hi.point);
  7092. else
  7093. drawPointHighlight(hi.series, hi.point);
  7094. }
  7095. octx.restore();
  7096.  
  7097. executeHooks(hooks.drawOverlay, [octx]);
  7098. }
  7099.  
  7100. function highlight(s, point, auto) {
  7101. if (typeof s == "number")
  7102. s = series[s];
  7103.  
  7104. if (typeof point == "number") {
  7105. var ps = s.datapoints.pointsize;
  7106. point = s.datapoints.points.slice(ps * point, ps * (point + 1));
  7107. }
  7108.  
  7109. var i = indexOfHighlight(s, point);
  7110. if (i == -1) {
  7111. highlights.push({ series: s, point: point, auto: auto });
  7112.  
  7113. triggerRedrawOverlay();
  7114. }
  7115. else if (!auto)
  7116. highlights[i].auto = false;
  7117. }
  7118.  
  7119. function unhighlight(s, point) {
  7120. if (s == null && point == null) {
  7121. highlights = [];
  7122. triggerRedrawOverlay();
  7123. return;
  7124. }
  7125.  
  7126. if (typeof s == "number")
  7127. s = series[s];
  7128.  
  7129. if (typeof point == "number") {
  7130. var ps = s.datapoints.pointsize;
  7131. point = s.datapoints.points.slice(ps * point, ps * (point + 1));
  7132. }
  7133.  
  7134. var i = indexOfHighlight(s, point);
  7135. if (i != -1) {
  7136. highlights.splice(i, 1);
  7137.  
  7138. triggerRedrawOverlay();
  7139. }
  7140. }
  7141.  
  7142. function indexOfHighlight(s, p) {
  7143. for (var i = 0; i < highlights.length; ++i) {
  7144. var h = highlights[i];
  7145. if (h.series == s && h.point[0] == p[0]
  7146. && h.point[1] == p[1])
  7147. return i;
  7148. }
  7149. return -1;
  7150. }
  7151.  
  7152. function drawPointHighlight(series, point) {
  7153. var x = point[0], y = point[1],
  7154. axisx = series.xaxis, axisy = series.yaxis,
  7155. highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();
  7156.  
  7157. if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)
  7158. return;
  7159.  
  7160. var pointRadius = series.points.radius + series.points.lineWidth / 2;
  7161. octx.lineWidth = pointRadius;
  7162. octx.strokeStyle = highlightColor;
  7163. var radius = 1.5 * pointRadius;
  7164. x = axisx.p2c(x);
  7165. y = axisy.p2c(y);
  7166.  
  7167. octx.beginPath();
  7168. if (series.points.symbol == "circle")
  7169. octx.arc(x, y, radius, 0, 2 * Math.PI, false);
  7170. else
  7171. series.points.symbol(octx, x, y, radius, false);
  7172. octx.closePath();
  7173. octx.stroke();
  7174. }
  7175.  
  7176. function drawBarHighlight(series, point) {
  7177. var highlightColor = (typeof series.highlightColor === "string") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),
  7178. fillStyle = highlightColor,
  7179. barLeft;
  7180.  
  7181. switch (series.bars.align) {
  7182. case "left":
  7183. barLeft = 0;
  7184. break;
  7185. case "right":
  7186. barLeft = -series.bars.barWidth;
  7187. break;
  7188. default:
  7189. barLeft = -series.bars.barWidth / 2;
  7190. }
  7191.  
  7192. octx.lineWidth = series.bars.lineWidth;
  7193. octx.strokeStyle = highlightColor;
  7194.  
  7195. drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,
  7196. function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);
  7197. }
  7198.  
  7199. function getColorOrGradient(spec, bottom, top, defaultColor) {
  7200. if (typeof spec == "string")
  7201. return spec;
  7202. else {
  7203. // assume this is a gradient spec; IE currently only
  7204. // supports a simple vertical gradient properly, so that's
  7205. // what we support too
  7206. var gradient = ctx.createLinearGradient(0, top, 0, bottom);
  7207.  
  7208. for (var i = 0, l = spec.colors.length; i < l; ++i) {
  7209. var c = spec.colors[i];
  7210. if (typeof c != "string") {
  7211. var co = $.color.parse(defaultColor);
  7212. if (c.brightness != null)
  7213. co = co.scale('rgb', c.brightness);
  7214. if (c.opacity != null)
  7215. co.a *= c.opacity;
  7216. c = co.toString();
  7217. }
  7218. gradient.addColorStop(i / (l - 1), c);
  7219. }
  7220.  
  7221. return gradient;
  7222. }
  7223. }
  7224. }
  7225.  
  7226. // Add the plot function to the top level of the jQuery object
  7227.  
  7228. $.plot = function(placeholder, data, options) {
  7229. //var t0 = new Date();
  7230. var plot = new Plot($(placeholder), data, options, $.plot.plugins);
  7231. //(window.console ? console.log : alert)("time used (msecs): " + ((new Date()).getTime() - t0.getTime()));
  7232. return plot;
  7233. };
  7234.  
  7235. $.plot.version = "0.8.3";
  7236.  
  7237. $.plot.plugins = [];
  7238.  
  7239. // Also add the plot function as a chainable property
  7240.  
  7241. $.fn.plot = function(data, options) {
  7242. return this.each(function() {
  7243. $.plot(this, data, options);
  7244. });
  7245. };
  7246.  
  7247. // round to nearby lower multiple of base
  7248. function floorInBase(n, base) {
  7249. return base * Math.floor(n / base);
  7250. }
  7251.  
  7252. })(jQuery);
  7253. }
  7254. }
  7255. /* ===== Load UserScript ===== */
  7256. function addJQuery(callback){
  7257. var script = document.createElement("script");
  7258. script.async = true;
  7259. script.setAttribute("src", "//ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js");
  7260. script.addEventListener(
  7261. 'load',
  7262. function(){
  7263. var script = document.createElement("script");
  7264. script.async = true;
  7265. script.textContent = "window.jQ = jQuery.noConflict(true);"+
  7266. "("+callback.toString()+")();";
  7267. document.head.appendChild(script);
  7268. },
  7269. false
  7270. );
  7271. document.head.appendChild(script);
  7272. }
  7273. if(window.location.host.indexOf("worldofwarships") > -1){
  7274. addJQuery(WoWsStatInfo);
  7275. }
  7276. })(window);