WME Locksmith

Dynamic locking tool which locks based on State standards

  1. // ==UserScript==
  2. // @name WME Locksmith
  3. // @namespace https://gf.qytechs.cn/en/users/286957-skidooguy
  4. // @version 2023.09.26.00
  5. // @description Dynamic locking tool which locks based on State standards
  6. // @author SkiDooGuy / JustinS83 / Blaine "herrchin" Kahle
  7. // @match https://www.waze.com/editor*
  8. // @match https://www.waze.com/*/editor*
  9. // @match https://beta.waze.com/editor*
  10. // @match https://beta.waze.com/*/editor*
  11. // @exclude https://www.waze.com/user/editor*
  12. // @require https://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js
  13. // @require https://apis.google.com/js/api.js
  14. // @grant none
  15. // @contributionURL https://github.com/WazeDev/Thank-The-Authors
  16. // ==/UserScript==
  17.  
  18. /* global W */
  19. /* global WazeWrap */
  20. /* global $ */
  21. /* global OpenLayers */
  22. /* global _ */
  23. /* global require */
  24.  
  25. const LOCKSMITH_VERSION = `v${GM_info.script.version}`;
  26. const FEATURELOCK = 2;
  27. const LS_UPDATE_NOTES = `<b>NEW:</b><br>
  28. - Allowed for "Current Standards" string to be translated<br><br>
  29. <b>FIXES:</b><br>
  30. - <br><br>`;
  31. const TRANSLATIONS = {
  32. default: {
  33. scriptTitle: 'Locksmith',
  34. sheetTooltip: 'Spreadsheet Connection',
  35. rankTooltip: 'Allows segments that you cannot edit or lock to the standard rank to be highlighted and show in the UI',
  36. highLockTooltip: 'Watch out for map exceptions, some higher locks are there for a reason!',
  37. resetTooltip: 'Reset lock values and UI',
  38. attrTooltip: 'Colored attributes are available in this state, click to toggle them enabled',
  39. resetValue: 'Reset',
  40. scanValue: 'Scan',
  41. lockAllValue: 'Lock All',
  42. optionsMenu: 'Options',
  43. activeScan: 'Active Scan',
  44. enHighlights: 'Enable Highlights',
  45. detAbvRank: 'Detect segs above my rank',
  46. saveCustLock: 'Save custom locks',
  47. saveScnSet: 'Save scan settings',
  48. manStateSel: 'Manual state select',
  49. disStatePop: 'Disable states popup',
  50. ovrLockSegs: 'Include overlocked segs',
  51. lockStand: 'Lock Standards ',
  52. lockStat: 'Lock Status: Low | High | All',
  53. othrSegTypes: 'Other segment types: ',
  54. addAttr: 'Additional Attributes',
  55. roadNonPed: 'NonRout Ped',
  56. roadRun: 'Runway',
  57. roadFry: 'Ferry',
  58. roadRail: 'Railroad',
  59. roadOff: 'Off-Road',
  60. roadPLR: 'PLR',
  61. roadPVT: 'PVT',
  62. roadLS: 'LS',
  63. roadPS: 'PS',
  64. roadMinH: 'mH',
  65. roadMajH: 'MH',
  66. roadRmp: 'Ramp',
  67. roadFwy: 'Fwy',
  68. unpaved: 'Unpaved',
  69. oneWay: 'One-way',
  70. hov: 'HOV',
  71. wkt: 'WKT',
  72. toll: 'Toll',
  73. currentStandards: 'Current Standards',
  74. option0: 'Auto',
  75. optionHRCS: 'HRCS'
  76. }
  77.  
  78. };
  79.  
  80. let _allStandardsArray = {};
  81. let _currentStateStandards = {};
  82. let LsSettings = {};
  83. let _currentState = '';
  84. let cakeFlavor;
  85. let roadClear = false;
  86. let LocksmithHighlightLayer;
  87. let tries = 0;
  88. let UpdateObj;
  89. let editorInfo;
  90. let country;
  91. let langLocality = 'default';
  92.  
  93.  
  94. console.log('Locksmith(LS): initializing...');
  95.  
  96. const css = [
  97. '.ls-Wrapper {width:100%;height:100%;margin-bottom:30%;background-color:white;border:2px solid white;border-radius:6px;font-size:12px;font-family:Poppins, "Helvetica Neue", Helvetica, "Open Sans", sans-serif;user-select:none;}',
  98. '.ls-Body {display:block;padding:3px;}',
  99. '.ls-Header-Wrapper {display:block;width:100%;}',
  100. '.ls-Header-Text-Container {width:100%;padding:0 5px 0 5px;display:inline-block;border-bottom:1px solid grey;}',
  101. '.ls-Label {display:inline-block;position:relative;padding-right:20px;font-weight:normal;margin:5px 0 0 0;width:auto;cursor:pointer;}',
  102. '.ls-Label input[type=checkbox] {position:absolute;opacity:0;height:0;width:0;}',
  103. '.ls-CheckBox {position:absolute;height:13px;width:13px;background-color:#eee;border:1px solid black;border-radius:4px;top:1px;right:0px;}',
  104. '.ls-Label:hover input ~ .ls-CheckBox {background-color:#ccc;}',
  105. '.ls-Label input:checked ~ .ls-CheckBox {background-color:rgb(66 184 196);}',
  106. '.ls-Options-Container {display:inline-block;}',
  107. '.ls-Options-Menu {position:relative;display:block;width:100%;float:left;padding:3px;border:1px solid black;border-radius:5px;text-align:center;}',
  108. '.ls-Options-Menu:hover {border:1.5px outset grey;background-color:rgb(224,224,224);}',
  109. '.ls-Options-Dropdown-Menu {display:none;position:absolute;background-color:#f9f9f9;min-width:160px;top:25px;left:0px;z-index:1;text-align:left;}',
  110. '.ls-Options-Menu:hover .ls-Options-Dropdown-Menu {display:block;}',
  111. '.ls-Options-Dropdown-Menu ul {list-style:none;padding-left:0px;border:1px solid grey;border-radius:5px;}',
  112. '.ls-Options-Dropdown-Menu li {padding:5px;}',
  113. '.ls-Options-Dropdown-Menu li:hover {background-color:rgb(220,220,220);border:.5px solid lightgrey;border-radius:5px;}',
  114. '.ls-Section-Container {display:inline-block;width:100%;}',
  115. '.ls-Section-Header {width:100%;display:block;padding-bottom:2px;border-bottom:1.5px solid grey;margin-bottom:5px;}',
  116. '.ls-Select {color:#444;box-sizing:border-box;margin-right:5px;outline:none;padding:3px;border:1px solid lightgrey;border-radius:6px;}',
  117. '.ls-Select:hover {border:1px solid grey;}',
  118. '.ls-Select:focus {border:1px solid black;}',
  119. '.ls-Lock-Options {display:block;width:100%;max-height:3-px;margin-bottom:3px;}',
  120. '.ls-Seg-Result {display:inline-block;position:relative;float:right;top:8px;}',
  121. '.ls-IL-Block {display:inline-block;}',
  122. '.fa.fa-arrow-circle-up {position:relative;color:lightgrey;padding:0px 5px 0px 5px}',
  123. '.fa.fa-arrow-circle-down {position:relative;color:lightgrey;padding:0px 5px 0px 5px}',
  124. '.ls-Seg-Quantity-Low {position:relative;padding:0px 5px 0px 5px;}',
  125. '.ls-Seg-Quantity-High {position:relative;padding:0px 5px 0px 5px;}',
  126. '.ls-Seg-Quantity-Low.enabled {}',
  127. '.ls-Seg-Quantity-High.enabled {}',
  128. '.ls-Seg-Attributes {display:inline-block;border:1px solid lightgrey;border-radius:5px;padding:2px;margin:4px;background-color:lightgrey;font-size:12px}',
  129. '.ls-Attr-Label {display:inline-block;position:relative;padding:2px 5px 2px 2px;font-size:12px;font-weight:bold;width:auto;}',
  130. '.ls-Attr-Label input[type=checkbox] {position:absolute;opacity:0;height:0;width:0;}',
  131. '.ls-Attr-CheckBox {position:relative;padding:2px;background-color:lightgrey;border:1px solid lightgrey;border-radius:4px;top:1px;right:0px;}',
  132. '.ls-Attr-Label:hover input ~ .ls-Attr-CheckBox {border:1.2px outset grey;}',
  133. '.ls-Attr-Label input:checked ~ .ls-Attr-CheckBox {border:1.2px outset black;}',
  134. '.ls-Button-Container {position:relative;display:inline-block;float:right;padding-top:3px;width:40%;}',
  135. '.ls-Button {border:1px solid black;border-radius:5px;cursor:pointer;padding:3px;background-color:white;}',
  136. '.ls-Button:hover {border:1.5px outset grey;background-color:rgb(224,224,224);}',
  137. '.key-Text {font-weight:bold;font-size:14px;}',
  138. '#lsConnectionStatus {display:inline;position:relative;height:15px;width:30px;border:1px solid lightgrey;border-radius:4px;font-size:8px;text-align:center;font-weight:bold;top:-2px;left:2px;line-height:1.5;}'
  139. ].join(' ');
  140.  
  141. function Locksmithbootstrap() {
  142. if (typeof W === 'object' && W.userscripts?.state?.isReady && W.map && W.model && W.model.countries && W.model.states && W.loginManager.user && $ && WazeWrap.Ready) {
  143. checkCountry();
  144. if (country === null) {
  145. setTimeout(function () {
  146. Locksmithbootstrap();
  147. }, 200);
  148. } else {
  149. initLocksmith();
  150. }
  151. } else if (tries < 500) {
  152. setTimeout(() => {
  153. tries++;
  154. Locksmithbootstrap();
  155. }, 200);
  156. } else console.log('LS: Failed to load');
  157. }
  158.  
  159. function initLocksmith() {
  160. editorInfo = W.loginManager.user;
  161.  
  162. const $section = $('<div>');
  163. // HTML for UI tab
  164. $section.html([
  165. '<div class="ls-Wrapper">',
  166. '<div class="ls-Body">',
  167. `<div class="ls-Header-Wrapper">
  168. <div class="ls-Header-Text-Container">
  169. <span class='key-Text'>Locksmith</span> - ${LOCKSMITH_VERSION}
  170. <a href='https://docs.google.com/spreadsheets/d/1z9WQW_6xdXDn9nz_087DoZby2XxcDSxxRbby_y1tKho/edit#gid=0' target="_blank" id='lsConnectionStatus' data-original-title='${TRANSLATIONS[langLocality].colTooltip}'></a>
  171. </div>
  172. <div class="ls-Options-Container" style="display:block;height:35px;padding:2px 10px 0 10px;width:100%">
  173. <div style="display:inline-block;float:left;position:relative;width:60%;">
  174. <div class="ls-Options-Container" style="margin:3px 0 0 0;">
  175. <div class="ls-Options-Menu">
  176. <div><span id='ls-text-options'></span></div>
  177. <div class="ls-Options-Dropdown-Menu">
  178. <ul>
  179. <li>
  180. <label class="ls-Label">
  181. <span id='ls-text-activeScan'></span>
  182. <input type="checkbox" class="ls-Save-Status" id="lsEnableActiveScan">
  183. <span class="ls-CheckBox"></span>
  184. </label>
  185. </li>
  186. <li>
  187. <label class="ls-Label">
  188. <span id='ls-text-enHighlights'></span>
  189. <input type="checkbox" class="ls-Save-Status" id="lsEnableHighlightSeg">
  190. <span class="ls-CheckBox"></span>
  191. </label>
  192. </li>
  193. <li>
  194. <label class="ls-Label">
  195. <span id='ls-text-saveCustLock'></span>
  196. <input type="checkbox" class="ls-Save-Status" id="lsEnableSaveValues">
  197. <span class="ls-CheckBox"></span>
  198. </label>
  199. </li>
  200. <li>
  201. <label class="ls-Label">
  202. <span id='ls-text-saveScnSet'></span>
  203. <input type="checkbox" class="ls-Save-Status" id="lsEnableSaveSettings">
  204. <span class="ls-CheckBox"></span>
  205. </label>
  206. </li>
  207. <li>
  208. <label class="ls-Label" style="margin:0px;">
  209. <span id='ls-text-manStateSel'></span>
  210. <input type="checkbox" id="lsManualStateOverride">
  211. <span class="ls-CheckBox"></span>
  212. </label>
  213. </li>
  214. <li>
  215. <label class="ls-Label">
  216. <span id='ls-text-disStatePop'></span>
  217. <input type="checkbox" class="ls-Save-Status" id="lsDisableStatePopup">
  218. <span class="ls-CheckBox"></span>
  219. </label>
  220. </li>
  221. <li id="ls-Above-Rank-Tooltip" data-original-title='${TRANSLATIONS.default.rankTooltip}'>
  222. <label class="ls-Label">
  223. <span id='ls-text-detAbvRank'></span>
  224. <input type="checkbox" class="ls-Save-Status" id="lsEnableIgnoreRank">
  225. <span class="ls-CheckBox"></span>
  226. </label>
  227. </li>
  228. <li id="ls-Higher-Level-Tooltip" data-original-title='${TRANSLATIONS.default.highLockTooltip}'>
  229. <label class="ls-Label" style="font-weight:bold;">
  230. <span id='ls-text-ovrLockSegs'></span>
  231. <input type="checkbox" class="ls-Save-Status" id="lsEnableResetHigher">
  232. <span class="ls-CheckBox"></span>
  233. </label>
  234. </li>
  235. </ul>
  236. </div>
  237. </div>
  238. </div>
  239. <div class="ls-Button-Container" style="width:50%;left:-20px">
  240. <input type="button" class="ls-Button" id="ls-Reset-Standards-Display" style="position:relative;" value='${TRANSLATIONS.default.resetValue}' data-original-title='${TRANSLATIONS.default.resetTooltip}'>
  241. </div>
  242. </div>
  243. <div class="ls-Button-Container">
  244. <input type="button" class="ls-Button" style="position:relative;left:5px;" id="ls-Maual-Scan-Activate" value='${TRANSLATIONS.default.scanValue}'>
  245. <input type="button" class="ls-Button" style="float:right;" id="ls-Lock-All-Submit" value='${TRANSLATIONS.default.lockAllValue}'>
  246. </div>
  247. </div>
  248. </div>
  249. <div class="ls-Section-Container" style="margin-top:0px;">
  250. <div class="ls-Section-Container">
  251. <span style="float:left;border-bottom:1px solid black;" id='ls-text-lockStand'></span>
  252. <span style="float:right;border-bottom:1px solid black;" id='ls-text-lockStat'></span>
  253. </div>
  254.  
  255. <div class="ls-Section-Container">
  256. <div class="ls-Section-Container" id="ls-Seg-Types-Main">
  257. <div class="ls-Lock-Options">
  258. <select class="ls-Select" id="lsLockStreetSelect">
  259. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  260. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  261. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  262. <option class="ls-Lock-Option-6">6</option>
  263. </select>
  264. <span class="ls-LS-Label"></span>
  265. <div class="ls-Seg-Result">
  266. <div id="ls-Seg-Result-LS" style="float:right;">
  267. <div class="ls-IL-Block">
  268. <span class="fa fa-arrow-circle-up" id="ls-LS-Lock-Up"></span>
  269. <span class="ls-Seg-Quantity-Low" id="ls-LS-Low-Quan"></span>
  270. </div>
  271. <div class="ls-IL-Block">
  272. <span class="fa fa-arrow-circle-down" id="ls-LS-Lock-Down"></span>
  273. <span class="ls-Seg-Quantity-High" id="ls-LS-High-Quan"></span>
  274. </div>
  275. <span class="fa fa-lock" id="icon-Lock-LS" style="color:lightgrey;padding-left:10px;float:right;"></span>
  276. </div>
  277. </div>
  278. </div>
  279.  
  280. <div class="ls-Lock-Options">
  281. <select class="ls-Select" id="lsLockPSSelect">
  282. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  283. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  284. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  285. <option class="ls-Lock-Option-6">6</option>
  286. </select>
  287. <span class="ls-PS-Label"></span>
  288. <div class="ls-Seg-Result">
  289. <div id="ls-Seg-Result-PS" style="float:right;">
  290. <div class="ls-IL-Block">
  291. <span class="fa fa-arrow-circle-up" id="ls-PS-Lock-Up"></span>
  292. <span class="ls-Seg-Quantity-Low" id="ls-PS-Low-Quan"></span>
  293. </div>
  294. <div class="ls-IL-Block">
  295. <span class="fa fa-arrow-circle-down" id="ls-PS-Lock-Down"></span>
  296. <span class="ls-Seg-Quantity-High" id="ls-PS-High-Quan"></span>
  297. </div>
  298. <span class="fa fa-lock" id="icon-Lock-PS" style="color:lightgrey;padding-left:10px;float:right;"></span>
  299. </div>
  300. </div>
  301. </div>
  302.  
  303. <div class="ls-Lock-Options">
  304. <select class="ls-Select" id="lsLockMinHSelect">
  305. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  306. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  307. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  308. <option class="ls-Lock-Option-6">6</option>
  309. </select>
  310. <span class="ls-minH-Label"></span>
  311. <div class="ls-Seg-Result">
  312. <div id="ls-Seg-Result-minH" style="float:right;">
  313. <div class="ls-IL-Block">
  314. <span class="fa fa-arrow-circle-up" id="ls-minH-Lock-Up"></span>
  315. <span class="ls-Seg-Quantity-Low" id="ls-minH-Low-Quan"></span>
  316. </div>
  317. <div class="ls-IL-Block">
  318. <span class="fa fa-arrow-circle-down" id="ls-minH-Lock-Down"></span>
  319. <span class="ls-Seg-Quantity-High" id="ls-minH-High-Quan"></span>
  320. </div>
  321. <span class="fa fa-lock" id="icon-Lock-minH" style="color:lightgrey;padding-left:10px;float:right;"></span>
  322. </div>
  323. </div>
  324. </div>
  325.  
  326. <div class="ls-Lock-Options">
  327. <select class="ls-Select" id="lsLockMajHSelect">
  328. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  329. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  330. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  331. <option class="ls-Lock-Option-6">6</option>
  332. </select>
  333. <span class="ls-majH-Label"></span>
  334. <div class="ls-Seg-Result">
  335. <div id="ls-Seg-Result-majH" style="float:right;">
  336. <div class="ls-IL-Block">
  337. <span class="fa fa-arrow-circle-up" id="ls-majH-Lock-Up"></span>
  338. <span class="ls-Seg-Quantity-Low" id="ls-majH-Low-Quan"></span>
  339. </div>
  340. <div class="ls-IL-Block">
  341. <span class="fa fa-arrow-circle-down" id="ls-majH-Lock-Down"></span>
  342. <span class="ls-Seg-Quantity-High" id="ls-majH-High-Quan"></span>
  343. </div>
  344. <span class="fa fa-lock" id="icon-Lock-majH" style="color:lightgrey;padding-left:10px;float:right;"></span>
  345. </div>
  346. </div>
  347. </div>
  348.  
  349. <div class="ls-Lock-Options">
  350. <select class="ls-Select" id="lsLockRmpSelect">
  351. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-HRCS">${TRANSLATIONS.default.optionHRCS}</option>
  352. <option class="ls-Lock-Option-1">1</option><option class="ls-Lock-Option-2">2</option>
  353. <option class="ls-Lock-Option-3">3</option><option class="ls-Lock-Option-4">4</option>
  354. <option class="ls-Lock-Option-5">5</option><option class="ls-Lock-Option-6">6</option>
  355. </select>
  356. <span class="ls-Ramp-Label"></span>
  357. <div class="ls-Seg-Result">
  358. <div id="ls-Seg-Result-Rmp" style="float:right;">
  359. <div class="ls-IL-Block">
  360. <span class="fa fa-arrow-circle-up" id="ls-Rmp-Lock-Up"></span>
  361. <span class="ls-Seg-Quantity-Low" id="ls-Rmp-Low-Quan"></span>
  362. </div>
  363. <div class="ls-IL-Block">
  364. <span class="fa fa-arrow-circle-down" id="ls-Rmp-Lock-Down"></span>
  365. <span class="ls-Seg-Quantity-High" id="ls-Rmp-High-Quan"></span>
  366. </div>
  367. <span class="fa fa-lock" id="icon-Lock-Rmp" style="color:lightgrey;padding-left:10px;float:right;"></span>
  368. </div>
  369. </div>
  370. </div>
  371.  
  372. <div class="ls-Lock-Options">
  373. <select class="ls-Select" id="lsLockFwySelect">
  374. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  375. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  376. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  377. <option class="ls-Lock-Option-6">6</option>
  378. </select>
  379. <span class="ls-FWY-Label"></span>
  380. <div class="ls-Seg-Result">
  381. <div id="ls-Seg-Result-Fwy" style="float:right;">
  382. <div class="ls-IL-Block">
  383. <span class="fa fa-arrow-circle-up" id="ls-Fwy-Lock-Up"></span>
  384. <span class="ls-Seg-Quantity-Low" id="ls-Fwy-Low-Quan"></span>
  385. </div>
  386. <div class="ls-IL-Block">
  387. <span class="fa fa-arrow-circle-down" id="ls-Fwy-Lock-Down"></span>
  388. <span class="ls-Seg-Quantity-High" id="ls-Fwy-High-Quan"></span>
  389. </div>
  390. <span class="fa fa-lock" id="icon-Lock-Fwy" style="color:lightgrey;padding-left:10px;float:right;"></span>
  391. </div>
  392. </div>
  393. </div>
  394. </div>
  395.  
  396. <div class="ls-Lock-Options">
  397. <div style="display:inline-block;float:left;cursor:pointer;" id="ls-Othr-Seg-Label"><span id='ls-text-othrSegTypes'></span></div>
  398. <div class="ls-Seg-Result" style="top:5px;" id="rl-Othr-Result-Container">
  399. <div class="ls-IL-Block">
  400. <span class="fa fa-arrow-circle-up" id="ls-othr-Lock-Up"></span>
  401. <span class="ls-Seg-Quantity-Low" id="ls-othr-Low-Quan"></span>
  402. </div>
  403. <div class="ls-IL-Block">
  404. <span class="fa fa-arrow-circle-down" id="ls-othr-Lock-Down"></span>
  405. <span class="ls-Seg-Quantity-High" id="ls-othr-High-Quan"></span>
  406. </div>
  407. <span class="fa fa-lock" id="icon-Lock-othr" style="color:lightgrey;padding-left:10px;float:right;"></span>
  408. </div>
  409. </div>
  410.  
  411. <div class="ls-Section-Container" id="ls-Seg-Types-Alt" style="display:none;">
  412. <div class="ls-Lock-Options" style="margin-top:3px;">
  413. <select class="ls-Select" id="lsLockPvtSelect">
  414. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  415. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  416. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  417. <option class="ls-Lock-Option-6">6</option>
  418. </select>
  419. <span class="ls-Pvt-Label"></span>
  420. <div class="ls-Seg-Result">
  421. <div id="ls-Seg-Result-Pvt" style="float:right;">
  422. <div class="ls-IL-Block">
  423. <span class="fa fa-arrow-circle-up" id="ls-Pvt-Lock-Up"></span>
  424. <span class="ls-Seg-Quantity-Low" id="ls-Pvt-Low-Quan"></span>
  425. </div>
  426. <div class="ls-IL-Block">
  427. <span class="fa fa-arrow-circle-down" id="ls-Pvt-Lock-Down"></span>
  428. <span class="ls-Seg-Quantity-High" id="ls-Pvt-High-Quan"></span>
  429. </div>
  430. <span class="fa fa-lock" id="icon-Lock-Pvt" style="color:lightgrey;padding-left:10px;float:right;"></span>
  431. </div>
  432. </div>
  433. </div>
  434.  
  435. <div class="ls-Lock-Options">
  436. <select class="ls-Select" id="lsLockPlrSelect">
  437. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  438. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  439. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  440. <option class="ls-Lock-Option-6">6</option>
  441. </select>
  442. <span class="ls-Plr-Label"></span>
  443. <div class="ls-Seg-Result">
  444. <div id="ls-Seg-Result-Plr" style="float:right;">
  445. <div class="ls-IL-Block">
  446. <span class="fa fa-arrow-circle-up" id="ls-Plr-Lock-Up"></span>
  447. <span class="ls-Seg-Quantity-Low" id="ls-Plr-Low-Quan"></span>
  448. </div>
  449. <div class="ls-IL-Block">
  450. <span class="fa fa-arrow-circle-down" id="ls-Plr-Lock-Down"></span>
  451. <span class="ls-Seg-Quantity-High" id="ls-Plr-High-Quan"></span>
  452. </div>
  453. <span class="fa fa-lock" id="icon-Lock-Plr" style="color:lightgrey;padding-left:10px;float:right;"></span>
  454. </div>
  455. </div>
  456. </div>
  457.  
  458. <div class="ls-Lock-Options">
  459. <select class="ls-Select" id="lsLockRailSelect">
  460. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  461. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  462. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  463. <option class="ls-Lock-Option-6">6</option>
  464. </select>
  465. <span class="ls-Rail-Label"></span>
  466. <div class="ls-Seg-Result">
  467. <div id="ls-Seg-Result-Rail" style="float:right;">
  468. <div class="ls-IL-Block">
  469. <span class="fa fa-arrow-circle-up" id="ls-Rail-Lock-Up"></span>
  470. <span class="ls-Seg-Quantity-Low" id="ls-Rail-Low-Quan"></span>
  471. </div>
  472. <div class="ls-IL-Block">
  473. <span class="fa fa-arrow-circle-down" id="ls-Rail-Lock-Down"></span>
  474. <span class="ls-Seg-Quantity-High" id="ls-Rail-High-Quan"></span>
  475. </div>
  476. <span class="fa fa-lock" id="icon-Lock-Rail" style="color:lightgrey;padding-left:10px;float:right;"></span>
  477. </div>
  478. </div>
  479. </div>
  480.  
  481. <div class="ls-Lock-Options">
  482. <select class="ls-Select" id="lsLockFrySelect">
  483. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  484. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  485. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  486. <option class="ls-Lock-Option-6">6</option>
  487. </select>
  488. <span class="ls-Fry-Label"></span>
  489. <div class="ls-Seg-Result">
  490. <div id="ls-Seg-Result-Fry" style="float:right;">
  491. <div class="ls-IL-Block">
  492. <span class="fa fa-arrow-circle-up" id="ls-Fry-Lock-Up"></span>
  493. <span class="ls-Seg-Quantity-Low" id="ls-Fry-Low-Quan"></span>
  494. </div>
  495. <div class="ls-IL-Block">
  496. <span class="fa fa-arrow-circle-down" id="ls-Fry-Lock-Down"></span>
  497. <span class="ls-Seg-Quantity-High" id="ls-Fry-High-Quan"></span>
  498. </div>
  499. <span class="fa fa-lock" id="icon-Lock-Fry" style="color:lightgrey;padding-left:10px;float:right;"></span>
  500. </div>
  501. </div>
  502. </div>
  503.  
  504. <div class="ls-Lock-Options">
  505. <select class="ls-Select" id="lsLockRnwySelect">
  506. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  507. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  508. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  509. <option class="ls-Lock-Option-6">6</option>
  510. </select>
  511. <span class="ls-Rnwy-Label"></span>
  512. <div class="ls-Seg-Result">
  513. <div id="ls-Seg-Result-Rnwy" style="float:right;">
  514. <div class="ls-IL-Block">
  515. <span class="fa fa-arrow-circle-up" id="ls-Rnwy-Lock-Up"></span>
  516. <span class="ls-Seg-Quantity-Low" id="ls-Rnwy-Low-Quan"></span>
  517. </div>
  518. <div class="ls-IL-Block">
  519. <span class="fa fa-arrow-circle-down" id="ls-Rnwy-Lock-Down"></span>
  520. <span class="ls-Seg-Quantity-High" id="ls-Rnwy-High-Quan"></span>
  521. </div>
  522. <span class="fa fa-lock" id="icon-Lock-Rnwy" style="color:lightgrey;padding-left:10px;float:right;"></span>
  523. </div>
  524. </div>
  525. </div>
  526.  
  527. <div class="ls-Lock-Options">
  528. <select class="ls-Select" id="lsLockOfrdSelect">
  529. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  530. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  531. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  532. <option class="ls-Lock-Option-6">6</option>
  533. </select>
  534. <span class="ls-Ofrd-Label"></span>
  535. <div class="ls-Seg-Result">
  536. <div id="ls-Seg-Result-Ofrd" style="float:right;">
  537. <div class="ls-IL-Block">
  538. <span class="fa fa-arrow-circle-up" id="ls-Ofrd-Lock-Up"></span>
  539. <span class="ls-Seg-Quantity-Low" id="ls-Ofrd-Low-Quan"></span>
  540. </div>
  541. <div class="ls-IL-Block">
  542. <span class="fa fa-arrow-circle-down" id="ls-Ofrd-Lock-Down"></span>
  543. <span class="ls-Seg-Quantity-High" id="ls-Ofrd-High-Quan"></span>
  544. </div>
  545. <span class="fa fa-lock" id="icon-Lock-Ofrd" style="color:lightgrey;padding-left:10px;float:right;"></span>
  546. </div>
  547. </div>
  548. </div>
  549.  
  550. <div class="ls-Lock-Options">
  551. <select class="ls-Select" id="lsLockNonpedSelect">
  552. <option class="ls-Lock-Option-0">${TRANSLATIONS.default.option0}</option><option class="ls-Lock-Option-1">1</option>
  553. <option class="ls-Lock-Option-2">2</option><option class="ls-Lock-Option-3">3</option>
  554. <option class="ls-Lock-Option-4">4</option><option class="ls-Lock-Option-5">5</option>
  555. <option class="ls-Lock-Option-6">6</option>
  556. </select>
  557. <span class="ls-Nonped-Label"></span>
  558. <div class="ls-Seg-Result">
  559. <div id="ls-Seg-Result-Nonped" style="float:right;">
  560. <div class="ls-IL-Block">
  561. <span class="fa fa-arrow-circle-up" id="ls-Nonped-Lock-Up"></span>
  562. <span class="ls-Seg-Quantity-Low" id="ls-Nonped-Low-Quan"></span>
  563. </div>
  564. <div class="ls-IL-Block">
  565. <span class="fa fa-arrow-circle-down" id="ls-Nonped-Lock-Down"></span>
  566. <span class="ls-Seg-Quantity-High" id="ls-Nonped-High-Quan"></span>
  567. </div>
  568. <span class="fa fa-lock" id="icon-Lock-Nonped" style="color:lightgrey;padding-left:10px;float:right;"></span>
  569. </div>
  570. </div>
  571. </div>
  572.  
  573. </div>
  574. </div>
  575. </div>
  576. <div class="ls-Section-Container" style="margin-top:5px;border-top:.5px solid lightgrey;">
  577. <div class="ls-Section-Container" style="margin-top:3px;">
  578. <span id='ls-currentStandards-label'></span>:&nbsp;&nbsp;<span id="ls-Current-State-Display" style="font-weight:bold;"></span>
  579. <div id="ls-State-Select-Container" style="display:none;">
  580. <select class="ls-Select" id="ls-State-Selection"></select>
  581. </div>
  582. </div>
  583. </div>
  584. <div class="ls-Section-Container">
  585. <div class="ls-Section-Header" style="float:left;margin-top:5px;" id="ls-Add-Att-Info" data-original-title='${TRANSLATIONS.default.attrTooltip}'><span id='ls-text-addAttr'></span></div>
  586. <div class="ls-Locking-Attributes">
  587. <label class="ls-Attr-Label">
  588. <input type="checkbox" class="ls-Att-Ck-Form" id="ls-Unpaved-Enable"><span class="ls-Attr-CheckBox" id="ls-Unpaved-Status"></span>
  589. </label>
  590. <label class="ls-Attr-Label">
  591. <input type="checkbox" class="ls-Att-Ck-Form" id="ls-OneWay-Enable"><span class="ls-Attr-CheckBox" id="ls-OneWay-Status"></span>
  592. </label>
  593. <label class="ls-Attr-Label">
  594. <input type="checkbox" class="ls-Att-Ck-Form" id="ls-HOV-Enable"><span class="ls-Attr-CheckBox" id="ls-HOV-Status"></span>
  595. </label>
  596. <label class="ls-Attr-Label">
  597. <input type="checkbox" class="ls-Att-Ck-Form" id="ls-Toll-Enable"><span class="ls-Attr-CheckBox" id="ls-Toll-Status"></span>
  598. </label>
  599. <label class="ls-Attr-Label">
  600. <input type="checkbox" class="ls-Att-Ck-Form" id="ls-WKT-Enable"><span class="ls-Attr-CheckBox" id="ls-WKT-Status"></span>
  601. </label>
  602. </div>
  603. </div>`,
  604. '</div>',
  605. '</div>'
  606. ].join(' '));
  607. // Attach HTML for tab to webpage
  608. UpdateObj = require('Waze/Action/UpdateObject');
  609. cakeFlavor = editorInfo.attributes.rank;
  610. roadClear = cakeFlavor >= FEATURELOCK;
  611.  
  612. // Script is initialized and the highlighting layer is created
  613. WazeWrap.Interface.Tab('LS', $section.html(), initializeSettings, 'LS');
  614.  
  615. WazeWrap.Interface.ShowScriptUpdate(GM_info.script.name, GM_info.script.version, LS_UPDATE_NOTES, 'https://gf.qytechs.cn/en/scripts/386773-wme-locksmith', 'https://www.waze.com/forum/viewtopic.php?f=819&t=285583');
  616.  
  617. LocksmithHighlightLayer = new OpenLayers.Layer.Vector('LocksmithHighlightLayer', { uniqueName: '_LocksmithHighlightLayer' });
  618. W.map.addLayer(LocksmithHighlightLayer);
  619. LocksmithHighlightLayer.setVisibility(true);
  620.  
  621. console.log('LS: loaded');
  622. }
  623.  
  624. async function initializeSettings() {
  625. loadSpreadsheet();
  626. await loadSettings();
  627. setUserOptions();
  628.  
  629. $(`<style type="text/css">${css}</style>`).appendTo('head');
  630.  
  631. // Allows WME native tooltip UI
  632. $('#ls-Add-Att-Info').tooltip();
  633. $('#lsConnectionStatus').tooltip();
  634. $('#ls-Above-Rank-Tooltip').tooltip({ placement: 'auto right' });
  635. $('#ls-Higher-Level-Tooltip').tooltip({ placement: 'auto bottom' });
  636. $('#ls-Reset-Standards-Display').tooltip({ placement: 'auto bottom' });
  637.  
  638. // Create listeners to run functions when buttons are clicked
  639. if (roadClear) {
  640. $('#ls-Lock-All-Submit').click(() => { relockAll(); });
  641. } else {
  642. $('#ls-Lock-All-Submit').hover();
  643. $('#ls-Lock-All-Submit').attr('value', 'Disabled');
  644. $('#ls-Lock-All-Submit').attr('disabled', true);
  645. $('#ls-Lock-All-Submit').css('background-color', '#ccc');
  646. }
  647. $('#ls-Maual-Scan-Activate').click(() => { scanArea(true); });
  648. $('#ls-Reset-Standards-Display').click(() => {
  649. $('#lsEnableSaveValues').prop('checked', false);
  650. LsSettings.EnableSaveValues = false;
  651. saveSettings();
  652. generateStateList();
  653. getCurrentState();
  654. setCurrentStandards(_currentState);
  655. resetUISegStats();
  656. });
  657. $('#ls-Othr-Seg-Label').click(() => {
  658. $('#ls-Seg-Types-Main').toggle();
  659. $('#ls-Seg-Types-Alt').toggle();
  660. $('#rl-Othr-Result-Container').toggle();
  661. });
  662.  
  663. $('#ls-State-Selection').change(function () {
  664. _currentState = this.value;
  665. setCurrentStandards(_currentState);
  666. });
  667. $('#lsEnableHighlightSeg').change(function () { if (!this.checked) { removeHighlights(); } });
  668. $("input[type='checkbox'].ls-Att-Ck-Form").change(function () {
  669. const elementName = $(this).attr('id');
  670.  
  671. switch (elementName) {
  672. case 'ls-Unpaved-Enable':
  673. if (this.checked) $('#ls-Unpaved-Status').css({ 'background-color': 'rgb(205,133,63)', 'background-image': '' });
  674. else $('#ls-Unpaved-Status').css({ 'background-color': '', 'background-image': 'repeating-linear-gradient(135deg,lightgrey,rgb(205,133,63) 20%,lightgrey 10%)' });
  675. break;
  676. case 'ls-OneWay-Enable':
  677. if (this.checked) $('#ls-OneWay-Status').css({ 'background-color': 'rgb(236, 249, 31)', 'background-image': '' });
  678. else $('#ls-OneWay-Status').css({ 'background-color': '', 'background-image': 'repeating-linear-gradient(135deg,rgb(239,251,81),rgb(209,224,6) 6px,black 8px)' });
  679. break;
  680. case 'ls-HOV-Enable':
  681. if (this.checked) $('#ls-HOV-Status').css({ 'background-color': 'rgb(254,151,13)', 'background-image': '' });
  682. else $('#ls-HOV-Status').css({ 'background-color': '', 'background-image': 'repeating-linear-gradient(135deg,rgb(254,151,13),rgb(247,199,134) 6px,black 8px)' });
  683. break;
  684. case 'ls-Toll-Enable':
  685. if (this.checked) $('#ls-Toll-Status').css({ 'background-color': 'rgb(253,14,202)', 'background-image': '' });
  686. else $('#ls-Toll-Status').css({ 'background-color': '', 'background-image': 'repeating-linear-gradient(135deg,rgb(253,14,202),rgb(252,156,231) 6px,black 8px)' });
  687. break;
  688. case 'ls-WKT-Enable':
  689. if (this.checked) $('#ls-WKT-Status').css({ 'background-color': 'rgb(9,235,255)', 'background-image': '' });
  690. else $('#ls-WKT-Status').css({ 'background-color': '', 'background-image': 'repeating-linear-gradient(135deg,rgb(9,235,255),rgb(161,247,255) 6px,black 8px)' });
  691. break;
  692. default:
  693. console.log('LS: Seg Att switch error');
  694. }
  695. });
  696. $('#lsManualStateOverride').change(function () {
  697. if (this.checked) {
  698. generateStateList();
  699. $('#ls-State-Select-Container').css('display', 'inline-block');
  700. $('#ls-Current-State-Display').css('display', 'none');
  701. setCurrentStandards(_currentState);
  702. } else {
  703. $('#ls-State-Select-Container').css('display', 'none');
  704. $('#ls-Current-State-Display').css('display', 'inline-block');
  705. _currentState = 'changeME';
  706. getCurrentState();
  707. }
  708. });
  709. $('#lsEnableActiveScan').change(function () {
  710. if (!this.checked) {
  711. resetUISegStats();
  712. removeHighlights();
  713. }
  714. });
  715.  
  716. // Trigger checkbox save status
  717. $('.ls-Save-Status').change(function () {
  718. let settingName = $(this)[0].id.substr(2);
  719. LsSettings[settingName] = this.checked;
  720. saveSettings();
  721. });
  722. // Trigger save upon select change
  723. $('.ls-Select').change(function () {
  724. let settingName = $(this)[0].id.substr(2);
  725. LsSettings[settingName] = this.value;
  726. saveSettings();
  727. });
  728.  
  729. // Register WME event listeners
  730. W.map.events.register('moveend', null, tryScan);
  731. W.map.events.register('movestart', null, resetUISegStats);
  732. W.model.actionManager.events.register('afteraction', null, tryScan);
  733. W.model.actionManager.events.register('afterundoaction', null, tryScan);
  734. W.model.actionManager.events.register('afterclearactions', null, tryScan);
  735. W.model.actionManager.events.register('afterclearactions', null, resetUISegStats);
  736. W.accelerators.events.register('editHouseNumbers', null, tryScan);
  737.  
  738. function setUserOptions() {
  739. // Checks editors rank and hides lock options above them
  740. verifyOptionEnable('.ls-Lock-Option-3', 2);
  741. verifyOptionEnable('.ls-Lock-Option-4', 3);
  742. verifyOptionEnable('.ls-Lock-Option-5', 4);
  743. verifyOptionEnable('.ls-Lock-Option-6', 5);
  744. // Set check boxes based on last use
  745. setChecked('lsEnableActiveScan', LsSettings.EnableActiveScan);
  746. setChecked('lsEnableHighlightSeg', LsSettings.EnableHighlightSeg);
  747. setChecked('lsEnableResetHigher', LsSettings.EnableResetHigher);
  748. setChecked('lsEnableSaveSettings', LsSettings.EnableSaveSettings);
  749. setChecked('lsDisableStatePopup', LsSettings.DisableStatePopup);
  750. setChecked('lsEnableIgnoreRank', LsSettings.EnableIgnoreRank);
  751. setChecked('lsEnableSaveValues', LsSettings.EnableSaveValues);
  752.  
  753. // Enable rank select drop downs appropriate for editors rank
  754. function verifyOptionEnable(className, rankRequired) {
  755. if (cakeFlavor < rankRequired) $(className).hide();
  756. }
  757.  
  758. function setChecked(checkboxId, checked) {
  759. $(`#${checkboxId}`).prop('checked', checked);
  760. }
  761. }
  762. }
  763.  
  764. async function saveSettings() {
  765. const localsettings = {
  766. lastSaveAction: Date.now(),
  767. EnableActiveScan: LsSettings.EnableActiveScan,
  768. EnableHighlightSeg: LsSettings.EnableHighlightSeg,
  769. EnableResetHigher: LsSettings.EnableResetHigher,
  770. DisableStatePopup: LsSettings.DisableStatePopup,
  771. EnableIgnoreRank: LsSettings.EnableIgnoreRank,
  772. EnableSaveSettings: LsSettings.EnableSaveSettings,
  773. EnableSaveValues: LsSettings.EnableSaveValues,
  774. LockStreetSelect: LsSettings.LockStreetSelect,
  775. LockPSSelect: LsSettings.LockPSSelect,
  776. LockMinHSelect: LsSettings.LockMinHSelect,
  777. LockMajHSelect: LsSettings.LockMajHSelect,
  778. LockRmpSelect: LsSettings.LockRmpSelect,
  779. LockFwySelect: LsSettings.LockFwySelect,
  780. LockPvtSelect: LsSettings.LockPvtSelect,
  781. LockPlrSelect: LsSettings.LockPlrSelect,
  782. LockRailSelect: LsSettings.LockRailSelect,
  783. LockFrySelect: LsSettings.LockFrySelect,
  784. LockRnwySelect: LsSettings.LockRnwySelect,
  785. LockOfrdSelect: LsSettings.LockOfrdSelect,
  786. LockNonpedSelect: LsSettings.LockNonpedSelect
  787.  
  788. };
  789.  
  790. if (localStorage) { localStorage.setItem('LsUS_Settings', JSON.stringify(localsettings)); }
  791. // Attempt to connect to the WazeWrap setting store server
  792. const serverSave = await WazeWrap.Remote.SaveSettings('LsUS_Settings', localsettings);
  793.  
  794. if (serverSave === null) console.log('LS: User PIN not set in WazeWrap tab');
  795. else if (serverSave === false) console.log('LS: Unable to save settings to server');
  796. }
  797.  
  798. async function loadSettings() {
  799. const localSettings = $.parseJSON(localStorage.getItem('LsUS_Settings'));
  800. // Attempt connection to WazeWrap setting server to retrieve settings
  801. const serverSettings = await WazeWrap.Remote.RetrieveSettings('LsUS_Settings');
  802. if (!serverSettings) console.log('LS: Error communicating with WW settings server');
  803. // Default checkbox settings
  804. const defaultsettings = {
  805. lastSaveAction: null,
  806. EnableActiveScan: false,
  807. EnableHighlightSeg: false,
  808. EnableResetHigher: false,
  809. DisableStatePopup: false,
  810. EnableIgnoreRank: false,
  811. EnableSaveSettings: false,
  812. EnableSaveValues: false,
  813. LockStreetSelect: 'Auto',
  814. LockPSSelect: 'Auto',
  815. LockMinHSelect: 'Auto',
  816. LockMajHSelect: 'Auto',
  817. LockRmpSelect: 'Auto',
  818. LockFwySelect: 'Auto',
  819. LockPvtSelect: 'Auto',
  820. LockPlrSelect: 'Auto',
  821. LockRailSelect: 'Auto',
  822. LockFrySelect: 'Auto',
  823. LockRnwySelect: 'Auto',
  824. LockOfrdSelect: 'Auto',
  825. LockNonpedSelect: 'Auto'
  826. };
  827.  
  828. LsSettings = $.extend({}, defaultsettings, localSettings);
  829. if (serverSettings && serverSettings.lastSaveAction > LsSettings.lastSaveAction) {
  830. $.extend(LsSettings, serverSettings);
  831. console.log('LS: server settings used');
  832. }
  833. if (LsSettings.EnableSaveSettings === false) LsSettings = defaultsettings;
  834. // Sets saved values for segment locks when desired
  835. if (LsSettings.EnableSaveValues === true) {
  836. $('#lsLockStreetSelect').val(LsSettings.LockStreetSelect);
  837. $('#lsLockPSSelect').val(LsSettings.LockPSSelect);
  838. $('#lsLockMinHSelect').val(LsSettings.LockMinHSelect);
  839. $('#lsLockMajHSelect').val(LsSettings.LockMajHSelect);
  840. $('#lsLockRmpSelect').val(LsSettings.LockRmpSelect);
  841. $('#lsLockFwySelect').val(LsSettings.LockFwySelect);
  842. $('#lsLockPvtSelect').val(LsSettings.LockPvtSelect);
  843. $('#lsLockPlrSelect').val(LsSettings.LockPlrSelect);
  844. $('#lsLockRailSelect').val(LsSettings.LockRailSelect);
  845. $('#lsLockFrySelect').val(LsSettings.LockFrySelect);
  846. $('#lsLockRnwySelect').val(LsSettings.LockRnwySelect);
  847. $('#lsLockOfrdSelect').val(LsSettings.LockOfrdSelect);
  848. $('#lsLockNonpedSelect').val(LsSettings.LockNonpedSelect);
  849. }
  850. }
  851.  
  852. function changeUI(eleID, status, type, inText) {
  853. if (type === 'lock' && status === 1) {
  854. $(eleID).attr('disabled', false);
  855. if (inText === 'high') $(eleID).css({ color: 'cyan', cursor: 'pointer' });
  856. if (inText === 'low') $(eleID).css({ color: 'red', cursor: 'pointer' });
  857. if (inText === 'both') $(eleID).css({ color: 'orange', cursor: 'pointer' });
  858. }
  859. if (type === 'text' && status === 1) {
  860. $(eleID).text(inText);
  861. }
  862. if (type === 'lock' && status === 0) {
  863. $(eleID).css({ color: 'lightgrey', cursor: 'default' });
  864. $(eleID).attr('disabled', true);
  865. $(eleID).off('click');
  866. }
  867. }
  868.  
  869. function resetUISegStats() {
  870. changeUI('.fa.fa-arrow-circle-up', 0, 'lock', null);
  871. changeUI('.fa.fa-arrow-circle-down', 0, 'lock', null);
  872. changeUI('.ls-Seg-Quantity-Low', 1, 'text', '--');
  873. changeUI('.ls-Seg-Quantity-High', 1, 'text', '--');
  874. changeUI('#icon-Lock-LS', 0, 'lock', null);
  875. changeUI('#icon-Lock-PS', 0, 'lock', null);
  876. changeUI('#icon-Lock-minH', 0, 'lock', null);
  877. changeUI('#icon-Lock-majH', 0, 'lock', null);
  878. changeUI('#icon-Lock-Rmp', 0, 'lock', null);
  879. changeUI('#icon-Lock-Fwy', 0, 'lock', null);
  880. changeUI('#icon-Lock-othr', 0, 'lock', null);
  881. changeUI('#icon-Lock-Pvt', 0, 'lock', null);
  882. changeUI('#icon-Lock-Plr', 0, 'lock', null);
  883. changeUI('#icon-Lock-Rail', 0, 'lock', null);
  884. changeUI('#icon-Lock-Rnwy', 0, 'lock', null);
  885. changeUI('#icon-Lock-Fry', 0, 'lock', null);
  886. changeUI('#icon-Lock-Ofrd', 0, 'lock', null);
  887. changeUI('#icon-Lock-Nonped', 0, 'lock', null);
  888. removeHighlights();
  889. $("a[href$='#sidepanel-lsus']").css('background-color', '#e9e9e9');
  890. }
  891.  
  892. function WKT_to_LinearRing(wkt) {
  893. const lines = wkt.split(',');
  894. const ringPts = [];
  895.  
  896. for (let i = 0; i < lines.length; i++) {
  897. const coords = lines[i].trim().match(/(-?\d*(?:\.\d*)?)\s(-?\d*(?:\.\d*))/);
  898. const pt = WazeWrap.Geometry.ConvertTo900913(coords[1], coords[2]);
  899. ringPts.push(new OpenLayers.Geometry.Point(pt.lon, pt.lat));
  900. }
  901. return new OpenLayers.Geometry.LinearRing(ringPts);
  902. }
  903.  
  904. async function loadSpreadsheet() {
  905. let connectionEstablished = false;
  906. const sheetCode = '1z9WQW_6xdXDn9nz_087DoZby2XxcDSxxRbby_y1tKho';
  907. const apiKey = 'AIzaSyB8ilOS8JuGaPSLtX3XJRDDpJtyII7aE7g';
  908. const standardsFailFunc = (jqXHR, textStatus, errorThrown) => {
  909. console.error('LS: Error loading settings:', errorThrown);
  910. };
  911. const translationsFailFunc = (jqXHR, textStatus, errorThrown) => {
  912. console.error('LS: Error loading trans:', errorThrown);
  913. };
  914.  
  915. try {
  916. await $.getJSON(
  917. `https://sheets.googleapis.com/v4/spreadsheets/${sheetCode}/values/Translations!A2:C?key=${apiKey}`
  918. )
  919. .done(async (transArray) => {
  920. if (transArray.values.length > 0) {
  921. _.each(transArray.values, t => {
  922. if (!TRANSLATIONS[t[1]] && Number.parseInt(t[2], 10) === 1) {
  923. TRANSLATIONS[t[1]] = JSON.parse(t[0]);
  924. }
  925. });
  926. } else {
  927. translationsFailFunc();
  928. }
  929. })
  930. .fail(translationsFailFunc);
  931. } catch (e) {
  932. translationsFailFunc(null, null, e);
  933. }
  934.  
  935. try {
  936. await $.getJSON(
  937. `https://sheets.googleapis.com/v4/spreadsheets/${sheetCode}/values/Standards!A2:D?key=${apiKey}`
  938. )
  939. .done((serverSettings) => {
  940. if (serverSettings.values.length > 0) {
  941. _.each(serverSettings.values, v => {
  942. if (!_allStandardsArray[v[1]]) _allStandardsArray[v[1]] = {};
  943. if (!_allStandardsArray[v[1]].States) _allStandardsArray[v[1]].States = {};
  944. if (!_allStandardsArray[v[1]].States[v[2]]) {
  945. const stateName = v[2] === undefined ? 'default' : v[2];
  946. _allStandardsArray[v[1]].States[stateName] = JSON.parse(v[0]);
  947. }
  948. else {
  949. if (!_allStandardsArray[v[1]].States[v[2]].Areas) _allStandardsArray[v[1]].States[v[2]].Areas = {};
  950. _allStandardsArray[v[1]].States[v[2]].Areas[v[3]] = JSON.parse(v[0]);
  951. if (v[3].startsWith('POLYGON')) _allStandardsArray[v[1]].States[v[2]].Areas[v[3]].Polygon = new OpenLayers.Geometry.Polygon(WKT_to_LinearRing(v[3]));
  952. }
  953. });
  954. connectionEstablished = true;
  955. } else {
  956. standardsFailFunc();
  957. }
  958. })
  959. .fail(standardsFailFunc);
  960. } catch (e) {
  961. standardsFailFunc(null, null, e);
  962. }
  963.  
  964. if (connectionEstablished) {
  965. $('#lsConnectionStatus').text('Good');
  966. $('#lsConnectionStatus').css('backgroundColor', 'lime');
  967. } else {
  968. $('#lsConnectionStatus').text('Error');
  969. $('#lsConnectionStatus').css('backgroundColor', 'red');
  970. }
  971.  
  972. // console.log(_allStandardsArray);
  973. // Process state standards for later use
  974. _.each(_allStandardsArray, stateKey => {
  975. for (const k in stateKey) {
  976. if (stateKey.hasOwnProperty(k)) {
  977. // Check if strings are numbers and convert to numbers if so
  978. let keyValue = stateKey[k];
  979. // convert "" values to null
  980. if (keyValue == '') keyValue = null;
  981. // If lock is 1 then change to Auto to prevent excessive 1 locks
  982. let tempKey = parseInt(keyValue);
  983. if (!isNaN(tempKey)) {
  984. if (keyValue == 1) tempKey = 'Auto';
  985. keyValue = tempKey;
  986. }
  987. stateKey[k] = keyValue;
  988. }
  989. }
  990.  
  991. if (stateKey.Areas) {
  992. _.each(stateKey.Areas, polyArea => {
  993. for (const k in polyArea) {
  994. if (polyArea.hasOwnProperty(k)) {
  995. // Check if strings are numbers and convert to numbers if so
  996. let keyValue = polyArea[k];
  997. // convert "" values to null
  998. if (keyValue == '') keyValue = null;
  999. // If lock is 1 then change to Auto to prevent excessive 1 locks
  1000. let tempKey = parseInt(keyValue);
  1001. if (!isNaN(tempKey)) {
  1002. if (keyValue == 1) tempKey = 'Auto';
  1003. keyValue = tempKey;
  1004. }
  1005. polyArea[k] = keyValue;
  1006. }
  1007. }
  1008. });
  1009. }
  1010. });
  1011.  
  1012. getCurrentState();
  1013. setUIText();
  1014. }
  1015.  
  1016. function setUIText() {
  1017. let strings = {};
  1018. langLocality = I18n.currentLocale().toLowerCase();
  1019. if (TRANSLATIONS[langLocality]) {
  1020. strings = TRANSLATIONS[langLocality];
  1021. } else if (langLocality.includes('-') && TRANSLATIONS[langLocality.split('-')[0]]) {
  1022. strings = TRANSLATIONS[langLocality.split('-')[0]];
  1023. } else {
  1024. strings = TRANSLATIONS.default;
  1025. }
  1026.  
  1027. Object.keys(TRANSLATIONS.default).forEach((transString) => {
  1028. if (!strings.hasOwnProperty(transString) || strings[transString] == "") {
  1029. strings[transString] = TRANSLATIONS.default[transString];
  1030. }
  1031. });
  1032.  
  1033. $('#ls-text-options').text(strings.optionsMenu);
  1034. $('#ls-text-activeScan').text(strings.activeScan);
  1035. $('#ls-text-enHighlights').text(strings.enHighlights);
  1036. $('#ls-text-detAbvRank').text(strings.detAbvRank);
  1037. $('#ls-text-saveCustLock').text(strings.saveCustLock);
  1038. $('#ls-text-saveScnSet').text(strings.saveScnSet);
  1039. $('#ls-text-manStateSel').text(strings.manStateSel);
  1040. $('#ls-text-disStatePop').text(strings.disStatePop);
  1041. $('#ls-text-ovrLockSegs').text(strings.ovrLockSegs);
  1042. $('#ls-text-othrSegTypes').text(strings.othrSegTypes);
  1043. $('#ls-text-addAttr').text(strings.addAttr);
  1044. $('#ls-text-lockStand').text(strings.lockStand);
  1045. $('#ls-text-lockStat').text(strings.lockStat);
  1046. $('.ls-option0').text(strings.option0);
  1047. $('.ls-optionHRCS').text(strings.optionHRCS);
  1048. $('.ls-option1').text(strings.option1);
  1049. $('.ls-option2').text(strings.option2);
  1050. $('.ls-option3').text(strings.option3);
  1051. $('.ls-option4').text(strings.option4);
  1052. $('.ls-option5').text(strings.option5);
  1053. $('.ls-option6').text(strings.option6);
  1054. $('.ls-FWY-Label').text(strings.roadFwy);
  1055. $('.ls-Ramp-Label').text(strings.roadRmp);
  1056. $('.ls-majH-Label').text(strings.roadMajH);
  1057. $('.ls-minH-Label').text(strings.roadMinH);
  1058. $('.ls-PS-Label').text(strings.roadPS);
  1059. $('.ls-LS-Label').text(strings.roadLS);
  1060. $('.ls-Pvt-Label').text(strings.roadPVT);
  1061. $('.ls-Plr-Label').text(strings.roadPLR);
  1062. $('.ls-Rail-Label').text(strings.roadRail);
  1063. $('.ls-Fry-Label').text(strings.roadFry);
  1064. $('.ls-Ofrd-Label').text(strings.roadOff);
  1065. $('.ls-Rnwy-Label').text(strings.roadRun);
  1066. $('.ls-Nonped-Label').text(strings.roadNonPed);
  1067. $('#ls-Unpaved-Status').text(strings.unpaved);
  1068. $('#ls-OneWay-Status').text(strings.oneWay);
  1069. $('#ls-HOV-Status').text(strings.hov);
  1070. $('#ls-WKT-Status').text(strings.wkt);
  1071. $('#ls-Toll-Status').text(strings.toll);
  1072. $('#ls-currentStandards-label').text(strings.currentStandards);
  1073. $('.ls-Seg-Quantity-Low').text('--');
  1074. $('.ls-Seg-Quantity-High').text('--');
  1075. $('.fa.fa-arrow-circle-up').css({ color: 'lightgrey', cursor: 'default' });
  1076. $('.fa.fa-arrow-circle-down').css({ color: 'lightgrey', cursor: 'default' });
  1077. $('.fa.fa-arrow-circle-up').attr('disabled', true);
  1078. $('.fa.fa-arrow-circle-down').attr('disabled', true);
  1079.  
  1080. $('#ls-Above-Rank-Tooltip').attr('data-original-title', strings.rankTooltip);
  1081. $('#ls-Higher-Level-Tooltip').attr('data-original-title', strings.highLockTooltip);
  1082. $('#ls-Reset-Standards-Display').attr('value', strings.resetValue);
  1083. $('#ls-Reset-Standards-Display').attr('data-original-title', strings.resetTooltip);
  1084. $('#ls-Maual-Scan-Activate').attr('data-original-title', strings.scanValue);
  1085. $('#ls-ls-Lock-All-Submit').attr('data-original-title', strings.lockAllValue);
  1086. $('#ls-Add-Att-Info').attr('data-original-title', strings.attrTooltip);
  1087. }
  1088.  
  1089. function getstatesAvailable() {
  1090. const allstates = W.model.states.getObjectArray();
  1091. const filtered = []
  1092.  
  1093. if (allstates) {
  1094. if (allstates.length > 1) {
  1095. for( var i = 0; i < allstates.length; i++){
  1096. if (!allstates[i].isInBbox) continue;
  1097. try {
  1098. var test = _allStandardsArray[W.model.countries.getObjectById(allstates[i].attributes.countryID).attributes.name].States[allstates[i].attributes.name];
  1099. filtered.push(allstates[i])
  1100. }
  1101. catch {
  1102. // console.log('skipping: ' + allstates[i].name);
  1103. }
  1104. }
  1105. } else {
  1106. filtered.push(allstates[0])
  1107. }
  1108. }
  1109. return filtered;
  1110. }
  1111.  
  1112. function getCurrentState() {
  1113. const overrideEnable = getId('lsManualStateOverride').checked;
  1114. const disablePopup = getId('lsDisableStatePopup').checked;
  1115. let statusOk = false;
  1116. let attempts = 0;
  1117.  
  1118. function stateModelStatus() {
  1119. const statesAvailable = getstatesAvailable();
  1120.  
  1121. if (statesAvailable) {
  1122. // Verify the number of states currently available and either prompt for manual selection or set standards based on that state
  1123. if (statesAvailable.length > 1) {
  1124. if (!overrideEnable) {
  1125. if (!disablePopup) WazeWrap.Alerts.info(GM_info.script.name, 'Multiple States available, please manually set the correct state or zoom in/out to reset the States layer');
  1126. $('#ls-Current-State-Display').text('Multiple');
  1127. } else statusOk = true;
  1128. } else if (statesAvailable.length === 1 && !overrideEnable) {
  1129. const stateName = statesAvailable[0].attributes.name === '' ? 'default' : statesAvailable[0].attributes.name;
  1130. if (_currentState !== stateName) {
  1131. _currentState = stateName;
  1132. const displayText = _currentState === 'default' ? W.model.getTopCountry().attributes.name : _currentState;
  1133. $('#ls-Current-State-Display').text(displayText);
  1134. setCurrentStandards(_currentState);
  1135. statusOk = true;
  1136. } else statusOk = true;
  1137. } else if (attempts < 20) setTimeout(() => { stateModelStatus(attempts++); }, 300);
  1138. } else if (attempts < 20) setTimeout(() => { stateModelStatus(attempts++); }, 300);
  1139. else WazeWrap.Alerts.warning(GM_info.script.name, 'Error loading state array');
  1140. }
  1141. stateModelStatus();
  1142. return statusOk;
  1143. }
  1144.  
  1145. function checkCountry() {
  1146. try {
  1147. country = W.model.getTopCountry().attributes.name;
  1148. } catch (err) {
  1149. country = null;
  1150. // console.log(err);
  1151. }
  1152. }
  1153.  
  1154. function generateStateList() {
  1155. const stateSelector = getId('ls-State-Selection');
  1156. const currOptionsLength = stateSelector.childNodes.length;
  1157. const statesAvailable = getstatesAvailable();
  1158.  
  1159. // Removes any options currently attached to the select
  1160. if (currOptionsLength > 0) {
  1161. for (let i = 0; i < currOptionsLength; i++) {
  1162. stateSelector.removeChild(stateSelector.firstChild);
  1163. }
  1164. }
  1165.  
  1166. // Adds available states to the user select
  1167. for (let i = 0; i < statesAvailable.length; i++) {
  1168. const currStateName = statesAvailable[i].attributes.name;
  1169. const newStateOption = document.createElement('option');
  1170. const stateNameText = document.createTextNode(currStateName);
  1171. if (i === 0) {
  1172. newStateOption.setAttribute('selected', true);
  1173. _currentState = currStateName;
  1174. }
  1175. newStateOption.appendChild(stateNameText);
  1176. stateSelector.appendChild(newStateOption);
  1177. }
  1178. }
  1179.  
  1180. function setCurrentStandards(stateName) {
  1181. let attempts = 0;
  1182. let proceed = false;
  1183. let countryName;
  1184. // Sets the locking standards based on the state and updates relevent UI components
  1185. function applyStandards() {
  1186. if (W.model.states.getObjectArray().length > 0) {
  1187. _.each(W.model.states.getObjectArray(), s => {
  1188. const modelName = s.attributes.name === '' ? 'default' : s.attributes.name;
  1189. if (modelName === stateName) {
  1190. countryName = s.attributes.countryID === 0 ? W.model.getTopCountry().attributes.name : W.model.countries.getObjectById(s.attributes.countryID).attributes.name;
  1191. if (countryName !== null) {
  1192. proceed = true;
  1193. _currentStateStandards = _allStandardsArray[countryName].States[stateName];
  1194. // console.log(_currentStateStandards);
  1195. }
  1196. }
  1197. });
  1198. }
  1199.  
  1200. if (_currentStateStandards && _currentStateStandards.LS && proceed) {
  1201. if (!getId('lsEnableSaveValues').checked) {
  1202. $('#lsLockStreetSelect').val(_currentStateStandards.LS);
  1203. $('#lsLockPSSelect').val(_currentStateStandards.PS);
  1204. $('#lsLockMinHSelect').val(_currentStateStandards.mH);
  1205. $('#lsLockMajHSelect').val(_currentStateStandards.MH);
  1206. $('#lsLockRmpSelect').val(_currentStateStandards.Ramp);
  1207. $('#lsLockFwySelect').val(_currentStateStandards.Fwy);
  1208. $('#lsLockPvtSelect').val(_currentStateStandards.Private);
  1209. $('#lsLockPlrSelect').val(_currentStateStandards.PLR);
  1210. $('#lsLockRailSelect').val(_currentStateStandards.Railroad);
  1211. $('#lsLockFrySelect').val(_currentStateStandards.Ferry);
  1212. $('#lsLockRnwySelect').val(_currentStateStandards.Runway);
  1213. $('#lsLockOfrdSelect').val(_currentStateStandards.Offroad);
  1214. $('#lsLockNonpedSelect').val(_currentStateStandards.NonRoutablePedestrian);
  1215. }
  1216.  
  1217. // Setup seg attribute based locks on UI
  1218. if (_currentStateStandards.Unpaved) {
  1219. $('#ls-Unpaved-Enable').attr('disabled', false);
  1220. $('#ls-Unpaved-Enable').prop('checked', true);
  1221. $('#ls-Unpaved-Status').css({ 'background-color': 'rgb(205,133,63)', 'background-image': '' });
  1222. } else {
  1223. $('#ls-Unpaved-Enable').attr('disabled', true);
  1224. $('#ls-Unpaved-Status').css({ 'background-image': 'repeating-linear-gradient(135deg,lightgrey,grey 10px,black 4px)', 'background-color': '' });
  1225. }
  1226. if (_currentStateStandards.LS1Way || _currentStateStandards.PS1Way || _currentStateStandards.mH1Way
  1227. || _currentStateStandards.MH1Way || _currentStateStandards.Private1Way) {
  1228. $('#ls-OneWay-Enable').attr('disabled', false);
  1229. $('#ls-OneWay-Enable').prop('checked', true);
  1230. $('#ls-OneWay-Status').css({ 'background-color': 'rgb(236,249,31)', 'background-image': '' });
  1231. } else {
  1232. $('#ls-OneWay-Enable').attr('disabled', true);
  1233. $('#ls-OneWay-Status').css({ 'background-image': 'repeating-linear-gradient(135deg,lightgrey,grey 10px,black 4px)', 'background-color': '' });
  1234. }
  1235. if (_currentStateStandards.HOV) {
  1236. $('#ls-HOV-Enable').attr('disabled', false);
  1237. $('#ls-HOV-Enable').prop('checked', true);
  1238. $('#ls-HOV-Status').css({ 'background-color': 'rgb(254,151,13)', 'background-image': '' });
  1239. } else {
  1240. $('#ls-HOV-Enable').attr('disabled', true);
  1241. $('#ls-HOV-Status').css({ 'background-image': 'repeating-linear-gradient(135deg,lightgrey,grey 10px,black 4px)', 'background-color': '' });
  1242. }
  1243. if (_currentStateStandards.Toll) {
  1244. $('#ls-Toll-Enable').attr('disabled', false);
  1245. $('#ls-Toll-Enable').prop('checked', true);
  1246. $('#ls-Toll-Status').css({ 'background-color': 'rgb(253,14,202)', 'background-image': '' });
  1247. } else {
  1248. $('#ls-Toll-Enable').attr('disabled', true);
  1249. $('#ls-Toll-Status').css({ 'background-image': 'repeating-linear-gradient(135deg,lightgrey,grey 10px,black 4px)', 'background-color': '' });
  1250. }
  1251. if (_currentStateStandards.Areas) {
  1252. $('#ls-WKT-Enable').attr('disabled', false);
  1253. $('#ls-WKT-Enable').prop('checked', true);
  1254. $('#ls-WKT-Status').css({ 'background-color': 'rgb(9,235,255)', 'background-image': '' });
  1255. } else {
  1256. $('#ls-WKT-Enable').attr('disabled', true);
  1257. $('#ls-WKT-Status').css({ 'background-image': 'repeating-linear-gradient(135deg,lightgrey,grey 10px,black 4px)', 'background-color': '' });
  1258. }
  1259.  
  1260. const logText = stateName === 'default' ? countryName : stateName;
  1261. console.log(`LS: Lock levels loaded for: ${logText}`);
  1262. } else {
  1263. if (attempts < 3) {
  1264. setTimeout(() => { applyStandards(); }, 200);
  1265. } else {
  1266. // console.log('LS: Error in settings current standards');
  1267. generateStateList();
  1268. getCurrentState();
  1269. setCurrentStandards(_currentState);
  1270. }
  1271. attempts++;
  1272. }
  1273. }
  1274. applyStandards();
  1275. }
  1276.  
  1277. function getId(iD) {
  1278. return document.getElementById(iD);
  1279. }
  1280.  
  1281. function onScreen(obj) {
  1282. if (obj.geometry) {
  1283. return (W.map.getExtent().intersectsBounds(obj.geometry.getBounds()));
  1284. }
  1285. return false;
  1286. }
  1287.  
  1288. function removeHighlights() {
  1289. LocksmithHighlightLayer.removeAllFeatures();
  1290. }
  1291.  
  1292. function processLocks(seg, currLockRnk, stdLockRnk) {
  1293. // Process lock action
  1294. if (stdLockRnk > cakeFlavor) stdLockRnk = cakeFlavor;
  1295. if (((currLockRnk < stdLockRnk) || (currLockRnk == null && stdLockRnk != null) ||
  1296. ((currLockRnk > stdLockRnk) && (currLockRnk <= cakeFlavor))) &&
  1297. seg.isGeometryEditable() && seg.attributes.hasClosures === false) {
  1298. W.model.actionManager.add(new UpdateObj(seg, { lockRank: stdLockRnk }));
  1299. return true;
  1300. }
  1301. return false;
  1302. }
  1303.  
  1304. function getSegmentConditions(seg, conditions) {
  1305. // Determine segment attributes for locking exceptions
  1306. const restrictions = seg.restrictions;
  1307. if ((seg.fwdDirection === false && seg.revDirection === true) || (seg.fwdDirection === true && seg.revDirection === false)) conditions.isOneWay = true;
  1308. if (seg.fwdToll === true || seg.revToll === true) conditions.isTollRoad = true;
  1309. if (restrictions.length > 0) {
  1310. for (let i = 0; i < restrictions.length; i++) {
  1311. if (restrictions[i]._defaultType === 'TOLL') conditions.isTollRoad = true;
  1312. }
  1313. }
  1314. if (seg.flags === 16) conditions.isUnpaved = true;
  1315. return conditions;
  1316. }
  1317.  
  1318. function getHighestLock(segID) {
  1319. const segObj = W.model.segments.getObjectById(segID);
  1320. const segType = segObj.attributes.roadType;
  1321. const checkedSegs = [];
  1322. let forwardLock = null;
  1323. let reverseLock = null;
  1324.  
  1325. function processForNode(forwardID) {
  1326. checkedSegs.push(forwardID);
  1327. const forNode = W.model.segments.getObjectById(forwardID).getToNode();
  1328. const forNodeSegs = [...forNode.attributes.segIDs];
  1329.  
  1330. for (let j = 0; j < forNodeSegs.length; j++) {
  1331. if (forNodeSegs[j] === forwardID) { forNodeSegs.splice(j, 1); }
  1332. }
  1333.  
  1334. for (let i = 0; i < forNodeSegs.length; i++) {
  1335. const conSeg = W.model.segments.getObjectById(forNodeSegs[i]).attributes;
  1336.  
  1337. if (conSeg.roadType !== segType) {
  1338. forwardLock = Math.max(conSeg.lockRank, forwardLock);
  1339. } else {
  1340. for (let k = 0; k < forNodeSegs.length; k++) {
  1341. if (!checkedSegs.some(segNum => segNum === conSeg.id)) {
  1342. const tempRank = processForNode(conSeg.id);
  1343. if (tempRank > forwardLock) forwardLock = tempRank;
  1344. }
  1345. }
  1346. }
  1347. }
  1348. return forwardLock;
  1349. }
  1350.  
  1351. function processRevNode(reverseID) {
  1352. checkedSegs.push(reverseID);
  1353. const revNode = W.model.segments.getObjectById(reverseID).getFromNode();
  1354. const revNodeSegs = [...revNode.attributes.segIDs];
  1355.  
  1356. for (let j = 0; j < revNodeSegs.length; j++) {
  1357. if (revNodeSegs[j] === reverseID) { revNodeSegs.splice(j, 1); }
  1358. }
  1359.  
  1360. for (let i = 0; i < revNodeSegs.length; i++) {
  1361. const conSeg = W.model.segments.getObjectById(revNodeSegs[i]).attributes;
  1362.  
  1363. if (conSeg.roadType !== segType) {
  1364. reverseLock = Math.max(conSeg.lockRank, reverseLock);
  1365. } else {
  1366. for (let k = 0; k < revNodeSegs.length; k++) {
  1367. if (!checkedSegs.some(segNum => segNum === conSeg.id)) {
  1368. const tempRank = processRevNode(conSeg.id);
  1369. if (tempRank > reverseLock) { reverseLock = tempRank; }
  1370. }
  1371. }
  1372. }
  1373. }
  1374. return reverseLock;
  1375. }
  1376.  
  1377. return Math.max(processForNode(segID), processRevNode(segID));
  1378. }
  1379.  
  1380. function processSegment(seg) {
  1381. const segAtt = seg.attributes;
  1382. const segType = segAtt.roadType;
  1383. let lockUpdateLvl = null;
  1384. let enUpdate = false;
  1385. let tempLocks = _currentStateStandards;
  1386. let possiblePolys = [];
  1387.  
  1388. // Gather primary segment locks from UI in case of user override of standards
  1389. tempLocks.LS = getId('lsLockStreetSelect').value;
  1390. tempLocks.PS = getId('lsLockPSSelect').value;
  1391. tempLocks.mH = getId('lsLockMinHSelect').value;
  1392. tempLocks.MH = getId('lsLockMajHSelect').value;
  1393. tempLocks.Ramp = getId('lsLockRmpSelect').value;
  1394. tempLocks.Fwy = getId('lsLockFwySelect').value;
  1395. tempLocks.Private = getId('lsLockPvtSelect').value;
  1396. tempLocks.PLR = getId('lsLockPlrSelect').value;
  1397. tempLocks.Railroad = getId('lsLockRailSelect').value;
  1398. tempLocks.Ferry = getId('lsLockFrySelect').value;
  1399. tempLocks.Offroad = getId('lsLockOfrdSelect').value;
  1400. tempLocks.Runway = getId('lsLockRnwySelect').value;
  1401. tempLocks.NonRoutablePedestrian = getId('lsLockNonpedSelect').value;
  1402. const unpavedChkd = getId('ls-Unpaved-Enable').checked;
  1403. const oneWayChkd = getId('ls-OneWay-Enable').checked;
  1404. const tollChkd = getId('ls-Toll-Enable').checked;
  1405. const wktChkd = getId('ls-WKT-Enable').checked;
  1406. // const hovChkd = getId('ls-HOV-Enable').checked;
  1407.  
  1408. let segStatus = seg.state == null ? 'good' : seg.state;
  1409. if (segStatus.toLowerCase() !== 'insert' && segStatus.toLowerCase() !== 'delete') {
  1410. // Gather/verify info attached to segment
  1411. const priSt = W.model.streets.getObjectById(segAtt.primaryStreetID);
  1412. if (priSt == null) return;
  1413. const cityObj = W.model.cities.getObjectById(priSt.attributes.cityID);
  1414. const cityName = cityObj.attributes.name;
  1415. const segStateName = W.model.states.getObjectById(cityObj.attributes.stateID).attributes.name === '' ? 'default' : W.model.states.getObjectById(cityObj.attributes.stateID).attributes.name;
  1416. // Setup object to verify certain segment attributes
  1417. const conditions = {
  1418. isOneWay: false,
  1419. isTollRoad: false,
  1420. isTunnel: false,
  1421. isUnpaved: false,
  1422. hasHeadlights: false
  1423. };
  1424.  
  1425. // Check if segment is in special city/polygon locking standards
  1426. if (wktChkd) {
  1427. _.each(tempLocks.Areas, (v, k) => {
  1428. if (!k.startsWith('POLYGON')) {
  1429. if (k === cityName) {
  1430. tempLocks = v;
  1431. }
  1432. } else { possiblePolys.push(v); }
  1433. });
  1434. for (let i = 0; i < possiblePolys.length; i++) {
  1435. if (possiblePolys[i].Polygon.intersects(seg.geometry)) {
  1436. tempLocks = possiblePolys[i];
  1437. break;
  1438. }
  1439. }
  1440. }
  1441.  
  1442. const coreLocks = {
  1443. lsLock: tempLocks.LS === 'Auto' ? 0 : tempLocks.LS - 1,
  1444. psLock: tempLocks.PS === 'Auto' ? 0 : tempLocks.PS - 1,
  1445. minHLock: tempLocks.mH === 'Auto' ? 0 : tempLocks.mH - 1,
  1446. majHLock: tempLocks.MH === 'Auto' ? 0 : tempLocks.MH - 1,
  1447. rmpLock: tempLocks.Ramp >= 0 ? tempLocks.Ramp - 1 : tempLocks.Ramp,
  1448. fwyLock: tempLocks.Fwy === 'Auto' ? 0 : tempLocks.Fwy - 1,
  1449. plrLock: tempLocks.PLR === 'Auto' ? 0 : tempLocks.PLR - 1,
  1450. pvtLock: tempLocks.Private === 'Auto' ? 0 : tempLocks.Private - 1,
  1451. nrpedLock: tempLocks.NonRoutablePedestrian === 'Auto' ? 0 : tempLocks.NonRoutablePedestrian - 1,
  1452. fryLock: tempLocks.Ferry === 'Auto' ? 0 : tempLocks.Ferry - 1,
  1453. rrLock: tempLocks.Railroad === 'Auto' ? 0 : tempLocks.Railroad - 1,
  1454. rnwyLock: tempLocks.Runway === 'Auto' ? 0 : tempLocks.Runway - 1,
  1455. offRoadLock: tempLocks.Offroad === 'Auto' ? 0 : tempLocks.Offroad - 1
  1456. };
  1457. const attLocks = {
  1458. pvtOneWay: tempLocks.Private1Way != null ? tempLocks.Private1Way - 1 : coreLocks.pvtLock,
  1459. plrOneWay: tempLocks.PLR1Way != null ? tempLocks.PLR1Way - 1 : coreLocks.plrLock,
  1460. lsOneWay: tempLocks.LS1Way != null ? tempLocks.LS1Way - 1 : coreLocks.lsLock,
  1461. psOneWay: tempLocks.PS1Way != null ? tempLocks.PS1Way - 1 : coreLocks.psLock,
  1462. minOneWay: tempLocks.mH1Way != null ? tempLocks.mH1Way - 1 : coreLocks.minHLock,
  1463. majOneWay: tempLocks.MH1Way != null ? tempLocks.MH1Way - 1 : coreLocks.majHLock,
  1464. tollLock: tempLocks.Toll != null ? tempLocks.Toll - 1 : null,
  1465. unpavedLock: tempLocks.Unpaved != null
  1466. };
  1467.  
  1468. if (seg.type === 'segment' && onScreen(seg) && (segStateName === _currentState)) {
  1469. getSegmentConditions(segAtt, conditions);
  1470.  
  1471. // Process local streets
  1472. if (segType === 1) {
  1473. lockUpdateLvl = coreLocks.lsLock;
  1474.  
  1475. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1476. lockUpdateLvl++;
  1477. }
  1478. if (conditions.isOneWay && attLocks.lsOneWay && oneWayChkd) {
  1479. lockUpdateLvl = attLocks.lsOneWay;
  1480. }
  1481. enUpdate = true;
  1482. }
  1483. // Process primary streets
  1484. if (segType === 2) {
  1485. lockUpdateLvl = coreLocks.psLock;
  1486.  
  1487. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1488. lockUpdateLvl++;
  1489. }
  1490. if (conditions.isOneWay && attLocks.psOneWay && oneWayChkd) {
  1491. lockUpdateLvl = attLocks.psOneWay;
  1492. }
  1493. enUpdate = true;
  1494. }
  1495. // Process Fwy
  1496. if (segType === 3) {
  1497. lockUpdateLvl = coreLocks.fwyLock;
  1498. enUpdate = true;
  1499. }
  1500. // Process ramps
  1501. if (segType === 4) {
  1502. lockUpdateLvl = coreLocks.rmpLock;
  1503. enUpdate = true;
  1504. if (lockUpdateLvl === 'HRCS') {
  1505. lockUpdateLvl = getHighestLock(segAtt.id);
  1506. }
  1507. }
  1508. // Process routable ped path
  1509. // if(segType == 5) {
  1510. // lockUpdateLvl = coreLocks.rpedLock;
  1511. // enUpdate = true;
  1512. // }
  1513. // Process MH
  1514. if (segType === 6) {
  1515. lockUpdateLvl = coreLocks.majHLock;
  1516.  
  1517. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1518. lockUpdateLvl++;
  1519. }
  1520. if (conditions.isOneWay && attLocks.majHOneWay && oneWayChkd) {
  1521. lockUpdateLvl = attLocks.majOneWay;
  1522. }
  1523. enUpdate = true;
  1524. }
  1525. // Process minor highways
  1526. if (segType === 7) {
  1527. lockUpdateLvl = coreLocks.minHLock;
  1528.  
  1529. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1530. lockUpdateLvl++;
  1531. }
  1532. if (conditions.isOneWay && attLocks.minHOneWay && oneWayChkd) {
  1533. lockUpdateLvl = attLocks.minHOneWay;
  1534. }
  1535. enUpdate = true;
  1536. }
  1537. // Process offroad
  1538. if (segType === 8) {
  1539. lockUpdateLvl = coreLocks.offRoadLock;
  1540. enUpdate = true;
  1541. }
  1542. // Process non-routable ped path
  1543. if (segType === 10) {
  1544. lockUpdateLvl = coreLocks.nrpedLock;
  1545. enUpdate = true;
  1546. }
  1547. // Process Ferry
  1548. if (segType === 15) {
  1549. lockUpdateLvl = coreLocks.fryLock;
  1550. enUpdate = true;
  1551. }
  1552. // Process PVT
  1553. if (segType === 17) {
  1554. lockUpdateLvl = coreLocks.pvtLock;
  1555.  
  1556. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1557. lockUpdateLvl++;
  1558. }
  1559. if (conditions.isOneWay && attLocks.pvtOneWay && oneWayChkd) {
  1560. lockUpdateLvl = attLocks.pvtOneWay;
  1561. }
  1562. enUpdate = true;
  1563. }
  1564. // Process Railroads
  1565. if (segType === 18) {
  1566. lockUpdateLvl = coreLocks.rrLock;
  1567. enUpdate = true;
  1568. }
  1569. // Process Runways
  1570. if (segType === 19) {
  1571. lockUpdateLvl = coreLocks.rnwyLock;
  1572. enUpdate = true;
  1573. }
  1574. // Process PLR
  1575. if (segType === 20) {
  1576. lockUpdateLvl = coreLocks.plrLock;
  1577.  
  1578. if (conditions.isUnpaved && attLocks.unpavedLock && unpavedChkd) {
  1579. lockUpdateLvl++;
  1580. }
  1581. if (conditions.isOneWay && attLocks.plrOneWay && oneWayChkd) {
  1582. lockUpdateLvl = attLocks.plrOneWay;
  1583. }
  1584. enUpdate = true;
  1585. }
  1586. if (conditions.isTollRoad && attLocks.tollLock && tollChkd) {
  1587. lockUpdateLvl = attLocks.tollLock;
  1588. }
  1589. if (lockUpdateLvl === -1) lockUpdateLvl = 0;
  1590. }
  1591. }
  1592.  
  1593. if (enUpdate) return lockUpdateLvl;
  1594. return false;
  1595. }
  1596.  
  1597. function relockAll() {
  1598. let count = 0;
  1599. const resetHigher = getId('lsEnableResetHigher').checked;
  1600.  
  1601. if (getCurrentState()) {
  1602. _.each(W.model.segments.getObjectArray(), v => {
  1603. const segAtt = v.attributes;
  1604. const currLockRnk = segAtt.lockRank;
  1605. let updateSuccess;
  1606.  
  1607. const stdLockRank = processSegment(v);
  1608.  
  1609. if (stdLockRank !== false) {
  1610. if (currLockRnk < stdLockRank || (currLockRnk > stdLockRank && resetHigher)) {
  1611. updateSuccess = processLocks(v, currLockRnk, stdLockRank);
  1612. }
  1613. }
  1614. if (updateSuccess) count++;
  1615. });
  1616. resetUISegStats();
  1617.  
  1618. if (count > 0) WazeWrap.Alerts.info(GM_info.script.name, `Locked ${count} segments`);
  1619. else WazeWrap.Alerts.info(GM_info.script.name, 'No segments out of standards');
  1620. }
  1621. }
  1622.  
  1623. function tryScan() {
  1624. if (!W.editingMediator.attributes.editingHouseNumbers && getId('lsEnableActiveScan').checked) scanArea(false);
  1625. }
  1626.  
  1627. function scanArea(manual) {
  1628. // Start by resetting UI scan elements
  1629. resetUISegStats();
  1630. let okGO = getCurrentState();
  1631.  
  1632. function editorSufficientRank(segRank, standardRank) {
  1633. if (cakeFlavor >= segRank && cakeFlavor >= standardRank) { return true; }
  1634. return false;
  1635. }
  1636.  
  1637. function highlightSegments(errorType, segGeo) {
  1638. const enableHighlight = getId('lsEnableHighlightSeg').checked;
  1639. if (enableHighlight) {
  1640. const style = {
  1641. strokeColor: '',
  1642. strokeLinecap: 'round',
  1643. strokeWidth: 18,
  1644. fill: false,
  1645. strokeOpacity: 0.5
  1646. };
  1647. if (errorType === 'high') { style.strokeColor = 'cyan'; } else { style.strokeColor = 'red'; }
  1648.  
  1649. const geo = segGeo.clone();
  1650. const feature = new OpenLayers.Feature.Vector(geo, {}, style);
  1651. LocksmithHighlightLayer.addFeatures([feature]);
  1652. }
  1653. }
  1654.  
  1655. if (okGO) {
  1656. // Object with array of roadtypes, to collect each wrongly locked segment, for later use
  1657. const badLockSegs = {
  1658. ls: [],
  1659. ps: [],
  1660. mih: [],
  1661. mah: [],
  1662. rmp: [],
  1663. fwy: [],
  1664. plr: [],
  1665. pvt: [],
  1666. rail: [],
  1667. fry: [],
  1668. rnwy: [],
  1669. ofrd: [],
  1670. nrpd: [],
  1671. othr: []
  1672. };
  1673. let incorrectLocks = false;
  1674. let numWrongLocks = 0;
  1675. const resetHigher = getId('lsEnableResetHigher').checked;
  1676. const ignoreHigher = getId('lsEnableIgnoreRank').checked;
  1677.  
  1678. // Count how many segments need a corrected lock (limit to 150 to save CPU), accounts for the users editor level
  1679. _.each(W.model.segments.getObjectArray(), v => {
  1680. if (numWrongLocks < 150 && v.type === 'segment' && onScreen(v)) {
  1681. const correctLockRank = processSegment(v);
  1682.  
  1683. if (correctLockRank !== false) {
  1684. const segGeo = v.geometry;
  1685. const segType = v.attributes.roadType;
  1686. const segLockRank = v.attributes.lockRank;
  1687.  
  1688. // LS
  1689. if (segType === 1) {
  1690. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1691. badLockSegs.ls.push({
  1692. segID: v.attributes.id,
  1693. currLockRnk: segLockRank,
  1694. stdLockRnk: correctLockRank,
  1695. lockError: 'high'
  1696. });
  1697. incorrectLocks = true;
  1698. numWrongLocks++;
  1699. highlightSegments('high', segGeo);
  1700. }
  1701. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1702. badLockSegs.ls.push({
  1703. segID: v.attributes.id,
  1704. currLockRnk: segLockRank,
  1705. stdLockRnk: correctLockRank,
  1706. lockError: 'low'
  1707. });
  1708. incorrectLocks = true;
  1709. numWrongLocks++;
  1710. highlightSegments('low', segGeo);
  1711. }
  1712. }
  1713. // PS
  1714. if (segType === 2) {
  1715. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1716. badLockSegs.ps.push({
  1717. segID: v.attributes.id,
  1718. currLockRnk: segLockRank,
  1719. stdLockRnk: correctLockRank,
  1720. lockError: 'high'
  1721. });
  1722. incorrectLocks = true;
  1723. numWrongLocks++;
  1724. highlightSegments('high', segGeo);
  1725. }
  1726. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1727. badLockSegs.ps.push({
  1728. segID: v.attributes.id,
  1729. currLockRnk: segLockRank,
  1730. stdLockRnk: correctLockRank,
  1731. lockError: 'low'
  1732. });
  1733. incorrectLocks = true;
  1734. numWrongLocks++;
  1735. highlightSegments('low', segGeo);
  1736. }
  1737. }
  1738. // Fwy
  1739. if (segType === 3) {
  1740. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1741. badLockSegs.fwy.push({
  1742. segID: v.attributes.id,
  1743. currLockRnk: segLockRank,
  1744. stdLockRnk: correctLockRank,
  1745. lockError: 'high'
  1746. });
  1747. incorrectLocks = true;
  1748. numWrongLocks++;
  1749. highlightSegments('high', segGeo);
  1750. }
  1751. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1752. badLockSegs.fwy.push({
  1753. segID: v.attributes.id,
  1754. currLockRnk: segLockRank,
  1755. stdLockRnk: correctLockRank,
  1756. lockError: 'low'
  1757. });
  1758. incorrectLocks = true;
  1759. numWrongLocks++;
  1760. highlightSegments('low', segGeo);
  1761. }
  1762. }
  1763. // Rmp
  1764. if (segType === 4) {
  1765. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1766. badLockSegs.rmp.push({
  1767. segID: v.attributes.id,
  1768. currLockRnk: segLockRank,
  1769. stdLockRnk: correctLockRank,
  1770. lockError: 'high'
  1771. });
  1772. incorrectLocks = true;
  1773. numWrongLocks++;
  1774. highlightSegments('high', segGeo);
  1775. }
  1776. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1777. badLockSegs.rmp.push({
  1778. segID: v.attributes.id,
  1779. currLockRnk: segLockRank,
  1780. stdLockRnk: correctLockRank,
  1781. lockError: 'low'
  1782. });
  1783. incorrectLocks = true;
  1784. numWrongLocks++;
  1785. highlightSegments('low', segGeo);
  1786. }
  1787. }
  1788. // MH
  1789. if (segType === 6) {
  1790. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1791. badLockSegs.mah.push({
  1792. segID: v.attributes.id,
  1793. currLockRnk: segLockRank,
  1794. stdLockRnk: correctLockRank,
  1795. lockError: 'high'
  1796. });
  1797. incorrectLocks = true;
  1798. numWrongLocks++;
  1799. highlightSegments('high', segGeo);
  1800. }
  1801. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1802. badLockSegs.mah.push({
  1803. segID: v.attributes.id,
  1804. currLockRnk: segLockRank,
  1805. stdLockRnk: correctLockRank,
  1806. lockError: 'low'
  1807. });
  1808. incorrectLocks = true;
  1809. numWrongLocks++;
  1810. highlightSegments('low', segGeo);
  1811. }
  1812. }
  1813. // mH
  1814. if (segType === 7) {
  1815. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1816. badLockSegs.mih.push({
  1817. segID: v.attributes.id,
  1818. currLockRnk: segLockRank,
  1819. stdLockRnk: correctLockRank,
  1820. lockError: 'high'
  1821. });
  1822. incorrectLocks = true;
  1823. numWrongLocks++;
  1824. highlightSegments('high', segGeo);
  1825. }
  1826. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1827. badLockSegs.mih.push({
  1828. segID: v.attributes.id,
  1829. currLockRnk: segLockRank,
  1830. stdLockRnk: correctLockRank,
  1831. lockError: 'low'
  1832. });
  1833. incorrectLocks = true;
  1834. numWrongLocks++;
  1835. highlightSegments('low', segGeo);
  1836. }
  1837. }
  1838. // Offroad
  1839. if (segType === 8) {
  1840. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1841. badLockSegs.ofrd.push({
  1842. segID: v.attributes.id,
  1843. currLockRnk: segLockRank,
  1844. stdLockRnk: correctLockRank,
  1845. lockError: 'high'
  1846. });
  1847. incorrectLocks = true;
  1848. numWrongLocks++;
  1849. highlightSegments('high', segGeo);
  1850. }
  1851. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1852. badLockSegs.ofrd.push({
  1853. segID: v.attributes.id,
  1854. currLockRnk: segLockRank,
  1855. stdLockRnk: correctLockRank,
  1856. lockError: 'low'
  1857. });
  1858. incorrectLocks = true;
  1859. numWrongLocks++;
  1860. highlightSegments('low', segGeo);
  1861. }
  1862. }
  1863. // Non-Routable Ped
  1864. if (segType === 10) {
  1865. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1866. badLockSegs.nrpd.push({
  1867. segID: v.attributes.id,
  1868. currLockRnk: segLockRank,
  1869. stdLockRnk: correctLockRank,
  1870. lockError: 'high'
  1871. });
  1872. incorrectLocks = true;
  1873. numWrongLocks++;
  1874. highlightSegments('high', segGeo);
  1875. }
  1876. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1877. badLockSegs.nrpd.push({
  1878. segID: v.attributes.id,
  1879. currLockRnk: segLockRank,
  1880. stdLockRnk: correctLockRank,
  1881. lockError: 'low'
  1882. });
  1883. incorrectLocks = true;
  1884. numWrongLocks++;
  1885. highlightSegments('low', segGeo);
  1886. }
  1887. }
  1888. // Ferry
  1889. if (segType === 15) {
  1890. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1891. badLockSegs.fry.push({
  1892. segID: v.attributes.id,
  1893. currLockRnk: segLockRank,
  1894. stdLockRnk: correctLockRank,
  1895. lockError: 'high'
  1896. });
  1897. incorrectLocks = true;
  1898. numWrongLocks++;
  1899. highlightSegments('high', segGeo);
  1900. }
  1901. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1902. badLockSegs.fry.push({
  1903. segID: v.attributes.id,
  1904. currLockRnk: segLockRank,
  1905. stdLockRnk: correctLockRank,
  1906. lockError: 'low'
  1907. });
  1908. incorrectLocks = true;
  1909. numWrongLocks++;
  1910. highlightSegments('low', segGeo);
  1911. }
  1912. }
  1913. // Pvt
  1914. if (segType === 17) {
  1915. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1916. badLockSegs.pvt.push({
  1917. segID: v.attributes.id,
  1918. currLockRnk: segLockRank,
  1919. stdLockRnk: correctLockRank,
  1920. lockError: 'high'
  1921. });
  1922. incorrectLocks = true;
  1923. numWrongLocks++;
  1924. highlightSegments('high', segGeo);
  1925. }
  1926. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1927. badLockSegs.pvt.push({
  1928. segID: v.attributes.id,
  1929. currLockRnk: segLockRank,
  1930. stdLockRnk: correctLockRank,
  1931. lockError: 'low'
  1932. });
  1933. incorrectLocks = true;
  1934. numWrongLocks++;
  1935. highlightSegments('low', segGeo);
  1936. }
  1937. }
  1938. // Railroads
  1939. if (segType === 18) {
  1940. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1941. badLockSegs.rail.push({
  1942. segID: v.attributes.id,
  1943. currLockRnk: segLockRank,
  1944. stdLockRnk: correctLockRank,
  1945. lockError: 'high'
  1946. });
  1947. incorrectLocks = true;
  1948. numWrongLocks++;
  1949. highlightSegments('high', segGeo);
  1950. }
  1951. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1952. badLockSegs.rail.push({
  1953. segID: v.attributes.id,
  1954. currLockRnk: segLockRank,
  1955. stdLockRnk: correctLockRank,
  1956. lockError: 'low'
  1957. });
  1958. incorrectLocks = true;
  1959. numWrongLocks++;
  1960. highlightSegments('low', segGeo);
  1961. }
  1962. }
  1963. // Runway
  1964. if (segType === 19) {
  1965. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1966. badLockSegs.rnwy.push({
  1967. segID: v.attributes.id,
  1968. currLockRnk: segLockRank,
  1969. stdLockRnk: correctLockRank,
  1970. lockError: 'high'
  1971. });
  1972. incorrectLocks = true;
  1973. numWrongLocks++;
  1974. highlightSegments('high', segGeo);
  1975. }
  1976. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1977. badLockSegs.rnwy.push({
  1978. segID: v.attributes.id,
  1979. currLockRnk: segLockRank,
  1980. stdLockRnk: correctLockRank,
  1981. lockError: 'low'
  1982. });
  1983. incorrectLocks = true;
  1984. numWrongLocks++;
  1985. highlightSegments('low', segGeo);
  1986. }
  1987. }
  1988. // PLR
  1989. if (segType === 20) {
  1990. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  1991. badLockSegs.plr.push({
  1992. segID: v.attributes.id,
  1993. currLockRnk: segLockRank,
  1994. stdLockRnk: correctLockRank,
  1995. lockError: 'high'
  1996. });
  1997. incorrectLocks = true;
  1998. numWrongLocks++;
  1999. highlightSegments('high', segGeo);
  2000. }
  2001. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  2002. badLockSegs.plr.push({
  2003. segID: v.attributes.id,
  2004. currLockRnk: segLockRank,
  2005. stdLockRnk: correctLockRank,
  2006. lockError: 'low'
  2007. });
  2008. incorrectLocks = true;
  2009. numWrongLocks++;
  2010. highlightSegments('low', segGeo);
  2011. }
  2012. }
  2013. // All other segment types
  2014. if (segType === 8 || segType === 10 || segType === 15 || segType === 17 || segType === 18 || segType === 19 || segType === 20) {
  2015. if (resetHigher && segLockRank > correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  2016. badLockSegs.othr.push({
  2017. segID: v.attributes.id,
  2018. currLockRnk: segLockRank,
  2019. stdLockRnk: correctLockRank,
  2020. lockError: 'high'
  2021. });
  2022. incorrectLocks = true;
  2023. numWrongLocks++;
  2024. highlightSegments('high', segGeo);
  2025. }
  2026. if (segLockRank < correctLockRank && (editorSufficientRank(segLockRank, correctLockRank) || ignoreHigher)) {
  2027. badLockSegs.othr.push({
  2028. segID: v.attributes.id,
  2029. currLockRnk: segLockRank,
  2030. stdLockRnk: correctLockRank,
  2031. lockError: 'low'
  2032. });
  2033. incorrectLocks = true;
  2034. numWrongLocks++;
  2035. highlightSegments('low', segGeo);
  2036. }
  2037. }
  2038. }
  2039. }
  2040. });
  2041.  
  2042.  
  2043. // Enable/configure UI elements if bad segments are found
  2044. let lsLow = 0;
  2045. let lsHigh = 0;
  2046. let psLow = 0;
  2047. let psHigh = 0;
  2048. let miLow = 0;
  2049. let miHigh = 0;
  2050. let maLow = 0;
  2051. let maHigh = 0;
  2052. let rmpLow = 0;
  2053. let rmpHigh = 0;
  2054. let fwyLow = 0;
  2055. let fwyHigh = 0;
  2056. let othrLow = 0;
  2057. let othrHigh = 0;
  2058. let plrLow = 0;
  2059. let plrHigh = 0;
  2060. let pvtLow = 0;
  2061. let pvtHigh = 0;
  2062. let railLow = 0;
  2063. let railHigh = 0;
  2064. let fryLow = 0;
  2065. let fryHigh = 0;
  2066. let rnwyLow = 0;
  2067. let rnwyHigh = 0;
  2068. let ofrdLow = 0;
  2069. let ofrdHigh = 0;
  2070. let nrpdLow = 0;
  2071. let nrpdHigh = 0;
  2072. if (incorrectLocks) {
  2073. _.each(badLockSegs, (key, value) => {
  2074. if (value === 'ls') {
  2075. for (let i = 0; i < key.length; i++) {
  2076. if (key[i].lockError === 'high') lsHigh++;
  2077. if (key[i].lockError === 'low') lsLow++;
  2078. }
  2079. if (lsHigh > 0 || lsLow > 0) {
  2080. if (roadClear) {
  2081. changeUI('#icon-Lock-LS', 1, 'lock', 'both');
  2082. $('#icon-Lock-LS').click(() => {
  2083. for (let i = 0; i < badLockSegs.ls.length; i++) {
  2084. const aryData = badLockSegs.ls[i];
  2085. const seg = W.model.segments.getObjectById(aryData.segID);
  2086. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2087. }
  2088. changeUI('#icon-Lock-LS', 0, 'lock', null);
  2089. changeUI('#ls-LS-Lock-Up', 0, 'lock', null);
  2090. changeUI('#ls-LS-Lock-Down', 0, 'lock', null);
  2091. changeUI('#ls-LS-Low-Quan', 1, 'text', '--');
  2092. changeUI('#ls-LS-High-Quan', 1, 'text', '--');
  2093. });
  2094. }
  2095. if (lsHigh > 0) {
  2096. changeUI('#ls-LS-High-Quan', 1, 'text', lsHigh);
  2097. if (roadClear) {
  2098. changeUI('#ls-LS-Lock-Down', 1, 'lock', 'high');
  2099. $('#ls-LS-Lock-Down').click(() => {
  2100. for (let i = 0; i < badLockSegs.ls.length; i++) {
  2101. const aryData = badLockSegs.ls[i];
  2102. const seg = W.model.segments.getObjectById(aryData.segID);
  2103. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2104. }
  2105. changeUI('#ls-LS-Lock-Down', 0, 'lock', null);
  2106. changeUI('#ls-LS-High-Quan', 1, 'text', '--');
  2107. lsHigh = 0;
  2108. if (lsLow === 0) changeUI('#icon-Lock-LS', 0, 'lock', null);
  2109. });
  2110. }
  2111. }
  2112. if (lsLow > 0) {
  2113. changeUI('#ls-LS-Low-Quan', 1, 'text', lsLow);
  2114.  
  2115. if (roadClear) {
  2116. changeUI('#ls-LS-Lock-Up', 1, 'lock', 'low');
  2117. $('#ls-LS-Lock-Up').click(() => {
  2118. for (let i = 0; i < badLockSegs.ls.length; i++) {
  2119. const aryData = badLockSegs.ls[i];
  2120. const seg = W.model.segments.getObjectById(aryData.segID);
  2121. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2122. }
  2123. changeUI('#ls-LS-Lock-Up', 0, 'lock', null);
  2124. changeUI('#ls-LS-Low-Quan', 1, 'text', '--');
  2125. lsLow = 0;
  2126. if (lsHigh === 0) changeUI('#icon-Lock-LS', 0, 'lock', null);
  2127. });
  2128. }
  2129. }
  2130. }
  2131. }
  2132. if (value === 'ps') {
  2133. for (let i = 0; i < key.length; i++) {
  2134. if (key[i].lockError === 'high') psHigh++;
  2135. if (key[i].lockError === 'low') psLow++;
  2136. }
  2137. if (psHigh > 0 || psLow > 0) {
  2138. if (roadClear) {
  2139. changeUI('#icon-Lock-PS', 1, 'lock', 'both');
  2140. $('#icon-Lock-PS').click(() => {
  2141. for (let i = 0; i < badLockSegs.ps.length; i++) {
  2142. const aryData = badLockSegs.ps[i];
  2143. const seg = W.model.segments.getObjectById(aryData.segID);
  2144. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2145. }
  2146. changeUI('#icon-Lock-PS', 0, 'lock', null);
  2147. changeUI('#ls-PS-Lock-Up', 0, 'lock', null);
  2148. changeUI('#ls-PS-Lock-Down', 0, 'lock', null);
  2149. changeUI('#ls-PS-Low-Quan', 1, 'text', '--');
  2150. changeUI('#ls-PS-High-Quan', 1, 'text', '--');
  2151. });
  2152. }
  2153. if (psHigh > 0) {
  2154. changeUI('#ls-PS-High-Quan', 1, 'text', psHigh);
  2155.  
  2156. if (roadClear) {
  2157. changeUI('#ls-PS-Lock-Down', 1, 'lock', 'high');
  2158. $('#ls-PS-Lock-Down').click(() => {
  2159. for (let i = 0; i < badLockSegs.ps.length; i++) {
  2160. const aryData = badLockSegs.ps[i];
  2161. const seg = W.model.segments.getObjectById(aryData.segID);
  2162. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2163. }
  2164. changeUI('#ls-PS-Lock-Down', 0, 'lock', null);
  2165. changeUI('#ls-PS-High-Quan', 1, 'text', '--');
  2166. psHigh = 0;
  2167. if (psLow === 0) changeUI('#icon-Lock-PS', 0, 'lock', null);
  2168. });
  2169. }
  2170. }
  2171. if (psLow > 0) {
  2172. changeUI('#ls-PS-Low-Quan', 1, 'text', psLow);
  2173.  
  2174. if (roadClear) {
  2175. changeUI('#ls-PS-Lock-Up', 1, 'lock', 'low');
  2176. $('#ls-PS-Lock-Up').click(() => {
  2177. for (let i = 0; i < badLockSegs.ps.length; i++) {
  2178. const aryData = badLockSegs.ps[i];
  2179. const seg = W.model.segments.getObjectById(aryData.segID);
  2180. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2181. }
  2182. changeUI('#ls-PS-Lock-Up', 0, 'lock', null);
  2183. changeUI('#ls-PS-Low-Quan', 1, 'text', '--');
  2184. psLow = 0;
  2185. if (psHigh === 0) changeUI('#icon-Lock-PS', 0, 'lock', null);
  2186. });
  2187. }
  2188. }
  2189. }
  2190. }
  2191. if (value === 'mih') {
  2192. for (let i = 0; i < key.length; i++) {
  2193. if (key[i].lockError === 'high') miHigh++;
  2194. if (key[i].lockError === 'low') miLow++;
  2195. }
  2196. if (miHigh > 0 || miLow > 0) {
  2197. if (roadClear) {
  2198. changeUI('#icon-Lock-minH', 1, 'lock', 'both');
  2199. $('#icon-Lock-minH').click(() => {
  2200. for (let i = 0; i < badLockSegs.mih.length; i++) {
  2201. const aryData = badLockSegs.mih[i];
  2202. const seg = W.model.segments.getObjectById(aryData.segID);
  2203. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2204. }
  2205. changeUI('#icon-Lock-minH', 0, 'lock', null);
  2206. changeUI('#ls-minH-Lock-Up', 0, 'lock', null);
  2207. changeUI('#ls-minH-Lock-Down', 0, 'lock', null);
  2208. changeUI('#ls-minH-Low-Quan', 1, 'text', '--');
  2209. changeUI('#ls-minH-High-Quan', 1, 'text', '--');
  2210. });
  2211. }
  2212. if (miHigh > 0) {
  2213. changeUI('#ls-minH-High-Quan', 1, 'text', miHigh);
  2214.  
  2215. if (roadClear) {
  2216. changeUI('#ls-minH-Lock-Down', 1, 'lock', 'high');
  2217. $('#ls-minH-Lock-Down').click(() => {
  2218. for (let i = 0; i < badLockSegs.mih.length; i++) {
  2219. const aryData = badLockSegs.mih[i];
  2220. const seg = W.model.segments.getObjectById(aryData.segID);
  2221. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2222. }
  2223. changeUI('#ls-minH-Lock-Down', 0, 'lock', null);
  2224. changeUI('#ls-minH-High-Quan', 1, 'text', '--');
  2225. miHigh = 0;
  2226. if (miLow === 0) changeUI('#icon-Lock-minH', 0, 'lock', null);
  2227. });
  2228. }
  2229. }
  2230. if (miLow > 0) {
  2231. changeUI('#ls-minH-Low-Quan', 1, 'text', miLow);
  2232.  
  2233. if (roadClear) {
  2234. changeUI('#ls-minH-Lock-Up', 1, 'lock', 'low');
  2235. $('#ls-minH-Lock-Up').click(() => {
  2236. for (let i = 0; i < badLockSegs.mih.length; i++) {
  2237. const aryData = badLockSegs.mih[i];
  2238. const seg = W.model.segments.getObjectById(aryData.segID);
  2239. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2240. }
  2241. changeUI('#ls-minH-Lock-Up', 0, 'lock', null);
  2242. changeUI('#ls-minH-Low-Quan', 1, 'text', '--');
  2243. miLow = 0;
  2244. if (miHigh === 0) changeUI('#icon-Lock-minH', 0, 'lock', null);
  2245. });
  2246. }
  2247. }
  2248. }
  2249. }
  2250. if (value === 'mah') {
  2251. for (let i = 0; i < key.length; i++) {
  2252. if (key[i].lockError === 'high') maHigh++;
  2253. if (key[i].lockError === 'low') maLow++;
  2254. }
  2255. if (maHigh > 0 || maLow > 0) {
  2256. if (roadClear) {
  2257. changeUI('#icon-Lock-majH', 1, 'lock', 'both');
  2258. $('#icon-Lock-majH').click(() => {
  2259. for (let i = 0; i < badLockSegs.mah.length; i++) {
  2260. const aryData = badLockSegs.mah[i];
  2261. const seg = W.model.segments.getObjectById(aryData.segID);
  2262. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2263. }
  2264. changeUI('#icon-Lock-majH', 0, 'lock', null);
  2265. changeUI('#ls-majH-Lock-Up', 0, 'lock', null);
  2266. changeUI('#ls-majH-Lock-Down', 0, 'lock', null);
  2267. changeUI('#ls-majH-Low-Quan', 1, 'text', '--');
  2268. changeUI('#ls-majH-High-Quan', 1, 'text', '--');
  2269. });
  2270. }
  2271. if (maHigh > 0) {
  2272. changeUI('#ls-majH-High-Quan', 1, 'text', maHigh);
  2273.  
  2274. if (roadClear) {
  2275. changeUI('#ls-majH-Lock-Down', 1, 'lock', 'high');
  2276. $('#ls-majH-Lock-Down').click(() => {
  2277. for (let i = 0; i < badLockSegs.mah.length; i++) {
  2278. const aryData = badLockSegs.mah[i];
  2279. const seg = W.model.segments.getObjectById(aryData.segID);
  2280. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2281. }
  2282. changeUI('#ls-majH-Lock-Down', 0, 'lock', null);
  2283. changeUI('#ls-majH-High-Quan', 1, 'text', '--');
  2284. maHigh = 0;
  2285. if (maLow === 0) changeUI('#icon-Lock-majH', 0, 'lock', null);
  2286. });
  2287. }
  2288. }
  2289. if (maLow > 0) {
  2290. changeUI('#ls-majH-Low-Quan', 1, 'text', maLow);
  2291.  
  2292. if (roadClear) {
  2293. changeUI('#ls-majH-Lock-Up', 1, 'lock', 'low');
  2294. $('#ls-majH-Lock-Up').click(() => {
  2295. for (let i = 0; i < badLockSegs.mah.length; i++) {
  2296. const aryData = badLockSegs.mah[i];
  2297. const seg = W.model.segments.getObjectById(aryData.segID);
  2298. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2299. }
  2300. changeUI('#ls-majH-Lock-Up', 0, 'lock', null);
  2301. changeUI('#ls-majH-Low-Quan', 1, 'text', '--');
  2302. maLow = 0;
  2303. if (maHigh === 0) changeUI('#icon-Lock-majH', 0, 'lock', null);
  2304. });
  2305. }
  2306. }
  2307. }
  2308. }
  2309. if (value === 'rmp') {
  2310. for (let i = 0; i < key.length; i++) {
  2311. if (key[i].lockError === 'high') rmpHigh++;
  2312. if (key[i].lockError === 'low') rmpLow++;
  2313. }
  2314. if (rmpHigh > 0 || rmpLow > 0) {
  2315. if (roadClear) {
  2316. changeUI('#icon-Lock-Rmp', 1, 'lock', 'both');
  2317. $('#icon-Lock-Rmp').click(() => {
  2318. for (let i = 0; i < badLockSegs.rmp.length; i++) {
  2319. const aryData = badLockSegs.rmp[i];
  2320. const seg = W.model.segments.getObjectById(aryData.segID);
  2321. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2322. }
  2323. changeUI('#icon-Lock-Rmp', 0, 'lock', null);
  2324. changeUI('#ls-Rmp-Lock-Up', 0, 'lock', null);
  2325. changeUI('#ls-Rmp-Lock-Down', 0, 'lock', null);
  2326. changeUI('#ls-Rmp-Low-Quan', 1, 'text', '--');
  2327. changeUI('#ls-Rmp-High-Quan', 1, 'text', '--');
  2328. });
  2329. }
  2330. if (rmpHigh > 0) {
  2331. changeUI('#ls-Rmp-High-Quan', 1, 'text', rmpHigh);
  2332.  
  2333. if (roadClear) {
  2334. changeUI('#ls-Rmp-Lock-Down', 1, 'lock', 'high');
  2335. $('#ls-Rmp-Lock-Down').click(() => {
  2336. for (let i = 0; i < badLockSegs.rmp.length; i++) {
  2337. const aryData = badLockSegs.rmp[i];
  2338. const seg = W.model.segments.getObjectById(aryData.segID);
  2339. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2340. }
  2341. changeUI('#ls-Rmp-Lock-Down', 0, 'lock', null);
  2342. changeUI('#ls-Rmp-High-Quan', 1, 'text', '--');
  2343. rmpHigh = 0;
  2344. if (rmpLow === 0) changeUI('#icon-Lock-Rmp', 0, 'lock', null);
  2345. });
  2346. }
  2347. }
  2348. if (rmpLow > 0) {
  2349. changeUI('#ls-Rmp-Low-Quan', 1, 'text', rmpLow);
  2350.  
  2351. if (roadClear) {
  2352. changeUI('#ls-Rmp-Lock-Up', 1, 'lock', 'low');
  2353. $('#ls-Rmp-Lock-Up').click(() => {
  2354. for (let i = 0; i < badLockSegs.rmp.length; i++) {
  2355. const aryData = badLockSegs.rmp[i];
  2356. const seg = W.model.segments.getObjectById(aryData.segID);
  2357. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2358. }
  2359. changeUI('#ls-Rmp-Lock-Up', 0, 'lock', null);
  2360. changeUI('#ls-Rmp-Low-Quan', 1, 'text', '--');
  2361. rmpLow = 0;
  2362. if (rmpHigh === 0) changeUI('#icon-Lock-Rmp', 0, 'lock', null);
  2363. });
  2364. }
  2365. }
  2366. }
  2367. }
  2368. if (value === 'fwy') {
  2369. for (let i = 0; i < key.length; i++) {
  2370. if (key[i].lockError === 'high') fwyHigh++;
  2371. if (key[i].lockError === 'low') fwyLow++;
  2372. }
  2373. if (fwyHigh > 0 || fwyLow > 0) {
  2374. if (roadClear) {
  2375. changeUI('#icon-Lock-Fwy', 1, 'lock', 'both');
  2376. $('#icon-Lock-Fwy').click(() => {
  2377. for (let i = 0; i < badLockSegs.fwy.length; i++) {
  2378. const aryData = badLockSegs.fwy[i];
  2379. const seg = W.model.segments.getObjectById(aryData.segID);
  2380. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2381. }
  2382. changeUI('#icon-Lock-Fwy', 0, 'lock', null);
  2383. changeUI('#ls-Fwy-Lock-Up', 0, 'lock', null);
  2384. changeUI('#ls-Fwy-Lock-Down', 0, 'lock', null);
  2385. changeUI('#ls-Fwy-Low-Quan', 1, 'text', '--');
  2386. changeUI('#ls-Fwy-High-Quan', 1, 'text', '--');
  2387. });
  2388. }
  2389. if (fwyHigh > 0) {
  2390. changeUI('#ls-Fwy-High-Quan', 1, 'text', fwyHigh);
  2391.  
  2392. if (roadClear) {
  2393. changeUI('#ls-Fwy-Lock-Down', 1, 'lock', 'high');
  2394. $('#ls-Fwy-Lock-Down').click(() => {
  2395. for (let i = 0; i < badLockSegs.fwy.length; i++) {
  2396. const aryData = badLockSegs.fwy[i];
  2397. const seg = W.model.segments.getObjectById(aryData.segID);
  2398. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2399. }
  2400. changeUI('#ls-Fwy-Lock-Down', 0, 'lock', null);
  2401. changeUI('#ls-Fwy-High-Quan', 1, 'text', '--');
  2402. fwyHigh = 0;
  2403. if (fwyLow === 0) changeUI('#icon-Lock-Fwy', 0, 'lock', null);
  2404. });
  2405. }
  2406. }
  2407. if (fwyLow > 0) {
  2408. changeUI('#ls-Fwy-Low-Quan', 1, 'text', fwyLow);
  2409.  
  2410. if (roadClear) {
  2411. changeUI('#ls-Fwy-Lock-Up', 1, 'lock', 'low');
  2412. $('#ls-Fwy-Lock-Up').click(() => {
  2413. for (let i = 0; i < badLockSegs.fwy.length; i++) {
  2414. const aryData = badLockSegs.fwy[i];
  2415. const seg = W.model.segments.getObjectById(aryData.segID);
  2416. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2417. }
  2418. changeUI('#ls-Fwy-Lock-Up', 0, 'lock', null);
  2419. changeUI('#ls-Fwy-Low-Quan', 1, 'text', '--');
  2420. fwyLow = 0;
  2421. if (fwyHigh === 0) changeUI('#icon-Lock-Fwy', 0, 'lock', null);
  2422. });
  2423. }
  2424. }
  2425. }
  2426. }
  2427. if (value === 'othr') {
  2428. for (let i = 0; i < key.length; i++) {
  2429. if (key[i].lockError === 'high') othrHigh++;
  2430. if (key[i].lockError === 'low') othrLow++;
  2431. }
  2432. if (othrHigh > 0 || othrLow > 0) {
  2433. if (roadClear) {
  2434. changeUI('#icon-Lock-othr', 1, 'lock', 'both');
  2435. $('#icon-Lock-othr').click(() => {
  2436. for (let i = 0; i < badLockSegs.othr.length; i++) {
  2437. const aryData = badLockSegs.othr[i];
  2438. const seg = W.model.segments.getObjectById(aryData.segID);
  2439. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2440. }
  2441. changeUI('#icon-Lock-othr', 0, 'lock', null);
  2442. changeUI('#ls-othr-Lock-Up', 0, 'lock', null);
  2443. changeUI('#ls-othr-Lock-Down', 0, 'lock', null);
  2444. changeUI('#ls-othr-Low-Quan', 1, 'text', '--');
  2445. changeUI('#ls-othr-High-Quan', 1, 'text', '--');
  2446. });
  2447. }
  2448. if (othrHigh > 0) {
  2449. changeUI('#ls-othr-High-Quan', 1, 'text', othrHigh);
  2450. if (roadClear) {
  2451. changeUI('#ls-othr-Lock-Down', 1, 'lock', 'high');
  2452. $('#ls-othr-Lock-Down').click(() => {
  2453. for (let i = 0; i < badLockSegs.othr.length; i++) {
  2454. const aryData = badLockSegs.othr[i];
  2455. const seg = W.model.segments.getObjectById(aryData.segID);
  2456. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2457. }
  2458. changeUI('#ls-othr-Lock-Down', 0, 'lock', null);
  2459. changeUI('#ls-othr-High-Quan', 1, 'text', '--');
  2460. othrHigh = 0;
  2461. if (othrLow === 0) changeUI('#icon-Lock-othr', 0, 'lock', null);
  2462. });
  2463. }
  2464. }
  2465. if (othrLow > 0) {
  2466. changeUI('#ls-othr-Low-Quan', 1, 'text', othrLow);
  2467. if (roadClear) {
  2468. changeUI('#ls-othr-Lock-Up', 1, 'lock', 'low');
  2469. $('#ls-othr-Lock-Up').click(() => {
  2470. for (let i = 0; i < badLockSegs.othr.length; i++) {
  2471. const aryData = badLockSegs.othr[i];
  2472. const seg = W.model.segments.getObjectById(aryData.segID);
  2473. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2474. }
  2475. changeUI('#ls-othr-Lock-Up', 0, 'lock', null);
  2476. changeUI('#ls-othr-Low-Quan', 1, 'text', '--');
  2477. othrLow = 0;
  2478. if (othrHigh === 0) changeUI('#icon-Lock-othr', 0, 'lock', null);
  2479. });
  2480. }
  2481. }
  2482. }
  2483. }
  2484. if (value === 'plr') {
  2485. for (let i = 0; i < key.length; i++) {
  2486. if (key[i].lockError === 'high') plrHigh++;
  2487. if (key[i].lockError === 'low') plrLow++;
  2488. }
  2489. if (plrHigh > 0 || plrLow > 0) {
  2490. if (roadClear) {
  2491. changeUI('#icon-Lock-Plr', 1, 'lock', 'both');
  2492. $('#icon-Lock-Plr').click(() => {
  2493. for (let i = 0; i < badLockSegs.plr.length; i++) {
  2494. const aryData = badLockSegs.plr[i];
  2495. const seg = W.model.segments.getObjectById(aryData.segID);
  2496. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2497. }
  2498. changeUI('#icon-Lock-Plr', 0, 'lock', null);
  2499. changeUI('#ls-Plr-Lock-Up', 0, 'lock', null);
  2500. changeUI('#ls-Plr-Lock-Down', 0, 'lock', null);
  2501. changeUI('#ls-Plr-Low-Quan', 1, 'text', '--');
  2502. changeUI('#ls-Plr-High-Quan', 1, 'text', '--');
  2503. });
  2504. }
  2505. if (plrHigh > 0) {
  2506. changeUI('#ls-Plr-High-Quan', 1, 'text', plrHigh);
  2507. if (roadClear) {
  2508. changeUI('#ls-Plr-Lock-Down', 1, 'lock', 'high');
  2509. $('#ls-Plr-Lock-Down').click(() => {
  2510. for (let i = 0; i < badLockSegs.plr.length; i++) {
  2511. const aryData = badLockSegs.plr[i];
  2512. const seg = W.model.segments.getObjectById(aryData.segID);
  2513. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2514. }
  2515. changeUI('#ls-Plr-Lock-Down', 0, 'lock', null);
  2516. changeUI('#ls-Plr-High-Quan', 1, 'text', '--');
  2517. plrHigh = 0;
  2518. if (plrLow === 0) changeUI('#icon-Lock-Plr', 0, 'lock', null);
  2519. });
  2520. }
  2521. }
  2522. if (plrLow > 0) {
  2523. changeUI('#ls-Plr-Low-Quan', 1, 'text', plrLow);
  2524. if (roadClear) {
  2525. changeUI('#ls-Plr-Lock-Up', 1, 'lock', 'low');
  2526. $('#ls-Plr-Lock-Up').click(() => {
  2527. for (let i = 0; i < badLockSegs.plr.length; i++) {
  2528. const aryData = badLockSegs.plr[i];
  2529. const seg = W.model.segments.getObjectById(aryData.segID);
  2530. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2531. }
  2532. changeUI('#ls-Plr-Lock-Up', 0, 'lock', null);
  2533. changeUI('#ls-Plr-Low-Quan', 1, 'text', '--');
  2534. plrLow = 0;
  2535. if (plrHigh === 0) changeUI('#icon-Lock-Plr', 0, 'lock', null);
  2536. });
  2537. }
  2538. }
  2539. }
  2540. }
  2541. if (value === 'pvt') {
  2542. for (let i = 0; i < key.length; i++) {
  2543. if (key[i].lockError === 'high') pvtHigh++;
  2544. if (key[i].lockError === 'low') pvtLow++;
  2545. }
  2546. if (pvtHigh > 0 || pvtLow > 0) {
  2547. if (roadClear) {
  2548. changeUI('#icon-Lock-Pvt', 1, 'lock', 'both');
  2549. $('#icon-Lock-Pvt').click(() => {
  2550. for (let i = 0; i < badLockSegs.pvt.length; i++) {
  2551. const aryData = badLockSegs.pvt[i];
  2552. const seg = W.model.segments.getObjectById(aryData.segID);
  2553. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2554. }
  2555. changeUI('#icon-Lock-Pvt', 0, 'lock', null);
  2556. changeUI('#ls-Pvt-Lock-Up', 0, 'lock', null);
  2557. changeUI('#ls-Pvt-Lock-Down', 0, 'lock', null);
  2558. changeUI('#ls-Pvt-Low-Quan', 1, 'text', '--');
  2559. changeUI('#ls-Pvt-High-Quan', 1, 'text', '--');
  2560. });
  2561. }
  2562. if (pvtHigh > 0) {
  2563. changeUI('#ls-Pvt-High-Quan', 1, 'text', pvtHigh);
  2564. if (roadClear) {
  2565. changeUI('#ls-Pvt-Lock-Down', 1, 'lock', 'high');
  2566. $('#ls-Pvt-Lock-Down').click(() => {
  2567. for (let i = 0; i < badLockSegs.pvt.length; i++) {
  2568. const aryData = badLockSegs.pvt[i];
  2569. const seg = W.model.segments.getObjectById(aryData.segID);
  2570. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2571. }
  2572. changeUI('#ls-Pvt-Lock-Down', 0, 'lock', null);
  2573. changeUI('#ls-Pvt-High-Quan', 1, 'text', '--');
  2574. pvtHigh = 0;
  2575. if (pvtLow === 0) changeUI('#icon-Lock-Pvt', 0, 'lock', null);
  2576. });
  2577. }
  2578. }
  2579. if (pvtLow > 0) {
  2580. changeUI('#ls-Pvt-Low-Quan', 1, 'text', pvtLow);
  2581. if (roadClear) {
  2582. changeUI('#ls-Pvt-Lock-Up', 1, 'lock', 'low');
  2583. $('#ls-Pvt-Lock-Up').click(() => {
  2584. for (let i = 0; i < badLockSegs.pvt.length; i++) {
  2585. const aryData = badLockSegs.pvt[i];
  2586. const seg = W.model.segments.getObjectById(aryData.segID);
  2587. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2588. }
  2589. changeUI('#ls-Pvt-Lock-Up', 0, 'lock', null);
  2590. changeUI('#ls-Pvt-Low-Quan', 1, 'text', '--');
  2591. pvtLow = 0;
  2592. if (pvtHigh === 0) changeUI('#icon-Lock-Pvt', 0, 'lock', null);
  2593. });
  2594. }
  2595. }
  2596. }
  2597. }
  2598. if (value === 'rail') {
  2599. for (let i = 0; i < key.length; i++) {
  2600. if (key[i].lockError === 'high') railHigh++;
  2601. if (key[i].lockError === 'low') railLow++;
  2602. }
  2603. if (railHigh > 0 || railLow > 0) {
  2604. if (roadClear) {
  2605. changeUI('#icon-Lock-Rail', 1, 'lock', 'both');
  2606. $('#icon-Lock-Rail').click(() => {
  2607. for (let i = 0; i < badLockSegs.rail.length; i++) {
  2608. const aryData = badLockSegs.rail[i];
  2609. const seg = W.model.segments.getObjectById(aryData.segID);
  2610. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2611. }
  2612. changeUI('#icon-Lock-Rail', 0, 'lock', null);
  2613. changeUI('#ls-Rail-Lock-Up', 0, 'lock', null);
  2614. changeUI('#ls-Rail-Lock-Down', 0, 'lock', null);
  2615. changeUI('#ls-Rail-Low-Quan', 1, 'text', '--');
  2616. changeUI('#ls-Rail-High-Quan', 1, 'text', '--');
  2617. });
  2618. }
  2619. if (railHigh > 0) {
  2620. changeUI('#ls-Rail-High-Quan', 1, 'text', railHigh);
  2621. if (roadClear) {
  2622. changeUI('#ls-Rail-Lock-Down', 1, 'lock', 'high');
  2623. $('#ls-Rail-Lock-Down').click(() => {
  2624. for (let i = 0; i < badLockSegs.rail.length; i++) {
  2625. const aryData = badLockSegs.rail[i];
  2626. const seg = W.model.segments.getObjectById(aryData.segID);
  2627. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2628. }
  2629. changeUI('#ls-Rail-Lock-Down', 0, 'lock', null);
  2630. changeUI('#ls-Rail-High-Quan', 1, 'text', '--');
  2631. railHigh = 0;
  2632. if (railLow === 0) changeUI('#icon-Lock-Rail', 0, 'lock', null);
  2633. });
  2634. }
  2635. }
  2636. if (railLow > 0) {
  2637. changeUI('#ls-Rail-Low-Quan', 1, 'text', railLow);
  2638. if (roadClear) {
  2639. changeUI('#ls-Rail-Lock-Up', 1, 'lock', 'low');
  2640. $('#ls-Rail-Lock-Up').click(() => {
  2641. for (let i = 0; i < badLockSegs.rail.length; i++) {
  2642. const aryData = badLockSegs.rail[i];
  2643. const seg = W.model.segments.getObjectById(aryData.segID);
  2644. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2645. }
  2646. changeUI('#ls-Rail-Lock-Up', 0, 'lock', null);
  2647. changeUI('#ls-Rail-Low-Quan', 1, 'text', '--');
  2648. railLow = 0;
  2649. if (railHigh === 0) changeUI('#icon-Lock-Rail', 0, 'lock', null);
  2650. });
  2651. }
  2652. }
  2653. }
  2654. }
  2655. if (value === 'fry') {
  2656. for (let i = 0; i < key.length; i++) {
  2657. if (key[i].lockError === 'high') fryHigh++;
  2658. if (key[i].lockError === 'low') fryLow++;
  2659. }
  2660. if (fryHigh > 0 || fryLow > 0) {
  2661. if (roadClear) {
  2662. changeUI('#icon-Lock-Fry', 1, 'lock', 'both');
  2663. $('#icon-Lock-Fry').click(() => {
  2664. for (let i = 0; i < badLockSegs.fry.length; i++) {
  2665. const aryData = badLockSegs.fry[i];
  2666. const seg = W.model.segments.getObjectById(aryData.segID);
  2667. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2668. }
  2669. changeUI('#icon-Lock-Fry', 0, 'lock', null);
  2670. changeUI('#ls-Fry-Lock-Up', 0, 'lock', null);
  2671. changeUI('#ls-Fry-Lock-Down', 0, 'lock', null);
  2672. changeUI('#ls-Fry-Low-Quan', 1, 'text', '--');
  2673. changeUI('#ls-Fry-High-Quan', 1, 'text', '--');
  2674. });
  2675. }
  2676. if (fryHigh > 0) {
  2677. changeUI('#ls-Fry-High-Quan', 1, 'text', fryHigh);
  2678.  
  2679. if (roadClear) {
  2680. changeUI('#ls-Fry-Lock-Down', 1, 'lock', 'high');
  2681. $('#ls-Fry-Lock-Down').click(() => {
  2682. for (let i = 0; i < badLockSegs.fry.length; i++) {
  2683. const aryData = badLockSegs.fry[i];
  2684. const seg = W.model.segments.getObjectById(aryData.segID);
  2685. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2686. }
  2687. changeUI('#ls-Fry-Lock-Down', 0, 'lock', null);
  2688. changeUI('#ls-Fry-High-Quan', 1, 'text', '--');
  2689. fryHigh = 0;
  2690. if (fryLow === 0) changeUI('#icon-Lock-Fry', 0, 'lock', null);
  2691. });
  2692. }
  2693. }
  2694. if (fryLow > 0) {
  2695. changeUI('#ls-Fry-Low-Quan', 1, 'text', fryLow);
  2696.  
  2697. if (roadClear) {
  2698. changeUI('#ls-Fry-Lock-Up', 1, 'lock', 'low');
  2699. $('#ls-Fry-Lock-Up').click(() => {
  2700. for (let i = 0; i < badLockSegs.fry.length; i++) {
  2701. const aryData = badLockSegs.fry[i];
  2702. const seg = W.model.segments.getObjectById(aryData.segID);
  2703. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2704. }
  2705. changeUI('#ls-Fry-Lock-Up', 0, 'lock', null);
  2706. changeUI('#ls-Fry-Low-Quan', 1, 'text', '--');
  2707. fryLow = 0;
  2708. if (fryHigh === 0) changeUI('#icon-Lock-Fry', 0, 'lock', null);
  2709. });
  2710. }
  2711. }
  2712. }
  2713. }
  2714. if (value === 'rnwy') {
  2715. for (let i = 0; i < key.length; i++) {
  2716. if (key[i].lockError === 'high') rnwyHigh++;
  2717. if (key[i].lockError === 'low') rnwyLow++;
  2718. }
  2719. if (rnwyHigh > 0 || rnwyLow > 0) {
  2720. if (roadClear) {
  2721. changeUI('#icon-Lock-Rnwy', 1, 'lock', 'both');
  2722. $('#icon-Lock-Rnwy').click(() => {
  2723. for (let i = 0; i < badLockSegs.rnwy.length; i++) {
  2724. const aryData = badLockSegs.rnwy[i];
  2725. const seg = W.model.segments.getObjectById(aryData.segID);
  2726. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2727. }
  2728. changeUI('#icon-Lock-Rnwy', 0, 'lock', null);
  2729. changeUI('#ls-Rnwy-Lock-Up', 0, 'lock', null);
  2730. changeUI('#ls-Rnwy-Lock-Down', 0, 'lock', null);
  2731. changeUI('#ls-Rnwy-Low-Quan', 1, 'text', '--');
  2732. changeUI('#ls-Rnwy-High-Quan', 1, 'text', '--');
  2733. });
  2734. }
  2735. if (rnwyHigh > 0) {
  2736. changeUI('#ls-Rnwy-High-Quan', 1, 'text', rnwyHigh);
  2737.  
  2738. if (roadClear) {
  2739. changeUI('#ls-Rnwy-Lock-Down', 1, 'lock', 'high');
  2740. $('#ls-Rnwy-Lock-Down').click(() => {
  2741. for (let i = 0; i < badLockSegs.rnwy.length; i++) {
  2742. const aryData = badLockSegs.rnwy[i];
  2743. const seg = W.model.segments.getObjectById(aryData.segID);
  2744. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2745. }
  2746. changeUI('#ls-Rnwy-Lock-Down', 0, 'lock', null);
  2747. changeUI('#ls-Rnwy-High-Quan', 1, 'text', '--');
  2748. rnwyHigh = 0;
  2749. if (rnwyLow === 0) changeUI('#icon-Lock-Rnwy', 0, 'lock', null);
  2750. });
  2751. }
  2752. }
  2753. if (rnwyLow > 0) {
  2754. changeUI('#ls-Rnwy-Low-Quan', 1, 'text', rnwyLow);
  2755.  
  2756. if (roadClear) {
  2757. changeUI('#ls-Rnwy-Lock-Up', 1, 'lock', 'low');
  2758. $('#ls-Rnwy-Lock-Up').click(() => {
  2759. for (let i = 0; i < badLockSegs.rnwy.length; i++) {
  2760. const aryData = badLockSegs.rnwy[i];
  2761. const seg = W.model.segments.getObjectById(aryData.segID);
  2762. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2763. }
  2764. changeUI('#ls-Rnwy-Lock-Up', 0, 'lock', null);
  2765. changeUI('#ls-Rnwy-Low-Quan', 1, 'text', '--');
  2766. rnwyLow = 0;
  2767. if (rnwyHigh === 0) changeUI('#icon-Lock-Rnwy', 0, 'lock', null);
  2768. });
  2769. }
  2770. }
  2771. }
  2772. }
  2773. if (value === 'ofrd') {
  2774. for (let i = 0; i < key.length; i++) {
  2775. if (key[i].lockError === 'high') ofrdHigh++;
  2776. if (key[i].lockError === 'low') ofrdLow++;
  2777. }
  2778. if (ofrdHigh > 0 || ofrdLow > 0) {
  2779. if (roadClear) {
  2780. changeUI('#icon-Lock-Ofrd', 1, 'lock', 'both');
  2781. $('#icon-Lock-Ofrd').click(() => {
  2782. for (let i = 0; i < badLockSegs.ofrd.length; i++) {
  2783. const aryData = badLockSegs.ofrd[i];
  2784. const seg = W.model.segments.getObjectById(aryData.segID);
  2785. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2786. }
  2787. changeUI('#icon-Lock-Ofrd', 0, 'lock', null);
  2788. changeUI('#ls-Ofrd-Lock-Up', 0, 'lock', null);
  2789. changeUI('#ls-Ofrd-Lock-Down', 0, 'lock', null);
  2790. changeUI('#ls-Ofrd-Low-Quan', 1, 'text', '--');
  2791. changeUI('#ls-Ofrd-High-Quan', 1, 'text', '--');
  2792. });
  2793. }
  2794. if (ofrdHigh > 0) {
  2795. changeUI('#ls-Ofrd-High-Quan', 1, 'text', ofrdHigh);
  2796.  
  2797. if (roadClear) {
  2798. changeUI('#ls-Ofrd-Lock-Down', 1, 'lock', 'high');
  2799. $('#ls-Ofrd-Lock-Down').click(() => {
  2800. for (let i = 0; i < badLockSegs.ofrd.length; i++) {
  2801. const aryData = badLockSegs.ofrd[i];
  2802. const seg = W.model.segments.getObjectById(aryData.segID);
  2803. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2804. }
  2805. changeUI('#ls-Ofrd-Lock-Down', 0, 'lock', null);
  2806. changeUI('#ls-Ofrd-High-Quan', 1, 'text', '--');
  2807. ofrdHigh = 0;
  2808. if (ofrdLow === 0) changeUI('#icon-Lock-Ofrd', 0, 'lock', null);
  2809. });
  2810. }
  2811. }
  2812. if (ofrdLow > 0) {
  2813. changeUI('#ls-Ofrd-Low-Quan', 1, 'text', ofrdLow);
  2814.  
  2815. if (roadClear) {
  2816. changeUI('#ls-Ofrd-Lock-Up', 1, 'lock', 'low');
  2817. $('#ls-Ofrd-Lock-Up').click(() => {
  2818. for (let i = 0; i < badLockSegs.ofrd.length; i++) {
  2819. const aryData = badLockSegs.ofrd[i];
  2820. const seg = W.model.segments.getObjectById(aryData.segID);
  2821. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2822. }
  2823. changeUI('#ls-Ofrd-Lock-Up', 0, 'lock', null);
  2824. changeUI('#ls-Ofrd-Low-Quan', 1, 'text', '--');
  2825. ofrdLow = 0;
  2826. if (ofrdHigh === 0) changeUI('#icon-Lock-Ofrd', 0, 'lock', null);
  2827. });
  2828. }
  2829. }
  2830. }
  2831. }
  2832. if (value === 'nrpd') {
  2833. for (let i = 0; i < key.length; i++) {
  2834. if (key[i].lockError === 'high') nrpdHigh++;
  2835. if (key[i].lockError === 'low') nrpdLow++;
  2836. }
  2837. if (nrpdHigh > 0 || nrpdLow > 0) {
  2838. if (roadClear) {
  2839. changeUI('#icon-Lock-Nonped', 1, 'lock', 'both');
  2840. $('#icon-Lock-Nonped').click(() => {
  2841. for (let i = 0; i < badLockSegs.nrpd.length; i++) {
  2842. const aryData = badLockSegs.nrpd[i];
  2843. const seg = W.model.segments.getObjectById(aryData.segID);
  2844. processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2845. }
  2846. changeUI('#icon-Lock-Nonped', 0, 'lock', null);
  2847. changeUI('#ls-Nonped-Lock-Up', 0, 'lock', null);
  2848. changeUI('#ls-Nonped-Lock-Down', 0, 'lock', null);
  2849. changeUI('#ls-Nonped-Low-Quan', 1, 'text', '--');
  2850. changeUI('#ls-Nonped-High-Quan', 1, 'text', '--');
  2851. });
  2852. }
  2853. if (nrpdHigh > 0) {
  2854. changeUI('#ls-Nonped-High-Quan', 1, 'text', nrpdHigh);
  2855.  
  2856. if (roadClear) {
  2857. changeUI('#ls-Nonped-Lock-Down', 1, 'lock', 'high');
  2858. $('#ls-Nonped-Lock-Down').click(() => {
  2859. for (let i = 0; i < badLockSegs.nrpd.length; i++) {
  2860. const aryData = badLockSegs.nrpd[i];
  2861. const seg = W.model.segments.getObjectById(aryData.segID);
  2862. if (aryData.lockError === 'high') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2863. }
  2864. changeUI('#ls-Nonped-Lock-Down', 0, 'lock', null);
  2865. changeUI('#ls-Nonped-High-Quan', 1, 'text', '--');
  2866. nrpdHigh = 0;
  2867. if (nrpdLow === 0) changeUI('#icon-Lock-Nonped', 0, 'lock', null);
  2868. });
  2869. }
  2870. }
  2871. if (nrpdLow > 0) {
  2872. changeUI('#ls-Nonped-Low-Quan', 1, 'text', nrpdLow);
  2873.  
  2874. if (roadClear) {
  2875. changeUI('#ls-Nonped-Lock-Up', 1, 'lock', 'low');
  2876. $('#ls-Nonped-Lock-Up').click(() => {
  2877. for (let i = 0; i < badLockSegs.nrpd.length; i++) {
  2878. const aryData = badLockSegs.nrpd[i];
  2879. const seg = W.model.segments.getObjectById(aryData.segID);
  2880. if (aryData.lockError === 'low') processLocks(seg, aryData.currLockRnk, aryData.stdLockRnk);
  2881. }
  2882. changeUI('#ls-Nonped-Lock-Up', 0, 'lock', null);
  2883. changeUI('#ls-Nonped-Low-Quan', 1, 'text', '--');
  2884. nrpdLow = 0;
  2885. if (nrpdHigh === 0) changeUI('#icon-Lock-Nonped', 0, 'lock', null);
  2886. });
  2887. }
  2888. }
  2889. }
  2890. }
  2891. });
  2892.  
  2893. let isActiveTab = $("a[href$='#sidepanel-ls']").parent().prop('class');
  2894. if (isActiveTab === '' || isActiveTab !== 'active') $("a[href$='#sidepanel-ls']").css('background-color', '#ed503bb5');
  2895. } else {
  2896. if (manual) WazeWrap.Alerts.info(GM_info.script.name, 'No segments out of standards');
  2897. }
  2898. }
  2899. }
  2900.  
  2901. Locksmithbootstrap();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址