您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds filtering and pop-up infobox for UR, MP and camera markers
当前为
- // ==UserScript==
- // @name UROverview Plus (URO+)
- // @namespace http://greasemonkey.chizzum.com
- // @description Adds filtering and pop-up infobox for UR, MP and camera markers
- // @include https://www.waze.com/*/editor/*
- // @include https://www.waze.com/editor/*
- // @include https://editor-beta.waze.com/*
- // @include https://beta.waze.com/*
- // @exclude https://www.waze.com/user/*editor/*
- // @exclude https://www.waze.com/*/user/*editor/*
- // @grant none
- // @version 3.98
- // ==/UserScript==
- /*
- TO-DO ITEMS
- =======================================================================================================================
- Bug fixes - MUST BE CLEARED BEFORE RELEASE
- =======================================================================================================================
- =======================================================================================================================
- Things to be checked
- =======================================================================================================================
- =======================================================================================================================
- Proposed functionality
- =======================================================================================================================
- Adjust default settings for places & MP tabs to account for dynamic nature of tab building
- Restore custom icon functionality
- Convert camera XHR code to async operation
- "Hide All" button for feed - automatically clicks the trashcan on all visible feed entries
- Allow custom alert box to be used as a confirm() replacement as well
- Improve reliability of yellow/green comment marker choice
- Implement some sort of UR "hotspot" marking to highlight areas of the map with significant clustering of URs
- Flush settings to localStorage whenever a change is made, or at least before opening a new tab via a popup
- User-defined setting presets
- Extend unstacking to cameras
- Place filtering
- - by last user to edit
- More localisation
- First-run information
- - show quickstart guide to URO features if no existing settings are present (i.e. new installation)
- =======================================================================================================================
- New functionality in progress
- =======================================================================================================================
- Addition of segment and place watchlist functionality
- */
- /* JSHint Directives */
- /* globals $: */
- /* globals W: true */
- /* globals I18n: */
- /* globals OL: true */
- /* globals OpenLayers: true */
- /* globals Waze: true */
- /* globals require: */
- /* jshint bitwise: false */
- /* jshint eqnull: true */
- var uroVersion = "3.98";
- var uroReleaseDate = "20170309";
- // list of changes affecting all users
- var uroChanges =
- [
- "Fix for missing segment popup in Firefox when certain segment address details were missing",
- "Fix for console errors when something other than a UR editing panel is opened",
- "Popups auto-hide when the map comments dropdown menu is accessed",
- "Inhibits speed limit validation on private and parking segments",
- "MP filter list now auto-generated based on whatever MP types are present in WME",
- "Popups now enabled for map comments"
- ];
- // list of changes affecting only WME Beta users (at least until the next production release including these parts of the beta code...)
- var uroBetaChanges =
- [
- "Compatibility fixes"
- ];
- // true enables debug output during script startup
- var uroShowDebugOutput = true;
- // true keeps debug output enabled after script startup
- var uroPersistentDebugOutput = false;
- /*
- var uroRecentDebug = [];
- */
- var uroCtrlsHidden = false;
- var uroCurrentTab = 1;
- var uroFID = -1;
- var uroShownFID = -1;
- var uroShownPopupType = null;
- var uroInhibitSave = true;
- var uroPopupTimer = -2;
- var uroPopupDwellTimer = -1;
- var uroPopupShown = false;
- var uroPopupSuppressed = false;
- var uroSetupListeners = true;
- var uroRootContainer = null;
- var uroPlacesRoot = null;
- var uroConfirmIntercepted = false;
- var uroCustomMarkerList = [];
- var uroPendingURSessionIDs = [];
- var uroRequestedURSessionIDs = [];
- var uroPlacesGroupsCollapsed = [];
- var uroKnownProblemTypeIDs = [];
- var uroKnownProblemTypeNames = [];
- var uroMouseInPopup = false;
- var uroURControlsIdx = null;
- var uroProblemControlsIdx = null;
- var uroTurnsLayerIdx = null;
- var uroMCLayerIdx = null;
- var uroNullCamLayer = false;
- var uroNullOpenLayers = false;
- var uroNullURLayer = false;
- var uroNullProblemLayer = false;
- var uroNullMapViewport = false;
- var uroURDialogIsOpen = false;
- var uroHoveredURID = null;
- var uroSelectedURID = null;
- var uroURReclickAttempts = 0;
- var uroPendingCommentDataRefresh = false;
- var uroWaitingCommentDataRefresh = false;
- var uroExpectedCommentCount = null;
- var uroCachedLastCommentID = null;
- var uroMCSelected = false;
- var uroPlaceSelected = false;
- var uroAutoCentreDisabledOn = [];
- var uroMouseIsDown = false;
- var uroBackfilling = false;
- var uroHidePopupOnPanelOpen = false;
- var uroUserID = -1;
- var uroURIDInURL = null;
- var uroDOMHasTurnProblems = false;
- var uroBetaEditor = false;
- var uroWazeBitsPresent = 0;
- var uroMTEMode = false;
- var uroFinalisingListenerSetup = false;
- var uroInitialised = false;
- var uroOWL = null;
- var uroDiv = null;
- var uroAlerts = null;
- var uroControls = null;
- var uroCtrlURs = null;
- var uroCtrlMPs = null;
- var uroCtrlPlaces = null;
- var uroCtrlCameras = null;
- var uroCtrlMisc = null;
- var uroCtrlHides = null;
- var uroAMList = [];
- var uroCWLGroups = [];
- var uroCamWatchObjects = [];
- var uroSegWatchObjects = [];
- var uroPlaceWatchObjects = [];
- var uroFriendlyAreaNames = [];
- var uroAreaNameHoverTime = -1;
- var uroAreaNameHoverObj = null;
- var uroAreaNameOverlayShown = false;
- var uroANEditHovered = false;
- var uroANEditBox = null;
- var uroPrevMouseX = -1;
- var uroPrevMouseY = -1;
- var dteControlsIdx = -1;
- var dteOldestFullDrive = new Date(0);
- var dteEpoch = new Date(0);
- var dteTopID = '';
- var dteClearHighlightsOnPanelClose = false;
- var dteArmClearHighlightsOnPanelClose = false;
- var dteOffset = 0;
- var uroUserTabId = '';
- var uroShowFeedFilter = false;
- var uroTBRObj = null;
- var uroBackfillQueue = [];
- var uroUnstackedMasterID = null;
- var uroStackList = [];
- var uroStackType = null;
- var uroMousedOverMarkerID = null;
- var uroMousedOverMarkerType = null;
- var uroClickedOnMarkerID = null;
- var uroClickedOnMarkerType = null;
- var uroAlertBoxStack = [];
- var uroAlertBoxTickAction = null;
- var uroAlertBoxCrossAction = null;
- var uroAlertBoxInUse = false;
- var uroNativeMarkerImage = 'problems-sc703e224cf.png';
- var uroCustomURTags = ['[ROADWORKS]','[CONSTRUCTION]','[CLOSURE]','[EVENT]','[NOTE]','[WSLM]','[BOG]','[DIFFICULT]'];
- var uroAltMarkers =
- [
- // 0 = closure
- "url('data:image/png;base64,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')",
- // 1 = cone
- "url('data:image/png;base64,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')",
- // 2 = custom text
- "url('data:image/png;base64,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')",
- // 3 = editor note
- "url('data:image/png;base64,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')",
- // 4 = event
- "url('data:image/png;base64,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')",
- // 5 = wslm & native SL URs
- "url('data:image/png;base64,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')",
- // 6 = Elgin
- "url('data:image/png;base64,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')",
- // 7 = TrafficCast
- "url('data:image/png;base64,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')",
- // 8 = TrafficMaster
- "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAKrCAYAAAB/UOT4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AQYFhUp1xHJKAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAABmJLR0QAAADNAABgNL5sAAAi70lEQVR42u18CXBU55XuuUvf23urtaAVgQRiNyAWi2CIDRi8TBjsivOSyWRmkuekJlPJLMVUeV5NTVUqL+9NVapmSSWTSlXsOJk43jH4jcvB2I4J4NgGhIFgQICQBEK70NaLuvv2vfd95291g0BiMfa8V+/9p+tye7v3P//5z3+Wrz9BJEWKFClSpEiRIkWKFCn/H4jyMa5R+br77rtPicVihetDoZD729/+1sVTPpxPWgllYlAe3KisrPQoiuKNx+Oa67pKKpVSWAHHcVxd1y3TNDN9fX1WNpvNQCl7Qqkbin4zBR5++GF9ZGTEV1tbGygtLS32+/1lqqqWWJYVsG1bw2Dk8XhcvJfBOYlrhmtqagbHxsaGLl26NBqJRNJHjhxxbqTMtJbAzDXDMMyqqqpIUVFROW5Wh5svmzNnzkZYYmEikYhkMhkdFlDwPdfn81nBYHDUtjNnz5w598bp0y3NsNYFWKW/t7c3tmTJkuyTTz7p3LISK1eu1GF2nnkZZA5eb6yoqHjIMDyVjY0rQjC5CUUo62RIV40pJ3Hk2OFD51rO7zx69OjBs2fPtsJqI93d3ckJq0wSbQoFNMw4NHv27JlQonHjxo3fhhW2NjYuL62urgnpHsWjaZ6chyratOsYjvhDc+ob5pWUlJbDIiNYvhSWMrtu3ToLirjTKsHOF41GA1CiFseae++99wms+bLPfOYzJszthQFUTdVvzeN13TR0w4sJlHq93obR0dHLsMY4ljFZUlKS6ejomFIJZXx83FtfXz8DsnzLli3bseYN0NwLBTRNyw2OGxFmJQ58Xnh+7WFbNn/XwIU+DBoeGBhYNDg42IFrRnp6euJdXV32tbtDeeihh/h5EZyrDgr8GW7ACojlh+eLwREXqLm5mQ4fPkIXLlwk3Fi8X5jF1G5u4vpiTMRcsmTR47DIIJZ6GIpZu3fvdgpKcODp7+/34cPSu+++ez3Mt7axsdGE16usACyEgZvpmWeeJcyGDEMj03QpHFbg2TrZjgKraISwAUWu34mIJx74A1tk+cKFC1cfO3asPZ1Ox/BRuqAEgoq2ePFiH75Yjq30uYnZw5IaJZNJ2rHjFdq5cxd5vSbNmEFUVh6jOXOHKBTOkAsFhoa8dL61mIYGfRSPe66zCJQgBDIPfCuNCT167ty5/ViybnyU4Y9ZCeWee+7RseVC8+bNW4jZV9bV1XlxEXEgevXV/0W7dr1KwaCXZteP0IYtHVRanaThpI8sWxV7vMITp6YNXXTxbIT2vj2beruD11kDgUydOXOmr7W1tQb3n4/Y0YJlj7/55puuiqVgR/IUFxdHoOkmWMGD9fNAGeXEiY+EBbAxaMnSfnrsT06RG1KodziUM7+tkINjPOWhvrEQhWoy9MU/PUl19cPwFeUqX1GQW4IkTIuXa9asWQ+rB6CY2BgqlkKBc+n4PAKnXDZr1qwAfEJY4fnnX2QzUmVVjB7Ydp564yFCgJxy3RVEZSurUYJMeuiRVopGU2KpeCkwIZo1a7Y4wwoadt9c3DeK0K5jPEXF7BWefTgcLsJ6RfEh70eV93Fb23lSoeumze10OeVH+rxpLhJOmtY9dN/GDiilivd48Nmza9kSCmbvwaQjsEQJxvUhLSgqMiDPmn0jiD2ssOZsvuPHjwsrBIIWVdXHxc1vOTWrLlXVxeDIWViClfBQbe0sgrPz/VkJL86lyDsBjK+rPDBvRQzswZuFTX/pUpfw8urqGI1Dx9spPDANclSFKiqgvM1OyZaYlfcPHenfi7Mf4/o5CbK9XK4H2EzQ1GFL8IH1Ehf5fYiAtnZ7ZQ9mb7uauJbjTDRahLhi5vINXmMoL+sD31PFW5yGuRLCGzbXA1AgKxJQOCwuiicMMvTs7ZVrMJuuOLjWk3fGaz5X+P2MzXEd46scivHEgtOk8HkS5kljyzooYsR69vQEyVRsYeLbWpCsS719AfiFTvX1OSVwb5ezKSbLySyB5xbGd9T333/fhWZZ+MMolqDn4sWLFtaMli69C9sRs4kZ1Hk+TOYtWoOtoEL7C7gmldTEMixatEgsMSc8REsu/85y5YVonMH4jjpRdqWxQy63tLR8BM0sfJidObPGnTt3Lva6Q/v3ziIvVkmF199sk2qqQ3ZcofcOzCSfX6UFC+YTcgbxxHDYXIv+DoLcwTVGEsHSFhsZ/mDhNDA0NHQGH/ajNkwiZthf/OIXxPp1XgzT/jdxU9civ5kVS8PJKl9a83NeLb9pkRsn2vfmLEI+JARh2rZtm7AozO9ikik45gVYuwUKDcFKKVRujnB7ZFC3vLzc4ZoSSgQQwmdjxxgobBBJdYTv31NfX4QSIwb5vRkqL4tTIGBh1i6Zhk1hX5q0rEMdp4vog33V1NISRZg26Mtf/hItX76McE/OxBkc4zt27HjywoULR1Hq9WApkqdOnXL0vBIYNAnzdODDZjhlPSywasldprl16+dUXs9XXtlFHx4ppn44W1l5kqKlKfJDEQ7j7DfDA17q6/FTb6+HSsv89Ed/9CVCZSbKABxZDJaCL7xz/vz5E1juPuSnBAfYSZXVhx9+6KCeyHIBgQyXRqFbc771fDEqLR1pXqmurkZRM0JnzgxSd5ePeroC1H0xSBfbgtTWGsCSGXA8ndbeswoW+DI1NTXBAikuhBwUQlw3nHjxxRefQz3Sghai7+DBg+l8GzApCsEConSH5hYschkKVGD9wqi0VWwzlb0c1REcLQI/CsAXTFijhNiB165dTY8+ug0F0r00u242nDBB48lU9qOPPkriXuO/+tWvfon68gjm2IVzDCWePWXzg7XLYmlGoEg7x3leLyjy8K5du1YGAoEwZqhVV1eK7ctm5i3HHsnFDhIS/CRwVVZV7D179nBDdAo1xM+Qh05i8G5cE8PS29NW25w54Yw2R09s2RQskEC5PgAv5uBS3d7eHv7gg4OEzIsiJ0iopHGExeAcGfPy1lsv0aFDJ4ZQTz6FHbHj5MmTp7DEl+BnIzxX+Iqzb9++6fsOVgSD23CeNEI3O+soLIR79J7G+nZAwXlYV5OjIC9o1s2Qplwx6M9//t/T8XjgBZj7BdSS3PicgwV6sCVjmEya+1Mo4E7bi3KDC3EnGtkUnnNsT2N5RqDYEEyJ1eq/hGi3fcOGDRHcVFMVs1BHotsaHxuL/Ftz89sfYhIdsETv5cuXR9BGptDwWN/5znfynfv0DbGSK5kKSQIzZyWSmIkN09u4aQqBZxzf+8mJEye+vWrVqkj+u4cPH+ZI+NI777zTjO+1ssKwYBwTSKM1EKX9d7/73Xzr6d6oDVS+8IUvqHBID4KXgaBlYECeqgc3UmEBjesOnLlCUjFbJMg6z/79+7PDw8OHn3322dfhQ5fgP2NwbN5lXBhpaCc1bHkd/qZiMgruNa0SjEFoCCgmquIA2sEQbhSBmcO4UQTP+RyEJfxwWj++Zzc0NFRjwFL4zdAPf/jDl7jVw/d5GTkdcOvo4+/CKj5+DcvqXL8uX77cxY5xpooTXFfqCFh+zLIIF0exFFGk+CgGieLGRTiz+UNQpBqmLobXD6FyLkPLfwD5JjNRJnItqUOZAA6u/QPcCqqidDEYbnBwrY1i14HzutdCAxq2Hps/hCPKSkAZvokPg/MNGKHRMCsPbj6LLYPv+GAdHWfo5bAF4njZj8+GuTjC4Fm8x2VDGtcnsDxjuOcwno/CKgk4K9cHrnINFuVB/+nn2ULbEC7wMzQ0UZxyg6RxWOczv+b15udcBOE7Ng/KZz7wvsP68S7GvTJ4bxzfS0DhMTxPwIqpidzhXr07XDhlFk4zzvEeF/LWNBDneR25/uSBVW6AcXOVD3xFyW9rbFd+4uJzBwO5uMblCMwlHD4TFsHBVVt6ov0r+IQyFUjGQAn2t4ZihFsCLgE1nBXcnBslZQIiuK7egyUKXg/TO/wayjjshAj/DnaVzfXDtYCachMsS5nYtgwDTIIMbyZ5SJGvffnll90rdfj1xdnHxjEfeOABBTGhcD1yiYuE9enimBiUHdJAXVHAMdkZGMdkBbh8y+OY2Hq8IzJQ6pPBMR955BEda+lDZCzgmBhM4JhwygKOyc7GfQu2qsAx4dACx0QSTHNF/bFwzC1btmhwKhM3FDgmDoFjIpgJHBOOF+HgxDgmK8HFMhQUOGZra9sbLS1nmqG8wDFR1MRQEGV//OMf3zqOiaClw+wBRLUyHHMaGxs3IpcIHHPx4iUcPyZwzCzp06B5J04dP9R2rmMnGuuDZ86caYXlRriKn7DKjXFMKKChzBM4JrZTIwqQb8OkWxcvXlRaUVEZ4u4+j+Spijr97gj7Q7Nr6+Zhm5cj0QkcE8VP9rOf/ax16NCh6bPo/fffryJzBpDAoEftmvXr1z8Bcy9bsWIF/M3rzQFpt9YcK5pmejSPFxMoxTI1YHtfxvKNw6GT8K1MW1vb1FkUEc6LzDgDBczyTZs2bYf2DatXr2YQdQLpyRUv7IwcOfPnaw9+37GdAo4Jfwoj1S9CACzgmCigr8cxt27dyrmgCJrXwSJ/BguwAibWv4BjciuH6Id+8jx6lQHCjQs4JivH8EZeCQZUJ84m7lWMe5sLFswTOCai5zBKBeu11167gmNiUAV1ow8flqJaEjgmeg2T8wMrwB3UuXOtKGDfptHRMUJKQYWtoM0zhGczigP9oICLwyqgvqzEBOrrwT0LOCZ6nHZuyCfhmG+//baGHeBD0CnHVpqEY/Ls3333Xdq7dx9CcYDKyz3owNJUWTWKKjsrEnE87kNDFKbhIRMloUf0r67rCOvwPWw7y9W4BzkpDSe9DscUkB52gAEFStE1fWbOnDkPwinDjGdzhjxwgBXYS+FwgOrqU7RmfRvNXdBD3ohKHiR9I+CiJYzjsy4qK01SPBGgZMIQCnB8QhMuLIP7K/ffv4lLRBON9+/hH22wfBLVuKtiKQo45t133y1wTE7dWAqlra0dVvoNzO+j+QuG6Z4NJ0jx6RRLlcLxsBSoBPhAbUPxdAn5ojatu+8kzayNwRq6gIbyx9U4JkPXk3BMLAXXBALHxD5exkGKgQ3Wfs+eNxGSdSqvSFJj01kaTZVghpoAQnJlpMp7UZyRWOAbHtg3QCvx3aIiC/6iiu9yXYldLxokbH8ufAs4JtKBoiIWFHBMrL/AMdkbEWoJLTypmkKrVrdRwgphIEYmcg8eWOFZskJqTiFF4BYqWZqXGld0CHB1Ap8ibh854V2LYyIVTI9jYq2EU/nhfNHyMQEBXItLuW6+aaJJ+QmVHRXNGCPTzOGYbE1E2xvjmLwVr8Uxe3p6xY3LykYpY0+EE/Z44mOibMBrRmH4LJQSDyenFKxWCodF+YlyUKOqqsoCjokxJ+OYjCGhIbkOx2RUjwfwGhnKMpBOiIJiAPzr4rlrE6ON8H1x5tf8vjuhKF9jGLmuPRQKc7ov4JiwcAHHxBiqzjgi1+s453HMEMPR3GmzMvGERpqawvqaUCrLWUuUVk7OHQurkFMwpwgKbMw4Q1wNappKDLBci2PC+hnsyutxTOhSwDHRtokd0tPjQ4JJi5AsrOBYuRk7GbJdq3Dwa2Ehh5/jsLLU22fCAqxE1Y1xTDSxAsfEmwLHRM63ONTOnz8P65lFmFaptzMIM6YwAA9kiYFQ2OcUcia/dt2cEj2XAhQfc4RzIygVEt/58+cn4ZgYP4djwgI8+8vYEQUcE5nUZVQXGtHB92tIt5OwfEYMZjtpzB4HWyN/iNdIBThnk1k6fLCCdI8jgHUGU3hieRwThc3vUJmNICclN27cOBnHRBITOCb/kptOp+ytW/9AzKCj3UeH3q0hzY6RrsXhdFbuwKDisFmJDHnUBBRI0wcHqrCMOhzST5s2bSzgmMgZ1+GYSGo5HBPmETgm//6YxzER642qqiqkUU05efIj9B1hSie85PNmqLhohExvCg6G8k5Lk88TJ5iMutpDdPRgJZ1pCRED+Fu3fo6QNfNWyOAY37lz55Pt7e1Hsew9WIrrcUwoMAnHNKDU5s33Cxzz9dd305HmIPX3eZFFi6moOEM+P29NRSSs0UGT+nq91NurU7TYQ9u2/SEhR+SB1CyjuYxjwhonUF1NjWPyD+mI49xJF3DMjvaOYtSaOqothXfLFRzTpJ4uDHjJT53tfmo/76OODpXGUwqtXHWXgJKXLVsmcEwM6KB+mIRjohjqg19MjWPOmjVLlO4wm8AxoVRFZ2enwDFra2vUefPmYdc0UDQaQkj2iYTl9RbxdbRy5VJ66KEHaM2aJqqZWUPp1DiWIM1I7iQcE8MIHBPvTY1jstnyOCbHlDyOiTJM4JiPPfaYVlExgxYtWihwTN5y+R/aON0zlnlVbrHfeuutAo4JhzyJpRE4Ju51YxwT0c3GDQWOCWeF0okBDMKVcjWyari5+Qih9hTYJSc/PnjwfFhm2bt3JzU3nyzgmCdOnCjgmBwObgnHxOA2Bk9jf3MEHcXy9KJCPo317YCvzkNlZPL+V6boO5555h8FjtnV1fUCEzjQ+AgcE7EnxnDkx8YxMesCjskzQp+5HXVIhDuBq38PR7c1PjIS+rfm5jcLOObAwMAnh2MyHn0zHBMeX8AxYb1PB8fEzfn7HpynxDGxA16H4pcYl5I4psQxJY4pcUzJx5R8TMnHlHxMyceUfEzJx5R8TMnHlHxMyceUfEzJx5R8TMnHlHxMyceUOKbEMSWOKfmYko8p+ZiSjyn5mJKPKfmYko8p+ZiSjyn5mJKPKfmYko8p+Zj/l/Ixp8Ix/w/wMSfjmJKPKfmYEseUOKbEMSUfU/IxJR9T8jElH1PyMSUfU/IxJR9T8jElH1PyMSUfU/IxJR9T8jElH1PimBLHlDim5GNKPqbkY0o+puRjSj6m5GNKPqbkY0o+puRjSj6m5GNKPqbkY8r/H1P+/5iSjylxTIljShxT8jElH/PT42OuLbqn9FbWuTl96Jb5mMp0fEyYvwZrfRcKkMcx05Vfrfpq5IJ94ZYdeb13XbbNandfvvzyS3v27NmBMv8UHLkfSTH205/+1L5tPubm6s3BUXdUueon6JsqcTF7UY25MW2Pf8+i7aXbK+6Ij/nAzAd8Bf4cHiErRME0UgraJVtDf6rc2PnH3DG1sryyrGGkoeG2+Jj3b7n/TxN2om5b9TZvHpnxZX1Ul66jP+76Cg2cG6CRCyM03DNKTta5GR+TzqqtZqevq/62+Jiu1135V9G/8uukKzbafVbgf3b9Ix37zXH6sPcI6Whhdd2hSEgVuNQnysdELVm+aPGiB7rNbjWoBFXTNsmX8tH2U39LB36zn0zku+KgQ6Uz4p8iH3PBvEVZM1s8HB72+zN+mpGYQY+0baNjv/2QfIqHamffGR9zqbY0fFg9PD0fE6aKNN3dtMEyreBr9msGDKWtH1xPnc2XyOsatGjxx+djMkRkRgzyoGNz4crT8jG5nmQ+5r6ifdFeBV0t2lWn1SY03zSj7M74mKbXpMjMIvLbflrrX1t8Qz5majxV/JP0T3zDzrDalGkipxvOi9yw8f4742N6TS+FKoKkKZrAubJ29sZ8zBKtRBlTxygyVETKGNKm6dwxH1P1K2SFLVEE6Mxuvhkfk5HIpJIkrV+jdMJCS3jnfEzH49JP8bA4wnFrdyM+pqIqdr1S70ayEYrFYwIa/ST4mIGQn+JmjOJqnBVRDI8xiY+pX83HVD1qvN6tD9vjtmc8lFQ8hlrgY6Ys/daXA2bTJviYpmlQeU05KUbOljYeN+Rjwu8TDzoPJmup1lYjKmm6Qj29d8bHNBF3qczF8jjYN6ZIATfkYybGEv3amJa2VIuUKLzYhxiQuAM+5rhGaKXo372/pIyaIdiU9sf3j9yMj3kyEAs4A/pAttV/zglUB0hFFX8nfMyiuiJK+pPkaDlgXnXUm/Mxs+ns4F9k/iKeCVp2aH6I1LAmft+6XT7m4GUfFVUGqW95LyX8cXIxgV2Du+K3zMesKamp7Ql3G8e04/r8wCJ19OIQ9XSGb5mPeeZMlEIzDKreWEOvRndRCmGXfxv4pvbN+Cs7Xrl1PuYfKtsC+6J/a+6c84r2VfVrdOqd03Ti98X4boDKZkzPxxy4bFBxtZ9qNtTQCzOeJ9uwxc8z/3H5P8ba+tpuj485s3JmbdNAU/SNyje0llCLsqF6g6JrKvVdTFH3RR91d/oLfMz2tgD19/nIxnacu6KOitcX00slLwpfYCf/eefPkxppH4+P2VDXULkltiW0t2SvdsHsUJRyRVnUsJiilREKBOEvmo/McBFV1FdQ0bIw+Vf6aXfDbno//B5ljAzZip19evDp2ED3QOqO+Zjbj25fPh4ZD75cs8Po9r2hJkuTNIrEstRYKrbkUesoefHIeDKUMVPEDw190T+d/JdUTI+1fCJ8TK/hHTIzZtUaa42/bLjMOVZ6TE0E4so571k66zlLSTNJGAyVQhbxIOs81/MTZV3r5svxkfjTt8LHnCoMCuwKWc5ctmxZBDumHGm3Gs40B+l+QfGM4v+SnpUOfL/8+55B76CabwGKnCJHtRXrfxz9ForCup0wdzMseRrL2onZD+L6BCwwZX/6sfiYVYmqvzTLzaLKbKWhuRrSgoHiV8/+IP2vyZaRlqcO3CYfU7lBa6iiG2O0i6suEz1oGEpwDVBbXlm+6tEvPfrNjcbGkvxFu1O746cPn37lnbff+fW1fEwGR7Ak9lX4xCfAxxwdUwLegL49tL3mGd8z5t6xvanUaOr4c88+95/Lx8Sy2PMa5s38hxn/UIrXIz/60Y9e/k/HMRH7JY4pcUyJY06JY37ta19TkJAm4Zg/+9nPPl0c8ytf+Qr7geBjMv8B5i7wMfM4JgcopiQwjsm/CP/iF7+4JRzzZkooX//613Usg2/+/PkBrGcxmuYyKFHCLRzzMScclZ0yg/cFHxMKCBzz17/+teBjvvrqqx8Px8RaaoFAQPAxET3LcdSheV2G1wLHRLyI8Dbl3cFKcO/C+x/h4WxnZ9cbra3nBR8TAam/s7MztmDBguz3vve9W8cxt2zZojOCi/xRhmPOXXfdtRFWeAhxo3J+aH7plUW6vv3Lz7ct3Xqo82LXTuQhwcfkEh8FbhLWuTkfc9OmTVpdXV0Ih+BjIop+G2u+9YmSJ2r/2vzrwBXXnOK4+rc+L5W/FH15w7cqv2UyYpf/u3Lc3zpw4MD0WXTbtm0qYoPgYzKOuXr16idg7mWNZY3BVrc1T6+iIjxSSmpqJSYUOWgfVNuddu209/Six6OPV2AnFfiYWNbM6dOnp86ijBvMmzdP8DHXr1+/nf+se1X5Kl9+8DqljpY4S6jerqeoGxUNTVyJT7+4eN3utqsrIivKahI1DWiuBI6Jait+7tw5+7qgBEfkXFCKvL/w8499frvqVdc9WvxoOKbFROVUg0eT3USfH/08xQbiND44TokhtHe2e1Vl5lxFFM0KTs4EJZIb7kR9/ezj8I/vI+UfHh4eHnr++eev4JgPP/ywwDEbGhpKV6xYsR7rufLvI3/vRwWtWGj9qtwq+qeRf6b2jzro3Og5MhQP8e/zwYAmeLpM5EgjIzDjkP/aNk8MRT4TxB7LynjQ3Pmww5bD0quPHj16PR8THqs1NTWJvyuHIg8MegbVkBJSgygHytJl9Hfd/42OHv2QArqXwkjuxaVxqqwaIZ/XEVhDIoHuqzdKI8MeuorUfh2OiV0m+Jhnz57dj2Up4JjCzzdv3qyjlAvNnTd3UdbIFo8FxvwBO0C1yVr680t/TmeOnCaTcn9VvfazJ2n12uNUUj1M3miSzOJxKp/dT6vWHqGVd5+BgskCF9N1rywVsr66UF0YRlStwfafjzLP/9hjjwmN1QcffLDAx2xc3rjBMqzgbme34Vquds/IPdR9sps8DnOlBqhp3TFyUHGOJiMwtyoGQfUg/hwvloqQGUnRmnuOCSsxvyPH281x8fSgjpIsJHDMxsZGgWPm2cfqG2+8wSla4JjMx/wg/EG0h3p0J4k+utMmM+VStChGy1afouFUWKy7S9kJop+T498x1c21Bd8u5Zq0fNVpCgbHyc66ggpnoEcNzghSkV1Ea71rMd/iAo6JdKCo6IYYvRM4ZjqVLv5B+ge+AWdAXWWtomxvlrKZDDWuOEcxy0+KkxU3zXHs7InneWVy79mYeUbRaemyNspYTI11SNd08pf4BY7JD+Zjos64HseE2QSOWa6WK0PKEAVGguSO4QYei4rLhzHLCZpjXhGmuTHXjqzcIfh4E5/hdVHZEPwgg3sjHBgupX1pgdQYrsFgqhfjcZWewzG5RONSjetIvGnzTwtDeCj9CiXHUliKURrPKhODWigKs4KNyIPa+YGd3PMcAZAVs8UjGh2Fv9gCHnjKfYrG8XBgNVicIUSBYyLj6pwFJ+GYc5Q5biKbUMbiY2K/G55xsmw3R4MUaK0zEeVyNEjnuu2Id2xYhv+oXYdf2DoZXoOG9MvUj4fBUcbj8U78ijgZx2Q+pqIp8dnubIFjJv0J1NEOjcVVwcfMWB6xHCq2Kp+5v7mW2JP3D7SwpLgZGouJupOKZyDE67ntysFvIm4UcEwdIZT/KjL/d+WJjc7GZJrSQbQuOmPU3T0+DMusQz+pTs4vBAt5gig8SQknx0pV1SypWYu6ug3yoveyi7CISpb8uEfKTRVwTLiChfGv8DEhBRwTSpCLXivlsSkR06i7IwRrjAvyp2NnJ7iXGZj6KioknjsTxFA3m6bOCwFKxKGS36F/N34p8HJ2yn3xfQLH5L+EQUbNIK1f4WPmcUxfzOf06X3Zs94zjq/cJ5zxvXdnImCxoZCMWBE3k3NEJ6eUOJgYivcQKchK2HTwvSrEB5eC1UEaM8aEJZhCyzgm8zHzOOYkPiYUETimlbIGv5H+RjzlT9uBOahhggpd6vTT+3tryLDHyWRny/ErKetY4n/tYW4mW8nQk5SNZ+l3+G5fv4bYYFLPwm4a9Y4Q2ibaMbiD877AMZFDhrAsV3BM5mPCLxz+MxrEikB1tLq2N5TDMRt8C9QRxjEvBWk8ZpDfTFNpyRgUT8EnbKyvRUEzSVhQ6mwNUzMscKYlTIFSD1Wsq6Sd4Vco7o3zn+a431C/Ed+1c9eTaLwLfEy0g9fjmPiwGVVV/cPKHwT2Rf/O3FH3svZf1cepZf8Z+v3xiPjL+dKyFBWVXMExk3GDhgc5k/pp8LJO0SovVa2romeLf0Vpg0nGjrvr8q6xjoEOgWPelI95LY65u2K31hJoUe6tvJe7Yeq9ME7dnSYOL3Vf9NPFtgC1t/uhgElZQ6e6pbVUtKaIXoy+ICyQVtL09KWnkyqpJ1566aXnMGGBY07Lx0RtOYmPObdubuXm2GaBY140LihUTsqCOYsoUhGigD9IiuYjIxSh8lkzKHJXiHzLfPT6nNfpvcDvKO1Jk6VY2acGn4r1d/ULHBMWEDgm+pjbxzH/5ujfCBzzlZqdxiXzkposTtLogjFabiwXOOYR6wj58Uh5UgLHTOIxHY7Jf1V9yzgml+jMx4TSAz7TJ3DMJqvJXzpc6hwtParGAzHljLeFWjwtlDATNKqPkqNYlFatKXFMWPYShrgzHBMzuIJjzszhmP3e/gKOWewU53DM4zkcs6urqxkKnIajf7I4JtMbGZmtilX9pafcU8AxvYpX4Jj/kv7nZMtQy1P7ruJjShxT4pgSx5Q45v8zOKYUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJEiRYoUKVKkSJFyZ/K/AZ1iuEDFYejDAAAAAElFTkSuQmCC')",
- // 9 = CalTrans
- "url('data:image/png;base64,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')",
- // 10 = TfL
- "url('data:image/png;base64,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')",
- // 11 = boots on ground
- "url('data:image/png;base64,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')",
- // 12 = difficult turn
- "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAKrCAYAAAB/UOT4AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4AgVAAgkef0zlwAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAABmJLR0QAAAAAAAD5Q7t/AAAhYUlEQVR42u1cC1SU1fYfFAExAYnXDCAEogjMMMMMDG98EC3ykTdzEsVEMLyKwkCimVYr7SKaENdSs7y2WvrP1VXTbqm9rHvNtJXdrmbZWt3U7HGT8qZp+cbvv39nzuCA8w2i3fVf63/3nrXXzPd95+zf/vbeZ59zNmeh0TAxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTH9B6gHcc8hQ4Z4m83mXk7GNe7L5785eUEwQGJjY/3o+5bc3Nx+BBySnZ0dlpKSEo5vXOM+nst23lIhr5sGx1uGh4f3ycrKCiaOpOv49PT0ZIvFYsrJybHQvQx84xr38Rzt0B790P9GlfHCm5Cg3hBGb9if3jbFbrcX79u3r7m1tXXXr7/++l1bW9sFhQjfuMZ9PEc7tEc/qXxvaZnrVsQL2tPb9aVvbWZm5uBFixaN+frrr3cQ2CXFhS5evKhkZmYpw4cXiuuzF35RpFKX0H7RwoVj0B9ypLxe16OIUMBqtQbk5+dHk4C0PXv2NF++fPlc25U2pTPNm/eQ0ru3hthLWbJkaYdnbW2XFfTb8+67zZADeZDblSLCBdAYZiwqKrIePXp0m6JCBw8eVAICtEpNjUZwaGiscuTIYbdtj2zYsK1o+HAr5EK+J9f0lAEYiUAjBbarKXDp0iWlrGyqotVqlOPHHRwZ2UOpqqpxNLhy5VpFdu7cnmk0WqxmcyRw5HDuaIXi4mJfDLW0tDTD+++/v1zxQG+++abSs2eQ8qc/aejKwWvWaBR//whl9+7dqv3WLVq03JCUZAAO8DpYQyaeQLLCgPnz55eQL8+rCfrpp5+UkSPHKjk5GuXECY2ybp1GefZZx+/sbI0yYcIU5fTp06qKzJ09uwQ4wJNuac8HvsnJyRF00/LVV1/tVBNwhcz8l7+8qlB7Zds2jbJ4sUb8Bs+f77jn5aVR3nnnXVUlIB84wAOu0xo95fCJr6urG+fJDSdPnlQSE5OVUaMcLhg50gEKHjHCce/OOzVKVlaucubMGbcyaPheBg7wgCtiAybJyMi4NS8vD7Gw2pMSDQ0NFAsa5a23HIDV1RpxDZ4+3XHvzTcd188995yqHOAAD7hOl/gimdCNrG+++eZDtY5ffvklBV5v5b77rgZjU5NG6dVLo3h7a5THH796v7RUowQH91Mog14j55dzpxXgAA+4wiVIqRStMQUFBUPJhD+oKVFYeLvSp49G+f77q2CbNmkUX1+N4uOjUdauvXr/u+80IomNHz/+mpgCAQd4wAW+hpJSHznp3EH+uuhOgZdeeon87kdv7tUOBP7wQwcYFHn9dU2HZ0uXwkL+ys6dO93FxUXgARf4iIlbKJ0mUGotdqfA2bNnleTkVCU+viMIuLVVI6wDRT799NrncXEaxWrNdmtZ4AEX+EIJ4gG4SfnhGkssXtxIVvBV/vrXa0HAQUEORX766dpnO3ciZvoozzzzTAeZwAEecIUSMAfl9DiaYIp+/vnn466NP//8cyUmJkm5914N+dO9En/4g0aZM8f9M/QZO1ZDlsxAMLbLBQ7wgCvcgcDAxEI85MiRIx+cv3i2fZqeO/chJTBQo+zf7x4EvHGjI2UjY7p7/ve/O6y1ePFSxIIC+TQv7QWeXG/0bh+iZB7rjh072u124MABivoAkQkvX1ZXIDhYo/j5aZQZM9y3uXTJYangYJ0Y5iDgAK99iMoVFFY/+pKSklLMG5gl777bpgwcqFEOHVK3AizgTNvFxertELQI7KqqaszA54EDPOA6k1UPuXiNoyw2fP/+/a/v2rVLCIa/nb7tzE6AujqH348e9dwWsiAT8oEDPBGUcnUuJjCsmrECuu+++8pJw9OIhUcf1ShPPaVR/vhHdcYMCougXUuL+zbLl2so5WsUna7P6dGjR5cDB3iuE1j7JCatMayysrIlMLDfFX//UEpEoeTzm2PI6N079Epubl4L4QwFTvvk1Wl5jwANwbKd0umIbdu2bV2+/Ora5ty5c8qNEq3Alffee28z5MptQUhnK7TvrOihP/kpghoaqcNdGzdu3PTxxx8rb7/9tnIztHDhwtbExMSpJN8E+cBR26mJhS6CRW5eTBMnThy5ZMmS5smTJ59bt26dcuHCBY8WudJpbUlTfxtly9doNIyCPMiVGdq7yxU3GmIM33///fry8vLC6urqigceeGBvd95+3rx5B2fNmlVZWlpaiOEIedejQAdFYDISEGqz2RImTZpkveOOO0bT4rRq7Nixhz2Bz50799TMmTPt1GcMTVC0wDYmULCHSld3bxcmd95+JCSIhEXdfvvtesrzhUTls2fP/pfK8u/kggULajE5Ia6Io9EfcuRI6JYCQgnslpDbsTImK+hIiZShQ4cWkY/ttKI+hRigDCvmBOK2pUuXNtPwGwUFoDgUQH9a1Pq4lA26dsW4cePQ2BcbFGzbkFqxT4BQUiaRQHLpevwTTzyxgpRoO/nLCWEFWry8QRaYTM+GYTOMVRMSEtaRZL1A5AUXhVSVaY8FdAQo9gfY0GJRSthmmn6zMQXTfewd7G+99ZZY2x87duwo3Z8LJQjsTuI8UiKd+qQiL5C8gfQsFst8aVVftSGKm76yFBAHkxJ4DvI8fEyCR5NiY+nZBGpTT4Ib6fdKyiPHyD3r6bqJnj9Mzyqozz3IM0hOdA9KF0ApvBDJ0XnaofeUi94wajQIkU0ghfAxwEnweHrbiSSojK4fIV5GglbQ92qLxbKKfrfQ9+P0vJpkTIK1qO846ofyQDH1zZdJMIYsHqSmhLAESj5YbMj0nS5NOwxvBGF4O1iFft8tQcbTbxsUxdsT+Ei0w0IWViQuwPIeCmC4Ik7ILZg93Q5XEZQYTvAbGqOmYDAYbpM+HQzFwEg+0t9GWSYy4hqxg6BEG/qdhH5YUePt4QbEGhRwCU7PdSoUv2SCuUVuXoNgJbkACobAzux8BsbwRD/4X5YcxMjoTsJy5gpRLpQW6lAy7IqdJUU55Hv8FpU8V4JwH0rffpS8/MGUTf1/97vfISv6yOe/fR2T3qYHLXS8aS7xq6mpuYUmtH7Tp08PqaqqCps6dWo4vnGN+3iOdmiPfjddx4QQmgl73XPPPX1mzJgRTGCRBBZPE1QyXZvsdruFnmfgG9e4j+doh/boh/43qowX3oQE9YYwesP+xCmrVq0q/uKLL5ppntp1/vz5DnVMXOM+nqMd2qMf+kMO5HVrAoP29EZ9qaOW3m7w+vXrx/zwww/X1DGxNZg/fz6tnBaJ6wuXzrXXMdEe/dAfciAPcq9rAkNDMmcAmTiaBKQdOnRItY754osvKhMn2gRv3fpK5523qGMeOnCgGXIgD3K7UkS4ABrDjA8++KD1+PHjqnVMmrSUyZMrleeftwmuqKiiXfpxt22P/+1v2x6cM8cKudLC7l1TUFDQE4GEoEKgkQKqdUysIVaseEaprLTRQsbB06bdS/uP51XrmMcPHNhe/fvfW2ZMmxYJHOBdY4Xa2lpfOdQM5AKPdUzsU++9t0x55x0bXTl4506bUlp6v9jJq9HODRuWV1ZUGIADvA7WgHmIA8l3A55//vkS8qdqHRNVucbGJuXhh23K6dM2ZdcuG20JHL8XLLDRjmulKKyo0Zpnny0BDvCkWxxWoMnJd8qUKRG0drS0trZ6rGPu2/eRQotf2vLblC1bbOI3eMMGxz38PnjwU1UlIB84wAOusAZ8g2BBklm9erXHOuYvv/yi2O11ypIlDhc0Nl5VYvFixz18z5//sOr+BHVM4AAPuCI2pCtuJR8hFjzWMV9++WWKBRvFhANw7VqbuAY/95zjHp7h2tOuDTjAA65wCUyCZELBkvXjjz+q1jG///57CryJytNPXw3GV1+1KSUlNmX8eJuyefPV+8uX2xQyt3Lq1Klr5Jy7cFYBDvCAK1yClEo3YmiHNZQCSrWOuWjRImXSJMdwdILt3WtTJkxwKOI6Uv79b0cCa2lpcbtNBA7wgAt8De2Y+sA/NPup1jH37NlDfp8o3twJBP7nPx1gUOQf/+j47JVXYKFS8ccZd3VM4AEX+BpMvaRNAmUzt3VMbILr6uqVWbM6goBPnbIJ60CRr7++9vnMmTbloYcWuLUs8IALfKEEBckA3HRniS1btpIVJiiffXYtCLiszKHImTPXPjt4EK6aJP5I09kSwAOuUALmoOQRRz4q+vXXXzsk/2+//VaZMaNWefJJG/nTvRIvv2xT1q93/wx9mppsZMl5yokTJ9rlAgd4wBXuQGBgYiGthtB88cHFSxfap+n161+kScqmHD3qHsQZnEjZyJjunh8+7LDWli2viJkV8ilh7QWeXG/0bh+idMP60UcfPePyFxoy5WSRCdva1BWYMsURE2vWuG9z+bLDUlOmTBPDHAQc4LUPUbmCCqZ5Xt/Q0FCKeQOz5LJlzUpNjU355ht1K8ACzozZ0KDeDkGLwF6zZi1m4PPAAR5wRbLC+g/BAf/U1dUNP3LkyOuU0YRg+Nvp287sBHjhBYffW1s9t4UsyIR84AAPuHL96ZjAsGrGCoi2/OW0ZDuNWPjzn23Kjh02Zft2dcYMCoug3bZt6u2gRGVl6elHH320HDjAa5/AnAsaTCbQjgJm2FNPPdVSVjblSmlpBSWiCvL5zTFklJZOvVJfP6eFFkxDgdM+ebkuaqAV9g5YtlPQjNi3b9/W7du3d0haN0oorH/22WebIVduC0I6WMFJ8E15ebk/WSKCGhlJ47t27969iXyofPLJJzdVx9y4cWMrmX8q9iaQDxxnLLhd6CJYsM4krU2NjY0jSUDz008/fQ5Fd+QOTxbpXMekqb9tx44dr9FoGAV5kAv5Xe1B2hXBGG5qatIvW7ascOXKlRVr167tVh1z3bp1B1esWFFJL1KI4Qh516NAB0VgMnqD0MceeyyBBFlpCzB6wYIFVUuXLj3cBfgpUtq+ZMkSbHwyyQuYpEIhr9u7MEQurQX9aHESRDESVV9frydFConLX3jhhX+pLP9O0rNaTE6IK4qBaPSHHDkSulfHRCfsluQ+MnDevHk6mmxSSJkisoydFiaijilrmKKOuWnTpmYKvFFQAIpDAfQvKyvzgbzr3Rh7UTLpieEjN0IBcjeO/UjUtGnTEmnU5BKP37x5s6hj4s/Oci/yBpl9MllhGDbDWDUhIWEdSRkyEHnBqZAnZdpjAR0Biv0BNrRYlBKAmYRlYwqm3yV0z75//35Rx6TN71Gy0FwoQQreSZxHiqTTdyryAik0kL5jscyHVbHxcTtEcRMWwJvLjGakxjnI8/AxCRxN7hlL9ybQ73rixjlz5qw8fPjwMQrW9XS/ie49TIpU0O97kGeQnIiLqF8BlMIL0bdOdYcOn8lFbxg1GITIJkGF8DHASZnxZIWJJKSM7j9C95cR4Aq6v5quV9HvFuLH6Xc18SRYC+ckqN0YuYrKx4vBTSQvyK0STkug5IPFhkzf6dK08HMRhOHtYBUCuRsgUI7u2aAo3p7uj0Q7LGRhRbpXgOU9FMBwRZxQXKAi6L6OiaDEcILf0Bg1hYqKitukTwdDMTCSD/wth6FJpvlUxA6CEm1IiST0k+WjGLgBsQYFXILTc50KxS8EqcxygTAhrCTLP8Fy99SBnc/AGJ7oB//LmpcYGd1JWF5OhRArsBA6Q7nrZbR39oWc36KS939OfB6Tz2PyeUw+j8nnMfk8Jp/H5POYfB6Tz2PyeUw+j8nnMfk8Jp/H5POYfB6Tz2PyeUw+j9nd85i0OPEbNmyYP5gSmD+u+Twmn8fk85h8HpPPY/J5TD6Pyecx+Twmn8fk85h8HpPPY/J5TD6Pyecx+Twmn8fk85j/FecxnecnYTKKFR+ykA8sBKWul2WCEn0hB+zp7fn/Y/J5TD6Pyecx+Twmn8fk85h8HpPPY/J5TD6Pyecx+Twmn8fk85h8HpPPY/J5TD6Pyecx/1+dx3QWWF2LqxUVFf719fWieCpr1nwek89j8nlMPo/J5zH5PCafx+TzmHwe87/4PObw4cMDFi5caGxoaCj/PzuP+eSTT/rxeUw+j8nnMfk8Jp/H5POYfB6Tz2Pyecz/5v+PKQqssUNivbVmbS8n4/o/fh4TIEGxQX79h/S/JTo3ul+EOSIkMjsyLDQlNBzfuMZ9PEc7qdRvcx4Tb9knvE+fyKzIYF2WLjLcHB4fkR6RHG4JN+lydBZtljYD37gW9+k52qE9+qH/DZ/HxJtEZUX1hrDI3Mj+umxdisFuKM7fl9+c0pqyK+zXsO96tfW6oFE0Cr5xjft4jnZoj37oDznSMtc/gUH7qJyovmRirTZTOzh9UfqYtK/TdvRs63kJoO2fi8SZxMPl9QXHN9qhffpCyxj0hxzIk1bxui4FdFZdQHR+dHREZkRa7p7cZt/Lvuc0VzrAOz7ziHtLXtLpWZtGQb/cd7ObIQfyILcrRRwuII1hxv5F/a1pR9O2uYF2fA4SBxDXSA4lPuK+bdqGhG39h0dbIRfyPbmmJwIJQYVAMx01bVdVAE4pI9YSH5ccSVwln7uxmmln0vYIY6hFa46IBI7b85gDigf4YqiFpYUZst/PXq6qAD5vEvck/pPLPRxt8Sferd7PuGjQ8pCkWw3AAV4Ha8A8FDyBZIUBxvnGEp/LPudVRf1EPJI4h/gE8TriZ+XvbOIJxKfVFTHM1pcAB3jSLVcPcIQkh0REDYmyGL4y7FQVATP/RR7mQbS4nMfUzJf3vIjf8aAEyQcO8Dqcx0SwIMno6/TjPLrhJHEi8Sh5PVKCgkfIe3cSZxGfcS+jR1uPy8ABHnBFbMAkugzdrZF5kYbM9zNXe1SiQcbCW/K6Wl6Dp3eKl+fU5QAHeMB1usQXySQ8Izxr0DeDPlTt+qUMvPtc7jUR9yL2Jn7c5X4pcTBxqxs55zQKcIAHXOESkZqzI2N0BbqhwWeCf1BVopC4D/H3Lvc2EfsS+xCvdbn/nUxg493EFH2AAzzgAl8TXxTfB/4Jzwq/w7vN+6JbBV6Sfm/qdP9DCQZFXu/0bKm0kJswBw7wgAt8DaZerVWbEJ4ZXuxWgbPEycTxbp61SutAkU/dPI8jtrq3LPCAC3yhRPSQ6AG46X3ZjSUWSyv8VcVNQVKRn9w82ylj5plOliAc4AFXKAFzUE6P0+XrikJ+DjneofnnxDHE97pPxeKDM3VzPOSVsdKS31y9DxzgAVe4QwQmTSzaXO2QQUcGfaC56DJNzyUOJN7vYdhulCn7hMrzv0trLXbMrJCbeDRxL/DEhIbAdA5Rmm6tlh2Wq4Y7IKMemfCyBwUwFP2IZ3iY7ObIdl867gEHeO1DFMkCqx9apunjSuJKxbyBjncTDyQ+5MEKLucxNcUe2n0qA5tmWZ9LPueBAzzgOpNVDwQH/KPN0w7X79e/rtklBf/Bxbed2fmpk34/2kVbeR4T8oEDPBGUrucxsWrGCij+vvjyHlk9TotYeJT4KeI/euBnpUXQrkWlzXJHyvfSaU5Hj44uBw7wrjmPKVdUsMawmMqYFlLiikjTvtLnN8O+IpdcCc4NbtHmaIcCp33y6nweE3sHLNsjsiNGJG9L3qpZ3jHn3/Bnn0ZJfS91M+QK+YSjeh6TFqH+5KeI8PRwY3h2+F1JG5M2aT4mIW/fhAL08V/o3xqYGDg1zBxmgnzgqJ7HRKQiWLDOpOg1JUxMGJm0JKm5x+Qe58QK6kIXFumU0LwavNrinol7bUDJgFGQB7mQ39UepF0RjGH9/Xr94PLBhYOrB1eEPBCytztv329ev4OJsxIrB5YOLMRwhLzrUaCDIjBZcmly6CDboITESYnW6DuiR+uKdVW9x/Y+7AncZ67PqYEzB9oTJiWMoXSUGWYMS4jKiwqFvG7vwuTO24+iI4hmu6iY22P00UXRhdpCbbn/bP9/uVMg4GTAyZQFKbWYnBBX2nRtNPpDzg2fxxTbQcrtWBnHFcfpYopiUiKHRhbFlsTa+57ue0rEwGXHnODV5tWWtDSpOSI3YpRQgBSHAugfmhzavfOYSeOSxHlMsRGibZvYENM+QQg1hyfqcnW5NHLGJz6RuMLrileb5heHFRJ3Jr4Rmhk6mYbhMLEZplUTEpJYRxbGBiIvuCikXsd0xgI6AhT7A2xoxaI0V2eOzI/MxhQclhVWEpIVYk94K+FdKKA9pj0amh86VyiRE3EnJaQ8bbY2nfqkiryQETFQl6mLxTIfVpUbH/XzmLIUEAeT6vJ0EDccPibho8OsYWPDc8Mn3Jp1a32/jH6N/XL7rQz9OPRYeEn4+qCMoKZga/DDoVmhFRF5EfcgzyA5hVvDiyKyIgqglHihnEidpx16T7noDaOGgxDZNOcXwscAJ8HjI/IjJtLblhHYI/2s/ZYFmANWBFoDVwdaAlcFmgNbgixBj4dkhlSHZYdNgrWo7zjqNwYvQRbMx4vBTTRUg9SUEJZAyQeLDZhRaE+2gJ/xRsIiSL2wSmbY3RJkPP22CSvR29MCdqQYHbSQhRXJmgVY3kMBDFfECblF/TwmghLDCX5DY9QUQg2ht8GnotgB/0I5Sj7wt0jvlnCTcB1di9ihoEQb+p2EflhR4+3hBsQaFHAJTs91KhS/5FyC7BkIEworIWZQvyKBndn5DIzhiX7wP0aac2R0J2F1OI8pLdShZNgVO0uKcsj/tucxSWiPmIKYnuZKs3fGrIxeTsY17uP5f6SOCcEAMZQa/NJr0m9Jr07vZ5puCkmrSgtLnZoajm9c4z6eox3aS4W8buqNyazepnKTf9I9SX3MM8zBBBZpnG6MN800JafOSDWZ7CaLcZYxA9/imu7jOdqhPfrBSjekDDpZ6ix+humGYP1MfXxKdUqmqdqUkr8qv3jYF8Oa9Sf1u8LOd6pj0jXu4znaob252twfyqTPSO8Ny1y3IlAgZUqKv2GGQZs0LcmYODNxhOF/DIvNP5ivrWNekvuShS7Xso6J9sPWDxtjnGkcbKw0atOmp/WFVbpUxKmAucocYLFboklA2tBDQ9XrmC8ST5S81X0dc+iBIc2QA3mQ25UiXjAZNIYZLQ9arJbjFvU65jHiycTPS65QKYpgx/W35G2WOWYr5Ar5aq4Rw4sCCUGFQDMfN6vXMbGGWEFcKetY4Gly/6FSxzQfMGw3/l5vMU0zRgIHeNdYIbM201cMuemphoJDBZ7rmAfkTv2dTmWAUrmTV6tVbTAtN1SkGIADvA7WgHlMlaZAGmID8p/PL/Fp81DHRFWukfhhWa/cJbcE+L1A7rjOqiuS92xuCXCAJ93isEJUZpSvYYohwjzbbEltTfVcx6SNjMYmt/xb5G/wBnnPJuveKh/IBw7wgCusAd8gWJBk8lbnea5jYilnd6noN7oosdilsjNffX+COiZwRFIjXBEb0hW3mmvNhrxDeZ7rmC/LWDggr9fK63td6pbOePGwawMO8AQuXAKTIJkYqgxZiT8mqtcxv5eB97TLvVeJS2SpcLPLfYT1FOJTbuRQjgUO8IArXIKUaqoyxRgfMA4NPuuhjrmIeJIcjs7PXllQL+k0Uv4tE1iLSh2TcIAHXOBrcubm9IF/DDUG9TrmHun3Vzvd/6cEgyL/6PTsFWmhg+7rmMADLvA1mHpNM0wJ+mq9+4LPBVmNmeXm2SlpHSjytZvnM4kfcm9Z4AEX+EIJS61lAG66tYRzGH6m4qYyqcgZlT9RlciieydLAA+4QgmYg5JHHPmoKOTXTnXMb2VV7kkPdUyMmPUe8kqTtKRLiRE4wAOuwx2Y62liMdYahww+PvgD53QsvtfLSeqoh2G7V6Zstb/2HJbW2iLrmCQ3qTVpL/CAKwLTOUSN1UZr9kfZV+uYX0lTbpCd1RSYImNijYfJbr1sJ/9CABzgtQ9RJAusfkyzTHpLg6VUzBvouEz+qfEbD1bY6ZIxGzy0+1oGNimKOilwgAdckaywkBEjBHFRZxxuPGJ8XRRQbdLfXdUxX5B+b+2i7csOmZAPHOAB17k6FxMYVs1iBfSEpbzX/F6nRSz8mXgH8XYP/La0yA75hzi1dqSEd6X3aeOjxnLgAK99AnMuaDCZCGvUGoelPJXSQsF0RaTpCS5LuBvlCSLlX4mvj29JtacOBU775OW6qIFW2Dtg2U5jeIRxn3GrZnunpHWjny9pifeZZTPkQj5wOljBdZGLPUZGbUYEra6Merv+LuNu4ybx9+9Pbq6O2Xdj39aEqQlTsTeBfLGXUdmpiYUugkWsM6tNJmujdaRlo6XZ+2nvc2IFdakLi3SuY77s1TZ4x+DXrA3WUZAHuZDf1R6kXRGM4YKmAn3OspzCrJVZFVFro7pVxwxfF37QusJamdWYVYjhCHnXo0AHRWCygoaC0JzHchJyGnOspgdNo/UL9FVBS4M81jH91vmdyliZYbcusY5JnZmaaZhqSLDUWEIhr1u7MDRE5GbPzvajtWAQBVKUpd6iT3swrVD/oL484IUA93XMXwJOZr2QVYvJCXGVNiMtGv0hR46E7tUx0Qm7JbHooZVx5rxMXfrc9BRTvanI2Gi09z0r65htV+uYlk2WZkOtYRQUgOJQAP2NZUYfl7JB164oeLSgJ4aP2InTtk3uxrH1j0qdlppotBtzU+wp49M2pznqmHJBqz+gfyOpJmmyodowDJthrJqQkLCOtNZZA5EXnAp5UqY9FtARoNgfYEMrFqU1JrOpzpSNKTi5JrkksTbRPnj/YFHH1P2gO5pYnzhXKGE33EmK5tEElZ5mT0sV5YIq48C0mWmxWOYLq9LGx+0QxU1YQExmlNFgUsqeOcjz8DHljdHJs5LHptSmTBhkH1Qfb49vjJsTtzLscNixAUsHrI+rjWtKsCc8TIpU6Gv19yDPIDmRZYoMswwFUEq8ULVZp7pDh89gLmH6WaZBiGxKsYXwMcD1dfrx+gf0E5Oqk8oI7JH42vhlsTWxK2LrYlfH2mNX3VZzW8uAmgGPJ9oTq5PtyZNgLZyToP5j8BL0QvkiVshNllmWILdKOC2Bkg8WG8KM0J5MCz/jjYRF6O1gFX2N/m6AQLnk6mSbUBRvX6MfiXZiIUtWpBcpwPIeCmC4Ik70ZfpbUAVyW8dEUGI4wW9ojJqCocJwG3wKU4q8D6bkA39DMFKxGI50LWIHQUlt0mrSkkQ/lJfo7eEGxBoUcAlO9SIZTIXiF4JUrDVIKZhQWAkLEcQNgrcTO5+BRX6hfvA/RppzZHQnYXk5FUKswEKdS4ZdsbOkiL6Q42lY/i9/ofIO/jaWEgAAAABJRU5ErkJggg==')",
- ];
- var uroMarkers =
- [
- // 0 = comment count circle
- ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAaCAYAAAA5WTUBAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB90LCxYGJyle3m4AAAAdaVRYdENvbW1lbnQAAAAAAENyZWF0ZWQgd2l0aCBHSU1QZC5lBwAAAv1JREFUSMfFls1r3EYYxn+zo9XsqjuSxpBQU5OCDy0Y3JODs2Z36W6P/YBCk159s+/5F9Z/QsHkUAruZZ344Jx7KPTSa2/NwSdDE1ISf8SWI63k6UVLN8ZuZFnQ56IZDYwevR/P+wguh7jieXF9Gewla3vJWeELAfA8b9ZxnFWl1P0kST7NsswDkFJGrus+i+P4cZqmP0VR9JyKIWq12owx5kff95PBYBCPRiN7EaPRyA4Gg9j3/cQY80hK6VdFwFFK3TXGvOx0OoktiE6nExtjXjSbzYUb/T3QqNfrvSAITofDob0uhsOhDcPwTVkiAmgCC8aYV2UITBMxxrwok5oGcEdr/XR5eXlsb4g8NY+uVQPAh0KIr7XW6f7+vq0Cvu8nnufNvu/jtak03FZKfbe4uGjn5uYqqe6lpSXrOM5qERIS8IEZz/O66+vrTlUttra25iql7hfSImAB+DIIgrd7e3u2KhwcHNggCE6LREIBGlBZlqn5+fnK1C4MQybqWiQdKi/O/wWTwpSAkFLGWZZVdnkURUgpoyIk/t3Uas93dnYqI7G9vY3rus+KkLBABtgoin7f3NxMqyKxtbWVxHH8uIhUG+AT4CMhxK1Wq/XD8fGxrIJEEATjNE0/ft+IrwEx8AaIrbWH1tpfV1ZWbhyNbrc7llL+XMRjyDwdTt6mzSRJ/jw5Ofkiy7JGr9crRWBjY4Pd3d3XR0dH31hrz4pOTw18BnwFPBBCPPR9/6zsKA+C4FQpdbeoc3tngAErwLfA90KIh2EYHrbb7cITtd1uj40xr+r1eq+s7jSAO0A3J/IAWG21Wr9ordN+vz++yt71+/2x1jrVWj/NR0DjukbmHVcF3ALmgJl8L4UQoeu6n3ued+/8/Hw2yzKVG91YSvlXFEW/xXH8xFr7B/A38PYqZ13EbYtcwkPgdk7kgylZF1PWPc076xR4DbwEDvN3tmwkLtZIMx/xwWTA5d1ELm6T1j4CjoGznFgpX/lfZxJwpwhMR2JCJJkobllN+QeQNNGuneopoQAAAABJRU5ErkJggg=="],
- // 1 = green comment marker
- ["data:image/png;base64,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"],
- // 2 = yellow (own) comment marker
- ["data:image/png;base64,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"]
- ];
- var uroFeedFilterReloads = 0;
- var uroFeedFilterFilters =
- [
- ['feed.issues.motivations.CAN_BE_SOLVED_BY_RANK', 'motivation'],
- ['feed.issues.motivations.CLOSE_TO_FAVORITES', 'motivation'],
- ['feed.issues.motivations.ISSUE_AGE', 'motivation'],
- ['feed.issues.motivations.ISSUE_REOPENED', 'motivation'],
- ['feed.issues.motivations.NEAR_DRIVES', 'motivation'],
- ['feed.issues.motivations.REPORTED_BY_USER', 'motivation'],
- ['feed.issues.motivations.USER_FOLLOWS_ISSUE', 'motivation'],
- ['feed.issues.motivations.USER_FOLLOWS_ISSUE_LAST_COMMENT', 'motivation'],
- ['venues.update_requests.panel.flag_title.IMAGE', 'title'],
- ['venues.update_requests.panel.flag_title.VENUE', 'title'],
- ['venues.update_requests.panel.title.ADD_IMAGE', 'title'],
- ['venues.update_requests.panel.title.ADD_VENUE', 'title'],
- ['venues.update_requests.panel.title.DELETE_VENUE', 'title'],
- ['venues.update_requests.panel.title.UPDATE_VENUE', 'title']
- ];
- /*
- function uroAddDebug(debugtext)
- {
- var ts = Math.round(performance.now());
- if(uroRecentDebug.length == 100)
- {
- uroRecentDebug.shift();
- }
- uroRecentDebug.push(ts+': '+debugtext);
- console.debug('URO+DBG '+ts+':'+debugtext);
- }
- function uroDumpDebug()
- {
- if(uroRecentDebug.length > 0)
- {
- document.getElementById('WazeMap').innerHTML = '<textarea id="uroDbgOutput" style="width:100%;height:100%">';
- var dbgOutput = '';
- for(var i=0; i<uroRecentDebug.length; i++)
- {
- dbgOutput += uroRecentDebug[i]+'\n';
- }
- document.getElementById('uroDbgOutput').textContent = dbgOutput;
- }
- }
- */
- function uroTempFixMTEDropDown()
- {
- // temporary fix for that bloody annoying bug in the closure event dropdown... sort it out devs!
- // also removes the "Choose Event" non-option from the list, so that it now always starts with "None"
- if(document.getElementsByName('closure_eventId').length > 0)
- {
- if(document.getElementsByName('closure_eventId')[0].selectedOptions.length > 0)
- {
- document.getElementsByName('closure_eventId')[0].required = false;
- if(document.getElementsByName('closure_eventId')[0].selectedOptions[0].text == I18n.lookup('closures.choose_event'))
- {
- document.getElementsByName('closure_eventId')[0].selectedOptions[0].remove();
- }
- }
- }
- }
- function uroAddLog(logtext)
- {
- if(uroShowDebugOutput) console.log('URO+: '+logtext);
- }
- function uroGetCBChecked(cbID)
- {
- try
- {
- return(document.getElementById(cbID).checked);
- }
- catch(err)
- {
- return null;
- }
- }
- function uroSetCBChecked(cbID, state)
- {
- try
- {
- document.getElementById(cbID).checked = state;
- }
- catch(err)
- {
- }
- }
- function uroGetElmValue(elmID)
- {
- try
- {
- return(document.getElementById(elmID).value);
- }
- catch(err)
- {
- return null;
- }
- }
- function uroSetStyleDisplay(elm,style)
- {
- try
- {
- document.getElementById(elm).style.display = style;
- }
- catch(err)
- {
- }
- }
- function uroSetOnClick(elm,fn)
- {
- try
- {
- document.getElementById(elm).onclick = fn;
- }
- catch(err)
- {
- }
- }
- function uroAddEventListener(elm,eventType,eventFn,eventBool)
- {
- try
- {
- document.getElementById(elm).addEventListener(eventType, eventFn, eventBool);
- }
- catch(err)
- {
- }
- }
- function uroAlertBoxObj(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction)
- {
- this.headericon = headericon;
- this.title = title;
- this.content = content;
- this.hasCross = hasCross;
- this.tickText = tickText;
- this.crossText = crossText;
- this.tickAction = tickAction;
- this.crossAction = crossAction;
- }
- function uroCloseAlertBox()
- {
- document.getElementById('uroAlerts').childNodes[0].innerHTML = '';
- document.getElementById('uroAlerts').childNodes[1].innerHTML = '';
- document.getElementById('uroAlertTickBtnCaption').innerHTML = '';
- document.getElementById('uroAlertCrossBtnCaption').innerHTML = '';
- uroAlertBoxTickAction = null;
- uroAlertBoxCrossAction = null;
- document.getElementById('uroAlerts').style.visibility = "hidden";
- document.getElementById('uroAlertCrossBtn').style.visibility = "hidden";
- uroAlertBoxInUse = false;
- if(uroAlertBoxStack.length > 0)
- {
- uroBuildAlertBoxFromStack();
- }
- }
- function uroCloseAlertBoxWithTick()
- {
- if(typeof uroAlertBoxTickAction === 'function')
- {
- uroAlertBoxTickAction();
- }
- uroCloseAlertBox();
- }
- function uroCloseAlertBoxWithCross()
- {
- if(typeof uroAlertBoxCrossAction === 'function')
- {
- uroAlertBoxCrossAction();
- }
- uroCloseAlertBox();
- }
- function uroShowAlertBox(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction)
- {
- uroAlertBoxStack.push(new uroAlertBoxObj(headericon, title, content, hasCross, tickText, crossText, tickAction, crossAction));
- if(uroAlertBoxInUse === false)
- {
- uroBuildAlertBoxFromStack();
- }
- }
- function uroBuildAlertBoxFromStack()
- {
- uroAlertBoxInUse = true;
- uroAlertBoxTickAction = null;
- uroAlertBoxCrossAction = null;
- var titleContent = '<span style="font-size:14px;padding:2px;">';
- titleContent += '<i class="fa '+uroAlertBoxStack[0].headericon+'"> </i> ';
- titleContent += uroAlertBoxStack[0].title;
- titleContent += '</span>';
- document.getElementById('uroAlerts').childNodes[0].innerHTML = titleContent;
- document.getElementById('uroAlerts').childNodes[1].innerHTML = uroAlertBoxStack[0].content;
- document.getElementById('uroAlertTickBtnCaption').innerHTML = uroAlertBoxStack[0].tickText;
- if(uroAlertBoxStack[0].hasCross)
- {
- document.getElementById('uroAlertCrossBtnCaption').innerHTML = uroAlertBoxStack[0].crossText;
- document.getElementById('uroAlertCrossBtn').style.visibility = "visible";
- if(typeof uroAlertBoxStack[0].crossAction === "function")
- {
- uroAlertBoxCrossAction = uroAlertBoxStack[0].crossAction;
- }
- }
- else
- {
- document.getElementById('uroAlertCrossBtn').style.visibility = "hidden";
- }
- if(typeof uroAlertBoxStack[0].tickAction === "function")
- {
- uroAlertBoxTickAction = uroAlertBoxStack[0].tickAction;
- }
- document.getElementById('uroAlerts').style.visibility = "";
- uroAlertBoxStack.shift();
- }
- function uroFirstTimerWelcomePack()
- {
- uroAddLog('welcome new users to Club URO...');
- // for now, just show the update notes...
- uroShowUpdateNotes();
- }
- function uroShowUpdateNotes()
- {
- uroAddLog('let existing users know what\'s new in this release');
- var releaseNotes = '';
- releaseNotes += '<p>Thanks for upgrading to URO+ '+uroVersion+' ('+uroReleaseDate+'). What\'s changed?</p>';
- var loop;
- if(uroChanges.length > 0)
- {
- releaseNotes += '<ul>';
- for(loop=0; loop < uroChanges.length; loop++)
- {
- releaseNotes += '<li>'+uroChanges[loop];
- }
- releaseNotes += '</ul>';
- }
- if((uroBetaEditor) && (uroBetaChanges.length > 0))
- {
- releaseNotes += '<p>For WME Beta:<p>';
- releaseNotes += '<ul>';
- for(loop=0; loop < uroBetaChanges.length; loop++)
- {
- releaseNotes += '<li>'+uroBetaChanges[loop];
- }
- releaseNotes += '</ul>';
- }
- uroShowAlertBox('fa-info-circle', 'URO+ Release Notes', releaseNotes, false, "OK", "", null, null);
- }
- function uroAdvertiseCustomIcons()
- {
- /*
- //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
- uroAddLog('advertise the benefits of custom UR icons...');
- var confirmMsg = '';
- confirmMsg += '<p>Hi there. One of the features of URO+ that a lot of users find useful is the ability to use a custom marker for URs and MPs which have been tagged with a specific keyword in their description text.</p>';
- confirmMsg += '<p>Markers are defined for <b>[ROADWORKS]</b>, <b>[CONSTRUCTION]</b>, <b>[CLOSURE]</b>, <b>[EVENT]</b>, <b>[NOTE]</b>, <b>[WSLM]</b>, <b>[BOG]</b> and <b>[DIFFICULT]</b> tags in URs, and <b>[TfL Open Data]</b>, <b>[Elgin]</b>, <b>[TM]</b>, <b>[TrafficCast]</b> and <b>[Caltrans]</b> in MPs.</p>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[1]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[0]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[4]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[3]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[5]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[11]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[12]+';background-position:0 -523px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[10]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[6]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[8]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[7]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<div style="background-image:'+uroAltMarkers[9]+';background-position:0 -25px;visibility:visible;height:40px;width:33px;float:left;"></div>';
- confirmMsg += '<p style="clear:left;">Would you like me to automatically enable these custom markers?</p>';
- confirmMsg += '<p>If you change your mind later on, they can be enabled/disabled via the Misc tab within the URO+ settings</p>';
- uroShowAlertBox('fa-info-circle', 'URO+ Message to Users', confirmMsg, true, 'Yes please', 'No thanks', uroSetMarkerCBs, null);
- */
- }
- function uroSetMarkerCBs()
- {
- uroSetCBChecked('_cbCustomRoadworksMarkers', true);
- uroSetCBChecked('_cbCustomConstructionMarkers', true);
- uroSetCBChecked('_cbCustomClosuresMarkers', true);
- uroSetCBChecked('_cbCustomEventsMarkers', true);
- uroSetCBChecked('_cbCustomNotesMarkers', true);
- uroSetCBChecked('_cbCustomBOGMarkers', true);
- uroSetCBChecked('_cbCustomDifficultMarkers', true);
- uroSetCBChecked('_cbCustomWSLMMarkers', true);
- uroSetCBChecked('_cbCustomNativeSLMarkers', true);
- uroSetCBChecked('_cbCustomElginMarkers', true);
- uroSetCBChecked('_cbCustomTrafficMasterMarkers', true);
- uroSetCBChecked('_cbCustomTrafficCastMarkers', true);
- uroSetCBChecked('_cbCustomCaltransMarkers', true);
- uroSetCBChecked('_cbCustomTFLMarkers', true);
- }
- function uroGatherSettings(container)
- {
- var options = '';
- var urOptions = document.getElementById(container).getElementsByTagName('input');
- for (var optIdx=0;optIdx<urOptions.length;optIdx++)
- {
- var id = urOptions[optIdx].id;
- if((id.indexOf('_cb') === 0)||(id.indexOf('_text') === 0)||(id.indexOf('_input') === 0))
- {
- options += ':' + id;
- if(urOptions[optIdx].type == 'checkbox') options += ',' + urOptions[optIdx].checked.toString();
- else if((urOptions[optIdx].type == 'text')||(urOptions[optIdx].type == 'number')) options += ',' + urOptions[optIdx].value.toString();
- }
- }
- return options;
- }
- function uroGatherCamWatchList()
- {
- var liststr = '';
- for(var loop=0;loop<uroCamWatchObjects.length;loop++)
- {
- var camObj = uroCamWatchObjects[loop];
- if((camObj.fid != null) && (camObj.persistent === true))
- {
- if(loop > 0) liststr += ':';
- liststr += camObj.fid+',';
- liststr += camObj.watch.lon+',';
- liststr += camObj.watch.lat+',';
- liststr += camObj.watch.type+',';
- liststr += camObj.watch.azymuth+',';
- liststr += camObj.watch.speed+',';
- liststr += camObj.watch.validated+',';
- liststr += camObj.groupID+',';
- liststr += camObj.server;
- }
- }
- return liststr;
- }
- function uroGatherSegWatchList()
- {
- var liststr = '';
- for(var loop=0;loop<uroSegWatchObjects.length;loop++)
- {
- var segObj = uroSegWatchObjects[loop];
- if((segObj.fid != null) && (segObj.persistent === true))
- {
- if(loop > 0) liststr += ':';
- liststr += segObj.fid+',';
- liststr += segObj.watch.left+',';
- liststr += segObj.watch.right+',';
- liststr += segObj.watch.bottom+',';
- liststr += segObj.watch.top+',';
- liststr += segObj.watch.fromNode+',';
- liststr += segObj.watch.toNode+',';
- liststr += segObj.watch.fwdDir+',';
- liststr += segObj.watch.revDir+',';
- liststr += segObj.watch.length+',';
- liststr += segObj.watch.level+',';
- liststr += segObj.watch.rank+',';
- liststr += segObj.watch.roadType+',';
- liststr += segObj.watch.updatedOn+',';
- liststr += segObj.groupID+',';
- liststr += segObj.server;
- }
- }
- return liststr;
- }
- function uroGatherPlaceWatchList()
- {
- var liststr = '';
- for(var loop=0;loop<uroPlaceWatchObjects.length;loop++)
- {
- var placeObj = uroPlaceWatchObjects[loop];
- if((placeObj.fid != null) && (placeObj.persistent === true))
- {
- if(loop > 0) liststr += ':';
- liststr += placeObj.fid+',';
- liststr += placeObj.watch.left+',';
- liststr += placeObj.watch.right+',';
- liststr += placeObj.watch.bottom+',';
- liststr += placeObj.watch.top+',';
- liststr += placeObj.watch.name+',';
- liststr += placeObj.watch.imageCount+',';
- liststr += placeObj.watch.residential+',';
- liststr += placeObj.watch.updatedOn+',';
- liststr += placeObj.groupID+',';
- liststr += placeObj.server;
- }
- }
- return liststr;
- }
- function uroGatherCWLGroups()
- {
- var liststr = '';
- for(var loop=0;loop<uroCWLGroups.length;loop++)
- {
- var groupObj = uroCWLGroups[loop];
- if(groupObj.groupID != -1)
- {
- if(loop > 0) liststr += ':';
- liststr += groupObj.groupID+',';
- liststr += groupObj.groupName+',';
- liststr += groupObj.groupCollapsed;
- }
- }
- return liststr;
- }
- function uroGatherPlacesGroups()
- {
- var liststr = '';
- for(var loop=0;loop<uroPlacesGroupsCollapsed.length;loop++)
- {
- if(loop > 0) liststr += ':';
- liststr += uroPlacesGroupsCollapsed[loop];
- }
- return liststr;
- }
- function uroGatherFriendlyAreaNames()
- {
- var liststr = '';
- for(var loop=0;loop<uroFriendlyAreaNames.length;loop++)
- {
- var fnObj = uroFriendlyAreaNames[loop];
- if(loop > 0) liststr += ':';
- liststr += fnObj.fName+',';
- liststr += fnObj.area+',';
- liststr += fnObj.server;
- }
- return liststr;
- }
- function uroSaveSettings()
- {
- if(uroInhibitSave)
- {
- uroAddLog('save inhibited');
- return;
- }
- if (localStorage)
- {
- localStorage.UROverviewUROptions = uroGatherSettings('uroCtrlURs');
- localStorage.UROverviewMPOptions = uroGatherSettings('uroCtrlMPs');
- localStorage.UROverviewCameraOptions = uroGatherSettings('uroCtrlCameras');
- localStorage.UROverviewMiscOptions = uroGatherSettings('uroCtrlMisc');
- localStorage.UROverviewPlacesOptions = uroGatherSettings('uroCtrlPlaces');
- localStorage.UROverviewCamWatchList = uroGatherCamWatchList();
- localStorage.UROverviewSegWatchList = uroGatherSegWatchList();
- localStorage.UROverviewPlaceWatchList = uroGatherPlaceWatchList();
- localStorage.UROverviewCWLGroups = uroGatherCWLGroups();
- localStorage.UROverviewFriendlyAreaNames = uroGatherFriendlyAreaNames();
- localStorage.UROverviewPlacesGroups = uroGatherPlacesGroups();
- localStorage.UROverviewMasterEnable = uroGetCBChecked('_cbMasterEnable');
- localStorage.UROverviewCurrentVersion = uroVersion;
- uroAddLog('save complete');
- }
- else
- {
- uroAddLog('no localStorage, save blocked');
- }
- }
- function uroApplySettings(settings)
- {
- var options = settings.split(':');
- for(var optIdx=0;optIdx<options.length;optIdx++)
- {
- var fields = options[optIdx].split(',');
- if(fields[0].indexOf('_cb') === 0)
- {
- if(document.getElementById(fields[0]) !== null)
- {
- uroSetCBChecked(fields[0], (fields[1] == 'true'));
- }
- }
- else if((fields[0].indexOf('_input') === 0)||(fields[0].indexOf('_text') === 0))
- {
- if(document.getElementById(fields[0]) !== null) document.getElementById(fields[0]).value = fields[1];
- }
- }
- }
- function uroApplyCamWatchList()
- {
- var objects = localStorage.UROverviewCamWatchList.split(':');
- uroCamWatchObjects = [];
- if(objects.length > 0)
- {
- for(var objIdx=0;objIdx<objects.length;objIdx++)
- {
- var fields = objects[objIdx].split(',');
- if(fields.length >= 7)
- {
- // following two bits of code add in blank fields if the user has updated their copy of URO+ from an
- // older version which didn't include support for either of these field types
- // add default groupID field
- if(fields.length == 7)
- {
- fields.push(0);
- }
- // set default groupID value to 0 (no group)
- if(fields[7] == -1)
- {
- fields[7] = 0;
- }
- // add default server field
- if(fields.length == 8)
- {
- fields.push('??');
- }
- // set default server value to unknown
- if(fields[8] === 0)
- {
- fields[8] = '??';
- }
- uroCamWatchObjects.push(new uroCamWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8]));
- }
- }
- }
- }
- /*
- function uroApplySegWatchList()
- {
- var objects = localStorage.UROverviewSegWatchList.split(':');
- uroSegWatchObjects = [];
- for(var objIdx=0;objIdx<objects.length;objIdx++)
- {
- var fields = objects[objIdx].split(',');
- uroSegWatchObjects.push(new uroSegWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10],fields[11],fields[12],fields[13],fields[14],fields[15]));
- }
- }
- function uroApplyPlaceWatchList()
- {
- var objects = localStorage.UROverviewPlaceWatchList.split(':');
- uroPlaceWatchObjects = [];
- for(var objIdx=0;objIdx<objects.length;objIdx++)
- {
- var fields = objects[objIdx].split(',');
- uroPlaceWatchObjects.push(new uroPlaceWatchObj(true,fields[0],fields[1],fields[2],fields[3],fields[4],fields[5],fields[6],fields[7],fields[8],fields[9],fields[10]));
- }
- }
- */
- function uroApplyCWLGroups()
- {
- var objects = localStorage.UROverviewCWLGroups.split(':');
- uroCWLGroups = [];
- if(objects.length === 0)
- {
- uroCWLGroups.push(new uroOWLGroupObj(0,'No group',false));
- }
- else
- {
- for(var objIdx=0;objIdx<objects.length;objIdx++)
- {
- var fields = objects[objIdx].split(',');
- if(fields.length < 2)
- {
- fields.push(false);
- }
- uroCWLGroups.push(new uroOWLGroupObj(fields[0],fields[1],(fields[2] == 'true')));
- }
- }
- }
- /*
- function uroApplyPlacesGroups()
- {
- var t = localStorage.UROverviewPlacesGroups.split(':');
- for(var i=0;i<t.length;i++)
- {
- uroPlacesGroupsCollapsed[i] = (t[i] == "true");
- }
- }
- */
- function uroApplyFriendlyAreaNames()
- {
- var objects = localStorage.UROverviewFriendlyAreaNames.split(':');
- uroFriendlyAreaNames = [];
- for(var objIdx=0;objIdx<objects.length;objIdx++)
- {
- var fields = objects[objIdx].split(',');
- uroFriendlyAreaNames.push(new uroAFNObj(fields[0],parseFloat(fields[1]),fields[2]));
- }
- uroReplaceAreaNames(true);
- }
- function uroTranslateLegacyMPTabSettings()
- {
- var options = localStorage.UROverviewMPOptions.split(':');
- for(var optIdx=0;optIdx<options.length;optIdx++)
- {
- var fields = options[optIdx].split(',');
- if(fields[0].indexOf('_cb') === 0)
- {
- if(fields[0] == '_cbMPFilterParkingLotInputAsPoint') uroSetCBChecked('_cbMPFilter_T50', (fields[1] == 'true'));
- if(fields[0] == '_cbMPMissingPLP_T70') uroSetCBChecked('_cbMPFilter_T70', (fields[1] == 'true'));
- if(fields[0] == '_cbMPMissingPLP_T71') uroSetCBChecked('_cbMPFilter_T71', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterDrivingDirectionMismatch') uroSetCBChecked('_cbMPFilter_T101', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterMissingJunction') uroSetCBChecked('_cbMPFilter_T102', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterMissingRoad') uroSetCBChecked('_cbMPFilter_T103', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterCrossroadsJunctionMissing') uroSetCBChecked('_cbMPFilter_T104', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterRoadTypeMismatch') uroSetCBChecked('_cbMPFilter_T105', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterRestrictedTurn') uroSetCBChecked('_cbMPFilter_T106', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterTurnProblem') uroSetCBChecked('_cbMPFilter_T200', (fields[1] == 'true'));
- if(fields[0] == '_cbMPFilterRoadClosureProblem') uroSetCBChecked('_cbMPFilter_T300', (fields[1] == 'true'));
- }
- }
- }
- function uroLoadSettings()
- {
- var isNewInstall = true;
- var isUpgradeInstall = true;
- var notifyAboutCustomIcons = true;
- uroAddLog('loadSettings()');
- if (localStorage.UROverviewUROptions != null)
- {
- uroAddLog('recover UR tab settings');
- uroApplySettings(localStorage.UROverviewUROptions);
- isNewInstall = false;
- }
- if (localStorage.UROverviewCameraOptions != null)
- {
- uroAddLog('recover camera tab settings');
- uroApplySettings(localStorage.UROverviewCameraOptions);
- isNewInstall = false;
- }
- if (localStorage.UROverviewMPOptions != null)
- {
- uroAddLog('recover MP tab settings');
- uroTranslateLegacyMPTabSettings();
- uroApplySettings(localStorage.UROverviewMPOptions);
- isNewInstall = false;
- }
- if (localStorage.UROverviewPlacesOptions != null)
- {
- uroAddLog('recover Places tab settings');
- uroApplySettings(localStorage.UROverviewPlacesOptions);
- isNewInstall = false;
- }
- if (localStorage.UROverviewMiscOptions != null)
- {
- uroAddLog('recover misc tab settings');
- uroApplySettings(localStorage.UROverviewMiscOptions);
- isNewInstall = false;
- if(localStorage.UROverviewCurrentVersion != null)
- {
- notifyAboutCustomIcons = false;
- }
- else
- {
- if(uroGetCBChecked('_cbCustomRoadworksMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomConstructionMarkers')=== true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomClosuresMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomEventsMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomNotesMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomWSLMMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomBOGMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomDifficultMarkers') === true) notifyAboutCustomIcons = false;
- if(uroGetCBChecked('_cbCustomNativeSLMarkers') === true) notifyAboutCustomIcons = false;
- }
- }
- if(localStorage.UROverviewCWLGroups != null)
- {
- uroAddLog('recover CWL groups');
- uroApplyCWLGroups();
- isNewInstall = false;
- }
- else
- {
- uroAddLog('set default CWL group');
- uroCWLGroups.push(new uroOWLGroupObj(0,'No group',false));
- }
- if(localStorage.UROverviewCamWatchList != null)
- {
- uroAddLog('recover camera watchlist');
- uroApplyCamWatchList();
- uroGetCurrentCamWatchListObjects();
- isNewInstall = false;
- }
- /*
- if(localStorage.UROverviewSegWatchList != null)
- {
- uroAddLog('recover segment watchlist');
- uroApplySegWatchList();
- uroGetCurrentSegWatchListObjects();
- isNewInstall = false;
- }
- if(localStorage.UROverviewPlaceWatchList != null)
- {
- uroAddLog('recover places watchlist');
- uroApplyPlaceWatchList();
- //uroGetCurrentPlaceWatchListObjects();
- isNewInstall = false;
- }
- if(localStorage.UROverviewPlacesGroups != null)
- {
- uroAddLog('recover places groups');
- uroApplyPlacesGroups();
- isNewInstall = false;
- }
- */
- if(localStorage.UROverviewCurrentVersion != null)
- {
- uroAddLog('comparing install versions');
- if(localStorage.UROverviewCurrentVersion == uroVersion)
- {
- isUpgradeInstall = false;
- }
- }
- if(localStorage.UROverviewFriendlyAreaNames != null)
- {
- uroAddLog('recover friendly area names');
- uroApplyFriendlyAreaNames();
- isNewInstall = false;
- }
- if(localStorage.UROverviewMasterEnable != null)
- {
- uroAddLog('recover master enable state');
- document.getElementById('_cbMasterEnable').checked = (localStorage.UROverviewMasterEnable == "true");
- }
- if(isNewInstall)
- {
- uroFirstTimerWelcomePack();
- }
- else if(isUpgradeInstall)
- {
- uroShowUpdateNotes();
- }
- if(notifyAboutCustomIcons)
- {
- uroAdvertiseCustomIcons();
- }
- uroInhibitSave = false;
- }
- function uroDefaultSettings()
- {
- uroShowAlertBox("fa-warning", "URO+ Warning", "Resetting URO+ settings <b>cannot</b> be undone.<br>Are you <i>sure</i> you want to do this?", true, "Reset settings", "Keep settings", uroDefaultSettingsAction, null);
- }
- function uroDefaultSettingsAction()
- {
- var defaultSettings = '';
- defaultSettings += '[UROverviewMPOptions][len=788]:_cbMPFilterParkingLotInputAsPoint,false:_cbMPFilterMissingJunction,false:_cbMPFilterMissingRoad,false:_cbMPFilterCrossroadsJunctionMissing,false:_cbMPFilterDrivingDirectionMismatch,false:_cbMPFilterRoadTypeMismatch,false:_cbMPFilterRestrictedTurn,false:_cbMPFilterRoadClosureProblem,false:_cbMPFilterUnknownProblem,false:_cbMPFilterTurnProblem,false:_cbFilterElgin,false:_cbFilterTrafficCast,false:_cbFilterTrafficMaster,false:_cbFilterCaltrans,false:_cbFilterTFL,false:_cbMPFilterReopenedProblem,false:_cbInvertMPFilter,false:_cbMPFilterOutsideArea,false:_cbMPFilterClosed,false:_cbMPFilterSolved,false:_cbMPFilterUnidentified,false:_cbMPClosedUserIDFilter,false:_cbMPNotClosedUserIDFilter,false:_cbMPFilterLowSeverity,false:_cbMPFilterMediumSeverity,false:_cbMPFilterHighSeverity,false[END]';
- defaultSettings += '[UROverviewPlaceWatchList][len=0][END]';
- defaultSettings += '[UROverviewSegWatchList][len=0][END]';
- defaultSettings += '[UROverviewPlacesGroups][len=65]false:false:false:false:false:false:false:false:false:false:false[END]';
- defaultSettings += '[UROverviewMasterEnable][len=4]true[END]';
- defaultSettings += '[UROverviewFriendlyAreaNames][len=0][END]';
- defaultSettings += '[UROverviewMiscOptions][len=1337]:_cbNativeConvoMarkers,true:_cbNativeBetaConvoMarkers,true:_cbCommentCount,false:_cbURBackfill,false:_inputUnstackSensitivity,15:_inputUnstackZoomLevel,3:_cbCustomRoadworksMarkers,false:_cbCustomConstructionMarkers,false:_cbCustomClosuresMarkers,false:_cbCustomEventsMarkers,false:_cbCustomNotesMarkers,false:_cbCustomBOGMarkers,false:_cbCustomDifficultMarkers,false:_cbCustomWSLMMarkers,false:_cbCustomNativeSLMarkers,false:_cbCustomKeywordMarkers,false:_textCustomKeyword,:_cbCustomElginMarkers,false:_cbCustomTrafficMasterMarkers,false:_cbCustomTrafficCastMarkers,false:_cbCustomCaltransMarkers,false:_cbCustomTFLMarkers,false:_inputPopupDwellTimeout,2:_inputPopupEntryTimeout,2:_inputMaxJitter,2:_cbInhibitURPopup,false:_cbInhibitMPPopup,false:_cbInhibitCamPopup,false:_cbInhibitSegPopup,false:_cbInhibitSegGenericPopup,false:_cbInhibitTurnsPopup,false:_cbInhibitLandmarkPopup,false:_cbInhibitPUPopup,false:_cbDateFmtDDMMYY,true:_cbDateFmtMMDDYY,false:_cbDateFmtYYMMDD,false:_cbTimeFmt24H,true:_cbTimeFmt12H,false:_cbWhiteBackground,false:_inputCustomBackgroundRed,255:_inputCustomBackgroundGreen,255:_inputCustomBackgroundBlue,255:_cbInhibitNURButton,false:_cbInhibitNMPButton,false:_cbInhibitNPURButton,false:_cbHideAMLayer,false:_cbDisablePlacesFiltering,false:_cbDisableTabStyling,false:_cbHideEditorInfo,false:_cbEnableDTE,false[END]';
- defaultSettings += '[UROverviewUROptions][len=1756]:_cbURFilterOutsideArea,false:_cbNoFilterForURInURL,false:_cbFilterWazeAuto,false:_cbFilterIncorrectTurn,false:_cbFilterIncorrectAddress,false:_cbFilterIncorrectRoute,false:_cbFilterMissingRoundabout,false:_cbFilterGeneralError,false:_cbFilterTurnNotAllowed,false:_cbFilterIncorrectJunction,false:_cbFilterMissingBridgeOverpass,false:_cbFilterWrongDrivingDirection,false:_cbFilterMissingExit,false:_cbFilterMissingRoad,false:_cbFilterBlockedRoad,false:_cbFilterMissingLandmark,false:_cbFilterSpeedLimits,false:_cbFilterUndefined,false:_cbFilterRoadworks,false:_cbFilterConstruction,false:_cbFilterClosure,false:_cbFilterEvent,false:_cbFilterNote,false:_cbFilterBOG,false:_cbFilterDifficult,false:_cbFilterWSLM,false:_cbInvertURFilter,false:_cbFilterOpenUR,false:_cbFilterClosedUR,false:_cbFilterSolved,false:_cbFilterUnidentified,false:_cbEnableMinAgeFilter,false:_inputFilterMinDays,:_cbEnableMaxAgeFilter,false:_inputFilterMaxDays,:_cbHideMyFollowed,false:_cbHideMyUnfollowed,false:_cbURDescriptionMustBePresent,false:_cbURDescriptionMustBeAbsent,false:_cbEnableKeywordMustBePresent,false:_textKeywordPresent,:_cbEnableKeywordMustBeAbsent,false:_textKeywordAbsent,:_cbCaseInsensitive,false:_cbHideMyComments,false:_cbHideAnyComments,false:_cbHideIfLastCommenter,false:_cbHideIfNotLastCommenter,false:_cbHideIfReporterLastCommenter,false:_cbHideIfReporterNotLastCommenter,false:_cbEnableMinCommentsFilter,false:_inputFilterMinComments,:_cbEnableMaxCommentsFilter,false:_inputFilterMaxComments,:_cbEnableCommentAgeFilter2,false:_inputFilterCommentDays2,:_cbEnableCommentAgeFilter,false:_inputFilterCommentDays,:_cbIgnoreOtherEditorComments,false:_cbURUserIDFilter,false:_cbURResolverIDFilter,false:_cbInvertURStateFilter,false:_cbNoFilterForTaggedURs,false[END]';
- defaultSettings += '[UROverviewCameraOptions][len=878]:_cbShowWorldCams,true:_cbShowUSACams,true:_cbShowNonWorldCams,true:_cbShowOnlyCamsCreatedBy,false:_cbShowOnlyCamsEditedBy,false:_textCameraEditor,:_cbShowOnlyMyCams,false:_cbShowApprovedCams,true:_cbShowNonApprovedCams,true:_cbShowOlderCreatedNonApproved,false:_inputCameraMinCreatedDays,:_cbShowOlderUpdatedNonApproved,false:_inputCameraMinUpdatedDays,:_cbShowSpeedCams,true:_cbShowIfSpeedSet,true:_cbShowIfNoSpeedSet,true:_cbShowRedLightCams,true:_cbShowDummyCams,true:_cbHideCreatedByMe,false:_cbHideCreatedByRank0,false:_cbHideCreatedByRank1,false:_cbHideCreatedByRank2,false:_cbHideCreatedByRank3,false:_cbHideCreatedByRank4,false:_cbHideCreatedByRank5,false:_cbHideUpdatedByMe,false:_cbHideUpdatedByRank0,false:_cbHideUpdatedByRank1,false:_cbHideUpdatedByRank2,false:_cbHideUpdatedByRank3,false:_cbHideUpdatedByRank4,false:_cbHideUpdatedByRank5,false:_cbHideCWLCams,false[END]';
- defaultSettings += '[UROverviewCamWatchList][len=0][END]';
- defaultSettings += '[UROverviewPlacesOptions][len=5421]:_cbFilterUneditablePlaceUpdates,false:_cbFilterLockRankedPlaceUpdates,false:_cbFilterNewPlacePUR,false:_cbFilterUpdatedDetailsPUR,false:_cbFilterNewPhotoPUR,false:_cbFilterFlaggedPUR,false:_cbLeavePURGeos,false:_cbInvertPURFilters,false:_cbPURFilterLowSeverity,false:_cbPURFilterMediumSeverity,false:_cbPURFilterHighSeverity,false:_cbEnablePURMinAgeFilter,false:_inputPURFilterMinDays,:_cbEnablePURMaxAgeFilter,false:_inputPURFilterMaxDays,:_cbPlaceFilterEditedLessThan,false:_inputFilterPlaceEditMinDays,:_cbPlaceFilterEditedMoreThan,false:_inputFilterPlaceEditMaxDays,:_cbHidePlacesL0,false:_cbHidePlacesL1,false:_cbHidePlacesL2,false:_cbHidePlacesL3,false:_cbHidePlacesL4,false:_cbHidePlacesL5,false:_cbHidePlacesStaff,false:_cbHidePlacesAdLocked,false:_cbHideAreaPlaces,false:_cbHidePointPlaces,false:_cbHidePhotoPlaces,false:_cbHideNoPhotoPlaces,false:_cbHideLinkedPlaces,false:_cbHideNoLinkedPlaces,false:_cbHideKeywordPlaces,false:_cbHideNoKeywordPlaces,false:_textKeywordPlace,:_cbShowOnlyPlacesCreatedBy,false:_cbShowOnlyPlacesEditedBy,false:_textPlacesEditor,:_cbPlacesFilter-CAR_SERVICES,false:_cbPlacesFilter-GAS_STATION,false:_cbPlacesFilter-GARAGE_AUTOMOTIVE_SHOP,false:_cbPlacesFilter-CAR_WASH,false:_cbPlacesFilter-CHARGING_STATION,false:_cbPlacesFilter-TRANSPORTATION,false:_cbPlacesFilter-AIRPORT,false:_cbPlacesFilter-BUS_STATION,false:_cbPlacesFilter-FERRY_PIER,false:_cbPlacesFilter-SEAPORT_MARINA_HARBOR,false:_cbPlacesFilter-SUBWAY_STATION,false:_cbPlacesFilter-TRAIN_STATION,false:_cbPlacesFilter-BRIDGE,false:_cbPlacesFilter-TUNNEL,false:_cbPlacesFilter-TAXI_STATION,false:_cbPlacesFilter-JUNCTION_INTERCHANGE,false:_cbPlacesFilter-PROFESSIONAL_AND_PUBLIC,false:_cbPlacesFilter-COLLEGE_UNIVERSITY,false:_cbPlacesFilter-SCHOOL,false:_cbPlacesFilter-CONVENTIONS_EVENT_CENTER,false:_cbPlacesFilter-GOVERNMENT,false:_cbPlacesFilter-LIBRARY,false:_cbPlacesFilter-CITY_HALL,false:_cbPlacesFilter-ORGANIZATION_OR_ASSOCIATION,false:_cbPlacesFilter-PRISON_CORRECTIONAL_FACILITY,false:_cbPlacesFilter-COURTHOUSE,false:_cbPlacesFilter-CEMETERY,false:_cbPlacesFilter-FIRE_DEPARTMENT,false:_cbPlacesFilter-POLICE_STATION,false:_cbPlacesFilter-MILITARY,false:_cbPlacesFilter-HOSPITAL_MEDICAL_CARE,false:_cbPlacesFilter-OFFICES,false:_cbPlacesFilter-POST_OFFICE,false:_cbPlacesFilter-RELIGIOUS_CENTER,false:_cbPlacesFilter-KINDERGARDEN,false:_cbPlacesFilter-FACTORY_INDUSTRIAL,false:_cbPlacesFilter-EMBASSY_CONSULATE,false:_cbPlacesFilter-INFORMATION_POINT,false:_cbPlacesFilter-SHOPPING_AND_SERVICES,false:_cbPlacesFilter-ARTS_AND_CRAFTS,false:_cbPlacesFilter-BANK_FINANCIAL,false:_cbPlacesFilter-SPORTING_GOODS,false:_cbPlacesFilter-BOOKSTORE,false:_cbPlacesFilter-PHOTOGRAPHY,false:_cbPlacesFilter-CAR_DEALERSHIP,false:_cbPlacesFilter-FASHION_AND_CLOTHING,false:_cbPlacesFilter-CONVENIENCE_STORE,false:_cbPlacesFilter-PERSONAL_CARE,false:_cbPlacesFilter-DEPARTMENT_STORE,false:_cbPlacesFilter-PHARMACY,false:_cbPlacesFilter-ELECTRONICS,false:_cbPlacesFilter-FLOWERS,false:_cbPlacesFilter-FURNITURE_HOME_STORE,false:_cbPlacesFilter-GIFTS,false:_cbPlacesFilter-GYM_FITNESS,false:_cbPlacesFilter-SWIMMING_POOL,false:_cbPlacesFilter-HARDWARE_STORE,false:_cbPlacesFilter-MARKET,false:_cbPlacesFilter-SUPERMARKET_GROCERY,false:_cbPlacesFilter-JEWELRY,false:_cbPlacesFilter-LAUNDRY_DRY_CLEAN,false:_cbPlacesFilter-SHOPPING_CENTER,false:_cbPlacesFilter-MUSIC_STORE,false:_cbPlacesFilter-PET_STORE_VETERINARIAN_SERVICES,false:_cbPlacesFilter-TOY_STORE,false:_cbPlacesFilter-TRAVEL_AGENCY,false:_cbPlacesFilter-ATM,false:_cbPlacesFilter-CURRENCY_EXCHANGE,false:_cbPlacesFilter-CAR_RENTAL,false:_cbPlacesFilter-FOOD_AND_DRINK,false:_cbPlacesFilter-RESTAURANT,false:_cbPlacesFilter-BAKERY,false:_cbPlacesFilter-DESSERT,false:_cbPlacesFilter-CAFE,false:_cbPlacesFilter-FAST_FOOD,false:_cbPlacesFilter-FOOD_COURT,false:_cbPlacesFilter-BAR,false:_cbPlacesFilter-ICE_CREAM,false:_cbPlacesFilter-CULTURE_AND_ENTERTAINEMENT,false:_cbPlacesFilter-ART_GALLERY,false:_cbPlacesFilter-CASINO,false:_cbPlacesFilter-CLUB,false:_cbPlacesFilter-TOURIST_ATTRACTION_HISTORIC_SITE,false:_cbPlacesFilter-MOVIE_THEATER,false:_cbPlacesFilter-MUSEUM,false:_cbPlacesFilter-MUSIC_VENUE,false:_cbPlacesFilter-PERFORMING_ARTS_VENUE,false:_cbPlacesFilter-GAME_CLUB,false:_cbPlacesFilter-STADIUM_ARENA,false:_cbPlacesFilter-THEME_PARK,false:_cbPlacesFilter-ZOO_AQUARIUM,false:_cbPlacesFilter-RACING_TRACK,false:_cbPlacesFilter-THEATER,false:_cbPlacesFilter-OTHER,false:_cbPlacesFilter-CONSTRUCTION_SITE,false:_cbPlacesFilter-LODGING,false:_cbPlacesFilter-HOTEL,false:_cbPlacesFilter-HOSTEL,false:_cbPlacesFilter-CAMPING_TRAILER_PARK,false:_cbPlacesFilter-COTTAGE_CABIN,false:_cbPlacesFilter-BED_AND_BREAKFAST,false:_cbPlacesFilter-OUTDOORS,false:_cbPlacesFilter-PARK,false:_cbPlacesFilter-PLAYGROUND,false:_cbPlacesFilter-BEACH,false:_cbPlacesFilter-SPORTS_COURT,false:_cbPlacesFilter-GOLF_COURSE,false:_cbPlacesFilter-PLAZA,false:_cbPlacesFilter-PROMENADE,false:_cbPlacesFilter-POOL,false:_cbPlacesFilter-SCENIC_LOOKOUT_VIEWPOINT,false:_cbPlacesFilter-SKI_AREA,false:_cbPlacesFilter-NATURAL_FEATURES,false:_cbPlacesFilter-ISLAND,false:_cbPlacesFilter-SEA_LAKE_POOL,false:_cbPlacesFilter-RIVER_STREAM,false:_cbPlacesFilter-FOREST_GROVE,false:_cbPlacesFilter-FARM,false:_cbPlacesFilter-CANAL,false:_cbPlacesFilter-SWAMP_MARSH,false:_cbPlacesFilter-DAM,false:_cbPlacesFilter-PARKING_LOT,false:_cbFilterPrivatePlaces,false:_cbInvertPlacesFilter,false[END]';
- defaultSettings += '[UROverviewCurrentVersion][len=0][END]';
- defaultSettings += '[UROverviewCWLGroups][len=16]0,No group,false[END]';
- document.getElementById('_txtSettings').value = defaultSettings;
- uroTextToSettings();
- document.getElementById('_txtSettings').value = '';
- }
- function uroSettingsToText()
- {
- var txtSettings = '';
- uroSaveSettings();
- for(var lsEntry in localStorage)
- {
- if(lsEntry.indexOf('UROverview') === 0)
- {
- txtSettings += '['+lsEntry+'][len=' + localStorage[lsEntry].length + ']' + localStorage[lsEntry] + '[END]\n';
- }
- }
- document.getElementById('_txtSettings').value = txtSettings;
- document.getElementById('_txtSettings').focus();
- document.getElementById('_txtSettings').select();
- }
- function uroTextToSettings()
- {
- var txtSettings = '';
- txtSettings = uroGetElmValue('_txtSettings');
- if(txtSettings.indexOf('[END]') == -1) return;
- var subText = txtSettings.split('[END]');
- for(var i=0;i<subText.length;i++)
- {
- var aPos = subText[i].indexOf('[');
- var bPos = subText[i].indexOf(']');
- if((aPos != -1) && (bPos != -1))
- {
- var settingID = subText[i].substr(aPos+1,bPos-1-aPos);
- subText[i] = subText[i].substr(bPos+1);
- bPos = subText[i].indexOf(']');
- if(bPos != -1)
- {
- var settingLength = subText[i].substr(5,bPos-5);
- subText[i] = subText[i].substr(bPos+1);
- if(subText[i].length == settingLength)
- {
- localStorage[settingID] = subText[i];
- }
- }
- }
- }
- uroLoadSettings();
- }
- function uroClearSettingsText()
- {
- document.getElementById('_txtSettings').value = '';
- }
- function uroDateToDays(dateToConvert)
- {
- var dateNow = new Date();
- var elapsedSinceEpoch = dateNow.getTime();
- var elapsedSinceEvent = elapsedSinceEpoch - dateToConvert;
- dateNow.setHours(0);
- dateNow.setMinutes(0);
- dateNow.setSeconds(0);
- dateNow.setMilliseconds(0);
- var elapsedSinceMidnight = elapsedSinceEpoch - dateNow.getTime();
- if(elapsedSinceEvent < elapsedSinceMidnight)
- {
- // event occurred today...
- return 0;
- }
- else
- {
- // event occurred at some point prior to midnight this morning, so return a minimum value of 1...
- return 1 + Math.floor((elapsedSinceEvent - elapsedSinceMidnight) / 86400000);
- }
- }
- function uroGetURAge(urObj,ageType,getRaw)
- {
- if(ageType === 0)
- {
- if((urObj.attributes.driveDate === null)||(urObj.attributes.driveDate === 0)) return -1;
- if(getRaw) return urObj.attributes.driveDate;
- else return uroDateToDays(urObj.attributes.driveDate);
- }
- else if(ageType === 1)
- {
- if((urObj.attributes.resolvedOn === null)||(urObj.attributes.resolvedOn === 0)) return -1;
- if(getRaw) return urObj.attributes.resolvedOn;
- else return uroDateToDays(urObj.attributes.resolvedOn);
- }
- else
- {
- return -1;
- }
- }
- function uroGetMCAge(mcObj,ageType,getRaw)
- {
- if(ageType === 0)
- {
- if((mcObj.attributes.createdOn === null)||(mcObj.attributes.createdOn === 0)) return -1;
- if(getRaw) return mcObj.attributes.createdOn;
- else return uroDateToDays(mcObj.attributes.createdOn);
- }
- else if(ageType === 1)
- {
- if((mcObj.attributes.updatedOn === null)||(mcObj.attributes.updatedOn === 0)) return -1;
- if(getRaw) return mcObj.attributes.updatedOn;
- else return uroDateToDays(mcObj.attributes.updatedOn);
- }
- else
- {
- return -1;
- }
- }
- function uroGetPURAge(purObj)
- {
- if(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded !== null)
- {
- return uroDateToDays(purObj.attributes.venueUpdateRequests[0].attributes.dateAdded);
- }
- else
- {
- return -1;
- }
- }
- function uroGetCameraAge(camObj, mode)
- {
- if(mode === 0)
- {
- if(camObj.attributes.updatedOn === null) return -1;
- return uroDateToDays(camObj.attributes.updatedOn);
- }
- if(mode === 1)
- {
- if(camObj.attributes.createdOn === null) return -1;
- return uroDateToDays(camObj.attributes.createdOn);
- }
- }
- function uroGetCommentAge(commentObj)
- {
- if(commentObj.createdOn === null) return -1;
- return uroDateToDays(commentObj.createdOn);
- }
- function uroParseDaysAgo(days)
- {
- if(days === 0) return 'today';
- else if(days === 1) return '1 day ago';
- else return days+' days ago';
- }
- function uroGetLocalisedSpeedString(camSpeed, includeValidity)
- {
- if(camSpeed !== null)
- {
- var conversionFactor = 1; // default to metric
- var multipleFactor = 10; // default to limits being set in multiples of 10
- var country;
- if(W.model.countries.top === undefined)
- {
- country = W.model.countries.additionalInfo[0].name;
- }
- else
- {
- country = W.model.countries.top.name;
- }
- if(country !== null)
- {
- // country-specific deviations from the above...
- if
- (
- (country == "United Kingdom") ||
- (country == "Jersey") ||
- (country == "Guernsey") ||
- (country == "United States")
- )
- {
- // countries using MPH
- conversionFactor = 1.609;
- }
- if
- (
- (country == "United States") ||
- (country == "Guernsey")
- )
- {
- // countries with speed limits set in multiples of 5
- multipleFactor = 5;
- }
- }
- var speed = Math.round(camSpeed / conversionFactor);
- var retval = speed;
- if(conversionFactor == 1) retval += "KM/H";
- else retval += "MPH";
- if(includeValidity === true)
- {
- // special handling for the 7KM/H spielstrasse found in Germany...
- if(country == "Germany")
- {
- if(speed != 7)
- {
- if(speed % multipleFactor !== 0) retval += " (not valid?)";
- }
- }
- else
- {
- if(speed % multipleFactor !== 0) retval += " (not valid?)";
- }
- }
- return retval;
- }
- else return "not set";
- }
- // --------------------------------------------------------------------------------------------------------------------
- // AREA FRIENDLYNAME STUFF
- // --------------------------------------------------------------------------------------------------------------------
- function uroAFNObj(fName, area, server)
- {
- this.fName = fName;
- this.area = area;
- this.server = server;
- }
- function uroUpdateAreaName(name, server, area)
- {
- var foundExisting = false;
- for(var i=0; i<uroFriendlyAreaNames.length; i++)
- {
- if((uroFriendlyAreaNames[i].server == server) && (uroFriendlyAreaNames[i].area == area))
- {
- if(name === "")
- {
- uroFriendlyAreaNames.splice(i,1);
- foundExisting = true;
- }
- else
- {
- uroFriendlyAreaNames[i].fName = name;
- foundExisting = true;
- }
- }
- }
- if((foundExisting === false) && (name !== ""))
- {
- uroFriendlyAreaNames.push(new uroAFNObj(name,area,server));
- }
- uroReplaceAreaNames(true);
- }
- function uroAreaNameHover()
- {
- if((uroAreaNameHoverObj === null) || (uroAreaNameHoverObj != this))
- {
- uroAreaNameHoverTime = 0;
- }
- uroAreaNameHoverObj = this;
- }
- function uroAreaNameUnHover()
- {
- if(uroANEditHovered === true)
- {
- return false;
- }
- if(uroAreaNameOverlayShown)
- {
- uroAreaNameHoverObj.removeChild(uroANEditBox);
- }
- uroAreaNameHoverObj = null;
- uroAreaNameHoverTime = -1;
- uroAreaNameOverlayShown = false;
- }
- function uroANEditHover()
- {
- uroANEditHovered = true;
- uroAddEventListener('uroANEditBox','mouseout',uroANEditUnHover,false);
- uroAddEventListener('uroANEditBox','click',uroANEditClick,false);
- }
- function uroANEditUnHover()
- {
- var newName = document.getElementById('_textAreaName').value;
- // sanitise name to avoid conflicts with config storage delimiters...
- newName = newName.replace(',','');
- newName = newName.replace(':','');
- var server = W.location.code;
- var area = uroGetAreaArea(uroAreaNameHoverObj.parentNode.children[1]);
- uroAreaNameHoverObj.removeChild(uroANEditBox);
- uroAreaNameOverlayShown = false;
- uroANEditHovered = false;
- uroUpdateAreaName(newName, server, area);
- }
- function uroANEditClick(e)
- {
- // this traps the click to prevent it falling through to the underlying area name element and
- // potentially causing the map view to be relocated to that area...
- e.stopPropagation();
- }
- function uroGetAreaArea(listObj)
- {
- var area = listObj.getElementsByTagName('span')[0].innerHTML;
- area = parseFloat(area.split(' ')[0]);
- return area;
- }
- function uroAreaNameOverlaySetup()
- {
- uroAreaNameOverlayShown = true;
- uroANEditBox = document.createElement('div');
- uroANEditBox.id = "uroANEditBox";
- uroANEditBox.style.position = "absolute";
- uroANEditBox.style.top = '7px';
- uroANEditBox.style.left = '2px';
- uroANEditBox.style.width = "99%";
- uroAreaNameHoverObj.appendChild(uroANEditBox);
- uroANEditBox.onmouseover = uroANEditHover();
- var existingName = uroAreaNameHoverObj.innerHTML;
- var italicTagPos = existingName.indexOf(' <i>');
- if(italicTagPos == -1)
- {
- existingName = "";
- }
- else
- {
- existingName = existingName.substr(0,italicTagPos);
- }
- uroANEditBox.innerHTML = '<input type="text" style="font-size:14px; line-height:16px; height:22px; width:100%" id="_textAreaName" value="'+existingName+'">';
- }
- function uroReplaceAreaNames(replaceAfterNameChange)
- {
- if(document.getElementById('sidepanel-areas') === undefined)
- {
- return;
- }
- if(replaceAfterNameChange === false)
- {
- if(document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id == "friendlyNamed")
- {
- return;
- }
- }
- var panelRootObj = document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0];
- if(panelRootObj === undefined)
- {
- // we get here if the user doesn't have any areas defined...
- return;
- }
- var areaCount = panelRootObj.children.length;
- if(areaCount === 0)
- {
- return;
- }
- var localisedManagedArea = I18n.lookup("user.areas.managed_area");
- for(var loop=0; loop < areaCount; loop++)
- {
- var childObjPElems = panelRootObj.children[loop].getElementsByTagName('p');
- var title = childObjPElems[0].innerHTML;
- if(title.indexOf(localisedManagedArea) > -1)
- {
- var area = uroGetAreaArea(childObjPElems[1]);
- childObjPElems[0].innerHTML = localisedManagedArea;
- for(var fnIdx=0; fnIdx < uroFriendlyAreaNames.length; fnIdx++)
- {
- var fnObj = uroFriendlyAreaNames[fnIdx];
- if((fnObj.area == area) && (fnObj.server == W.location.code))
- {
- childObjPElems[0].innerHTML = fnObj.fName +' <i>('+localisedManagedArea+')</i>';
- break;
- }
- }
- var titleObj = panelRootObj.getElementsByClassName('title')[loop];
- titleObj.addEventListener("mouseover", uroAreaNameHover, false);
- titleObj.addEventListener("mouseout", uroAreaNameUnHover, false);
- titleObj.style.cursor = "text";
- }
- }
- document.getElementById('sidepanel-areas').getElementsByClassName('result-list')[0].id = "friendlyNamed";
- }
- // --------------------------------------------------------------------------------------------------------------------
- // WATCHLIST STUFF
- // --------------------------------------------------------------------------------------------------------------------
- // Generic Functions
- function uroTypeCast(varin)
- {
- if(varin == "null") return null;
- if(typeof varin == "string") return parseInt(varin);
- return varin;
- }
- function uroTruncate(val)
- {
- if(val === null) return val;
- if(val < 0) return Math.ceil(val);
- return Math.floor(val);
- }
- function uroOWLGroupObj(groupID, groupName, groupCollapsed)
- {
- groupID = uroTypeCast(groupID);
- this.groupID = groupID;
- this.groupName = groupName;
- this.groupCount = 0;
- this.groupCollapsed = groupCollapsed;
- }
- // Camera Functions
- function uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon)
- {
- if(type !== null) type = uroTypeCast(type);
- if(azymuth !== null) azymuth = uroTruncate(uroTypeCast(azymuth)%360);
- if(speed !== null) speed = uroTruncate(uroTypeCast(speed));
- if(typeof validated == "string") validated = (validated == "true");
- if(lat !== null) lat = uroTruncate(uroTypeCast(lat));
- if(lon !== null) lon = uroTruncate(uroTypeCast(lon));
- this.type = type;
- this.azymuth = azymuth;
- this.speed = speed;
- this.validated = validated;
- this.lat = lat;
- this.lon = lon;
- }
- function uroCamWatchObj(persistent, fid, lon, lat, type, azymuth, speed, validated, groupID, server)
- {
- fid = uroTypeCast(fid);
- groupID = uroTypeCast(groupID);
- if(typeof persistent == "string") persistent = (persistent == "true");
- this.fid = fid;
- this.persistent = persistent;
- this.loaded = false;
- this.server = server;
- this.groupID = groupID;
- this.watch = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon);
- this.current = new uroCamWatchObjCheckProps(null, null, null, null, null, null);
- }
- function uroCamDataChanged(idx)
- {
- var camObj = uroCamWatchObjects[idx];
- if(camObj.loaded === false) return false;
- if(camObj.current.type != camObj.watch.type) return true;
- if(camObj.current.azymuth != camObj.watch.azymuth) return true;
- if(camObj.current.speed != camObj.watch.speed) return true;
- if(camObj.current.validated != camObj.watch.validated) return true;
- if(camObj.current.lat != camObj.watch.lat) return true;
- if(camObj.current.lon != camObj.watch.lon) return true;
- return false;
- }
- function uroFindCWLGroupByIdx(groupIdx)
- {
- var groupName = '';
- for(var loop=0;loop<uroCWLGroups.length;loop++)
- {
- if(uroCWLGroups[loop].groupID == groupIdx)
- {
- groupName = uroCWLGroups[loop].groupName;
- break;
- }
- }
- return groupName;
- }
- function uroIsCamOnWatchList(fid)
- {
- for(var loop=0;loop<uroCamWatchObjects.length;loop++)
- {
- if(uroCamWatchObjects[loop].fid == fid) return loop;
- }
- return -1;
- }
- function uroAddCurrentCamWatchData(idx, lat, lon, type, azymuth, speed, validated, server)
- {
- var camObj = uroCamWatchObjects[idx];
- camObj.loaded = true;
- camObj.server = server;
- camObj.current = new uroCamWatchObjCheckProps(type, azymuth, speed, validated, lat, lon);
- return(uroCamDataChanged(idx));
- }
- function uroAddCamToWatchList()
- {
- if(uroIsCamOnWatchList(uroShownFID) == -1)
- {
- var camObj = W.model.cameras.objects[uroShownFID];
- uroCamWatchObjects.push(new uroCamWatchObj(true, uroShownFID, camObj.geometry.x, camObj.geometry.y, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, 0, W.location.code));
- uroAddCurrentCamWatchData(uroCamWatchObjects.length-1, camObj.geometry.y, camObj.geometry.x, camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, W.location.code);
- uroAddLog('added camera '+uroShownFID+' to watchlist');
- uroOWLUpdateHTML();
- }
- }
- function uroRemoveCamFromWatchList()
- {
- var camidx = uroIsCamOnWatchList(uroShownFID);
- if(camidx != -1)
- {
- uroCamWatchObjects.splice(camidx,1);
- uroAddLog('removed camera '+uroShownFID+' from watchlist');
- uroOWLUpdateHTML();
- }
- }
- function uroUpdateCamWatchList()
- {
- var camIdx = uroIsCamOnWatchList(uroShownFID);
- if(camIdx != -1)
- {
- var camObj = W.model.cameras.objects[uroShownFID];
- uroCamWatchObjects[camIdx].watch = new uroCamWatchObjCheckProps(camObj.attributes.type, camObj.attributes.azymuth, camObj.attributes.speed, camObj.attributes.validated, camObj.geometry.y, camObj.geometry.x);
- }
- }
- function uroClearCamWatchList()
- {
- uroShowAlertBox("fa-warning", "URO+ Warning", "Removing all cameras from the OWL <b>cannot</b> be undone.<br>Are you <i>sure</i> you want to do this?", true, "Delete ALL Cameras", "Keep Cameras", uroClearCamWatchListAction, null);
- }
- function uroClearCamWatchListAction()
- {
- uroCamWatchObjects = [];
- uroOWLUpdateHTML();
- }
- function uroRetrieveCameras(lat, lon)
- {
- var camPos = new OpenLayers.LonLat();
- var camChanged = false;
- camPos.lon = lon;
- camPos.lat = lat;
- camPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- var camURL = 'https://' + document.location.host;
- camURL += Waze.Config.api_base;
- camURL += '/Features?language=en&cameras=true&bbox=';
- var latl = camPos.lat - 0.25;
- var latu = camPos.lat + 0.25;
- var lonl = camPos.lon - 0.25;
- var lonr = camPos.lon + 0.25;
- camURL += lonl+','+latl+','+lonr+','+latu;
- uroAddLog('retrieving camera data around '+camPos.lon+','+camPos.lat);
- var camReq = new XMLHttpRequest();
- camReq.open('GET',camURL,false);
- try
- {
- camReq.send();
- uroAddLog('response '+camReq.status+' received');
- if (camReq.status === 200)
- {
- var camData = JSON.parse(camReq.responseText);
- for(var camIdx = 0; camIdx < camData.cameras.objects.length; camIdx++)
- {
- var camObj = camData.cameras.objects[camIdx];
- var listIdx = uroIsCamOnWatchList(camObj.id);
- if(listIdx != -1)
- {
- camPos.lon = camObj.geometry.coordinates[0];
- camPos.lat = camObj.geometry.coordinates[1];
- camPos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
- camPos.lon = uroTruncate(camPos.lon);
- camPos.lat = uroTruncate(camPos.lat);
- camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code);
- }
- else if(camObj.validated === false)
- {
- }
- }
- }
- else
- {
- uroAddLog('request failed (status != 200)');
- }
- }
- catch(err)
- {
- uroAddLog('camera load request failed (exception '+err+' caught)');
- }
- return camChanged;
- }
- function uroGetCurrentCamWatchListObjects()
- {
- var camChanged = false;
- var camsChanged = [];
- var camsDeleted = [];
- var camidx;
- var camObj;
- for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- camObj = uroCamWatchObjects[camidx];
- if((camObj.loaded === false) && ((camObj.server == W.location.code) || (camObj.server == '??')))
- {
- if(typeof W.model.cameras.objects[camObj.fid] == 'object')
- {
- if(W.model.cameras.objects[camObj.fid].state != "Delete")
- {
- var wazeObj = W.model.cameras.objects[camObj.fid];
- camChanged |= uroAddCurrentCamWatchData(camidx, wazeObj.geometry.y, wazeObj.geometry.x, wazeObj.attributes.type, wazeObj.attributes.azymuth, wazeObj.attributes.speed, wazeObj.attributes.validated);
- }
- else
- {
- camChanged |= uroRetrieveCameras(camObj.watch.lat, camObj.watch.lon);
- }
- }
- else
- {
- camChanged |= uroRetrieveCameras(camObj.watch.lat, camObj.watch.lon);
- }
- }
- }
- if(camChanged)
- {
- for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- if(uroCamDataChanged(camidx))
- {
- camsChanged.push(uroCamWatchObjects[camidx]);
- }
- }
- }
- for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- camObj = uroCamWatchObjects[camidx];
- if((camObj.loaded === false) && (camObj.server == W.location.code))
- {
- camsDeleted.push(camObj);
- }
- }
- if((camsChanged.length > 0) || (camsDeleted.length > 0))
- {
- var alertStr = '';
- for(camidx=0;camidx<camsChanged.length;camidx++)
- {
- alertStr += 'Camera ID '+camsChanged[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsChanged[camidx].groupID)+'" has been changed<br>';
- }
- alertStr += '<br>';
- for(camidx=0;camidx<camsDeleted.length;camidx++)
- {
- alertStr += 'Camera ID '+camsDeleted[camidx].fid+' in group "'+uroFindCWLGroupByIdx(camsDeleted[camidx].groupID)+'" has been deleted<br>';
- }
- uroShowAlertBox("fa-info-circle", "URO+ Camera Watchlist Alert", alertStr, false, "OK", null, null, null);
- }
- }
- function uroClearDeletedCameras()
- {
- for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
- {
- if(uroCamWatchObjects[camidx].loaded === false)
- {
- uroShownFID = uroCamWatchObjects[camidx].fid;
- uroRemoveCamFromWatchList();
- }
- }
- }
- function uroClearUnknownServerCameras()
- {
- var confirmMsg = '<p>Cameras with an unknown server <i>cannot</i> be automatically verified by URO+</p>';
- confirmMsg += 'It is recommended that you manually load WME from each server (World, USA/Canada and Israel) to give URO+ a chance of locating these cameras.<br>';
- confirmMsg += 'If the cameras then continue to show up as an unknown server, it is safe to delete them...<br><br>';
- confirmMsg += 'Do you still wish to proceed with deleting all unknown server cameras?';
- uroShowAlertBox("fa-warning", "URO+ Warning", confirmMsg, true, "Delete unknown cameras", "Keep unknown cameras", uroClearUnknownServerCamerasAction, null);
- }
- function uroClearUnknownServerCamerasAction()
- {
- for(var camidx=uroCamWatchObjects.length-1;camidx>=0;camidx--)
- {
- if(uroCamWatchObjects[camidx].server == '??')
- {
- uroShownFID = uroCamWatchObjects[camidx].fid;
- uroRemoveCamFromWatchList();
- }
- }
- }
- function uroRescanCamWatchList()
- {
- for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- uroCamWatchObjects[camidx].loaded = false;
- }
- uroGetCurrentCamWatchListObjects();
- uroOWLUpdateHTML();
- }
- function uroGotoCam()
- {
- var camidx = this.id.substr(13);
- var camPos = new OpenLayers.LonLat();
- camPos.lon = uroCamWatchObjects[camidx].watch.lon;
- camPos.lat = uroCamWatchObjects[camidx].watch.lat;
- W.map.setCenter(camPos,4);
- W.map.camerasLayer.setVisibility(true);
- return false;
- }
- // Segment Functions
- /*
- function uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn)
- {
- if(left !== null) left = uroTruncate(uroTypeCast(left));
- if(right !== null) right = uroTruncate(uroTypeCast(right));
- if(bottom !== null) bottom = uroTruncate(uroTypeCast(bottom));
- if(top !== null) top = uroTruncate(uroTypeCast(top));
- if(fromNode !== null) fromNode = uroTypeCast(fromNode);
- if(toNode !== null) toNode = uroTypeCast(toNode);
- if(fwdDir !== null) fwdDir = uroTypeCast(fwdDir);
- if(revDir !== null) revDir = uroTypeCast(revDir);
- if(length !== null) length = uroTypeCast(length);
- if(level !== null) level = uroTypeCast(level);
- if(rank !== null) rank = uroTypeCast(rank);
- if(roadType !== null) roadType = uroTypeCast(roadType);
- if(updatedOn !== null) updatedOn = uroTypeCast(updatedOn);
- this.left = left;
- this.right = right;
- this.bottom = bottom;
- this.top = top;
- this.fromNode = fromNode;
- this.toNode = toNode;
- this.fwdDir = fwdDir;
- this.revDir = revDir;
- this.length = length;
- this.level = level;
- this.rank = rank;
- this.roadType = roadType;
- this.updatedOn = updatedOn;
- }
- function uroSegWatchObj(persistent, fid, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, groupID, server)
- {
- fid = uroTypeCast(fid);
- groupID = uroTypeCast(groupID);
- if(typeof persistent == "string") persistent = (persistent == "true");
- this.fid = fid;
- this.persistent = persistent;
- this.loaded = false;
- this.server = server;
- this.groupID = groupID;
- this.watch = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn);
- this.current = new uroSegWatchObjCheckProps(null, null, null, null, null, null, null, null, null, null, null, null, null);
- }
- function uroSegDataChanged(idx)
- {
- var segObj = uroSegWatchObjects[idx];
- if(segObj.loaded === false) return false;
- if(segObj.current.left != segObj.watch.left) return true;
- if(segObj.current.right != segObj.watch.right) return true;
- if(segObj.current.bottom != segObj.watch.bottom) return true;
- if(segObj.current.top != segObj.watch.top) return true;
- if(segObj.current.fromNode != segObj.watch.fromNode) return true;
- if(segObj.current.toNode != segObj.watch.toNode) return true;
- if(segObj.current.fwdDir != segObj.watch.fwdDir) return true;
- if(segObj.current.revDir != segObj.watch.revDir) return true;
- if(segObj.current.length != segObj.watch.length) return true;
- if(segObj.current.level != segObj.watch.level) return true;
- if(segObj.current.rank != segObj.watch.rank) return true;
- if(segObj.current.roadType != segObj.watch.roadType) return true;
- if(segObj.current.updatedOn != segObj.watch.updatedOn) return true;
- return false;
- }
- function uroIsSegOnWatchList(fid)
- {
- for(var loop=0;loop<uroSegWatchObjects.length;loop++)
- {
- if(uroSegWatchObjects[loop].fid == fid) return loop;
- }
- return -1;
- }
- function uroAddCurrentSegWatchData(idx, left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn, server)
- {
- var segObj = uroSegWatchObjects[idx];
- segObj.loaded = true;
- segObj.server = server;
- segObj.current = new uroSegWatchObjCheckProps(left, right, bottom, top, fromNode, toNode, fwdDir, revDir, length, level, rank, roadType, updatedOn);
- return(uroSegDataChanged(idx));
- }
- function uroClearSegWatchList()
- {
- if(confirm('Removing all segments from the OWL cannot be undone\nAre you sure you want to do this?') === true)
- {
- uroSegWatchObjects = [];
- uroOWLUpdateHTML();
- }
- }
- function uroAddUpdateSegWatchList()
- {
- var selectedCount = W.selectionManager.selectedItems.length;
- if(selectedCount === 0)
- {
- return;
- }
- for(var loop=0;loop < selectedCount; loop++)
- {
- var segObj = W.selectionManager.selectedItems[loop].model.attributes;
- var fid = segObj.id;
- var idx = uroIsSegOnWatchList(fid);
- if(idx != -1)
- {
- uroSegWatchObjects[idx].watch = new uroSegWatchObjCheckProps(segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn);
- uroAddLog('updated watchlist details for segment '+fid);
- }
- else
- {
- uroSegWatchObjects.push(new uroSegWatchObj(true, fid, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, 0, W.location.code));
- uroAddCurrentSegWatchData(uroSegWatchObjects.length-1, segObj.geometry.bounds.left, segObj.geometry.bounds.right, segObj.geometry.bounds.bottom, segObj.geometry.bounds.top, segObj.fromNodeID, segObj.toNodeID, segObj.fwdDirection, segObj.revDirection, segObj.length, segObj.level, segObj.rank, segObj.roadType, segObj.updatedOn, W.location.code);
- uroAddLog('added segment '+fid+' to watchlist');
- }
- }
- //uroOWLUpdateHTML();
- }
- function uroRemoveSegFromWatchList()
- {
- var selectedCount = W.selectionManager.selectedItems.length;
- if(selectedCount === 0)
- {
- return;
- }
- for(var loop=0;loop < selectedCount; loop++)
- {
- var fid = W.selectionManager.selectedItems[loop].model.attributes.id;
- var idx = uroIsSegOnWatchList(fid);
- if(idx != -1)
- {
- uroSegWatchObjects.splice(idx,1);
- uroAddLog('removed segment '+fid+' from watchlist');
- }
- }
- //uroOWLUpdateHTML();
- }
- function uroRetrieveSegments(lat, lon)
- {
- var pos = new OpenLayers.LonLat();
- var changed = false;
- pos.lon = lon;
- pos.lat = lat;
- pos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- var URL = 'https://' + document.location.host;
- URL += Waze.Config.api_base;
- URL += '/Features?roadTypes=1%2C2%2C3%2C4%2C5%2C6%2C7%2C8%2C9%2C10%2C11%2C12%2C13%2C14%2C15%2C16%2C17%2C18%2C19%2C20%2C21';
- URL += '&bbox=';
- var latl = pos.lat - 0.25;
- var latu = pos.lat + 0.25;
- var lonl = pos.lon - 0.25;
- var lonr = pos.lon + 0.25;
- URL += lonl+','+latl+','+lonr+','+latu;
- URL += '&language=en';
- uroAddLog('retrieving segment data around '+pos.lon+','+pos.lat);
- var req = new XMLHttpRequest();
- req.open('GET',URL,false);
- try
- {
- req.send();
- uroAddLog('response '+req.status+' received');
- if (req.status === 200)
- {
- var data = JSON.parse(req.responseText);
- for(var idx = 0; idx < data.segments.objects.length; idx++)
- {
- var obj = data.segments.objects[idx];
- var listIdx = uroIsSegOnWatchList(obj.id);
- if(listIdx != -1)
- {
- //pos.lon = obj.geometry.coordinates[0];
- //pos.lat = obj.geometry.coordinates[1];
- //pos.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
- //camPos.lon = uroTruncate(camPos.lon);
- //camPos.lat = uroTruncate(camPos.lat);
- //camChanged |= uroAddCurrentCamWatchData(listIdx, camPos.lat, camPos.lon, camObj.type, camObj.azymuth, camObj.speed, camObj.validated, W.location.code);
- }
- else if(obj.validated === false)
- {
- }
- }
- }
- else
- {
- uroAddLog('request failed (status != 200)');
- }
- }
- catch(err)
- {
- uroAddLog('segment load request failed (exception '+err+' caught)');
- }
- return changed;
- }
- function uroGetCurrentSegWatchListObjects()
- {
- var segChanged = false;
- var segsChanged = [];
- var segsDeleted = [];
- var idx;
- var segObj;
- for(idx=0;idx<uroSegWatchObjects.length;idx++)
- {
- segObj = uroSegWatchObjects[idx];
- if((segObj.loaded === false) && ((segObj.server == W.location.code) || (segObj.server == '??')))
- {
- var segLat = (segObj.watch.top + segObj.watch.bottom) / 2;
- var segLon = (segObj.watch.right + segObj.watch.left) / 2;
- if(typeof W.model.segments.objects[segObj.fid] == 'object')
- {
- if(W.model.segments.objects[segObj.fid].state != "Delete")
- {
- var wazeObj = W.model.segments.objects[segObj.fid];
- segChanged |= uroAddCurrentSegWatchData(idx, wazeObj.geometry.bounds.left, wazeObj.geometry.bounds.right, wazeObj.geometry.bounds.bottom, wazeObj.geometry.bounds.top, wazeObj.fromNodeID, wazeObj.toNodeID, wazeObj.fwdDirection, wazeObj.revDirection, wazeObj.length, wazeObj.level, wazeObj.rank, wazeObj.roadType, wazeObj.updatedOn, W.location.code);
- }
- else
- {
- segChanged |= uroRetrieveSegments(segLat, segLon);
- }
- }
- else
- {
- segChanged |= uroRetrieveSegments(segLat, segLon);
- }
- }
- }
- if(segChanged)
- {
- for(idx=0;idx<uroSegWatchObjects.length;idx++)
- {
- if(uroSegDataChanged(idx))
- {
- segsChanged.push(uroSegWatchObjects[idx]);
- }
- }
- }
- for(idx=0;idx<uroSegWatchObjects.length;idx++)
- {
- segObj = uroSegWatchObjects[idx];
- if((segObj.loaded === false) && (segObj.server == W.location.code))
- {
- segsDeleted.push(segObj);
- }
- }
- if((segsChanged.length > 0) || (segsDeleted.length > 0))
- {
- var alertStr = 'Segment WatchList Alert!!!\r\n';
- for(idx=0;idx<segsChanged.length;idx++)
- {
- alertStr += 'Segment ID '+segsChanged[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsChanged[idx].groupID)+'" has been changed\r\n';
- }
- for(idx=0;idx<segsDeleted.length;idx++)
- {
- alertStr += 'Segment ID '+segsDeleted[idx].fid+' in group "'+uroFindCWLGroupByIdx(segsDeleted[idx].groupID)+'" has been deleted\r\n';
- }
- alert(alertStr);
- }
- }
- // Places Functions
- function uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn)
- {
- if(left !== null) left = uroTruncate(uroTypeCast(left));
- if(right !== null) right = uroTruncate(uroTypeCast(right));
- if(bottom !== null) bottom = uroTruncate(uroTypeCast(bottom));
- if(top !== null) top = uroTruncate(uroTypeCast(top));
- if(imageCount !== null) imageCount = uroTypeCast(imageCount);
- if(typeof residential == "string") residential = (residential == "true");
- if(updatedOn !== null) updatedOn = uroTypeCast(updatedOn);
- this.left = left;
- this.right = right;
- this.bottom = bottom;
- this.top = top;
- this.name = name;
- this.imageCount = imageCount;
- this.residential = residential;
- this.updatedOn = updatedOn;
- }
- function uroPlaceWatchObj(persistent, fid, left, right, bottom, top, imageCount, name, residential, updatedOn, groupID, server)
- {
- groupID = uroTypeCast(groupID);
- if(typeof persistent == "string") persistent = (persistent == "true");
- this.fid = fid;
- this.persistent = persistent;
- this.loaded = false;
- this.server = server;
- this.groupID = groupID;
- this.watch = new uroPlaceWatchObjCheckProps(left, right, bottom, top, name, imageCount, residential, updatedOn);
- this.current = new uroPlaceWatchObjCheckProps(null, null, null, null, null, null, null, null);
- }
- function uroPlaceDataChanged(idx)
- {
- var placeObj = uroPlaceWatchObjects[idx];
- if(placeObj.loaded === false) return false;
- if(placeObj.current.left != placeObj.watch.left) return true;
- if(placeObj.current.right != placeObj.watch.right) return true;
- if(placeObj.current.bottom != placeObj.watch.bottom) return true;
- if(placeObj.current.top != placeObj.watch.top) return true;
- if(placeObj.current.name != placeObj.watch.name) return true;
- if(placeObj.current.imageCount != placeObj.watch.imageCount) return true;
- if(placeObj.current.residential != placeObj.watch.residential) return true;
- if(placeObj.current.updatedOn != placeObj.watch.updatedOn) return true;
- return false;
- }
- function uroIsPlaceOnWatchList(fid)
- {
- for(var loop=0;loop<uroPlaceWatchObjects.length;loop++)
- {
- if(uroPlaceWatchObjects[loop].fid == fid) return loop;
- }
- return -1;
- }
- function uroClearPlaceWatchList()
- {
- if(confirm('Removing all places from the OWL cannot be undone\nAre you sure you want to do this?') === true)
- {
- uroPlaceWatchObjects = [];
- uroOWLUpdateHTML();
- }
- }
- */
- function uroHighlightCWLEntry()
- {
- this.style.backgroundColor = '#FFFFAA';
- return false;
- }
- function uroUnhighlightCWLEntry()
- {
- var camidx = this.id.substr(8);
- var changed = uroCamDataChanged(camidx);
- var deleted = (uroCamWatchObjects[camidx].loaded === false);
- if(uroCamWatchObjects[camidx].server != W.location.code)
- {
- if(uroCamWatchObjects[camidx].server == '??') this.style.backgroundColor = '#A0A0A0';
- else this.style.backgroundColor = '#AAFFAA';
- }
- else if(changed) this.style.backgroundColor = '#AAAAFF';
- else if(deleted) this.style.backgroundColor = '#FFAAAA';
- else this.style.backgroundColor = '#FFFFFF';
- return false;
- }
- function uroCWLIconHighlight()
- {
- this.style.color="#0000ff";
- return false;
- }
- function uroCWLIconLowlight()
- {
- this.style.color="#ccccff";
- return false;
- }
- function uroPopulateCWLGroupSelect()
- {
- var selector = document.getElementById('_uroCWLGroupSelect');
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- for(var loop=0;loop<uroCWLGroups.length;loop++)
- {
- var groupObj = uroCWLGroups[loop];
- if(groupObj.groupID != -1)
- {
- selector.options.add(new Option(groupObj.groupName,groupObj.groupID));
- }
- }
- }
- function uroGetNextCWLGroupID()
- {
- var nextID = 1;
- for(var loop=0;loop<uroCWLGroups.length;loop++)
- {
- if(uroCWLGroups[loop].groupID >= nextID)
- {
- nextID = uroCWLGroups[loop].groupID + 1;
- }
- }
- return nextID;
- }
- function uroFindCWLGroupByName(groupName)
- {
- var groupID = -1;
- for(var loop=0;loop<uroCWLGroups.length;loop++)
- {
- if((uroCWLGroups[loop].groupName == groupName) && (uroCWLGroups[loop].groupID != -1))
- {
- groupID = uroCWLGroups[loop].groupID;
- break;
- }
- }
- return groupID;
- }
- function uroAddCWLGroup()
- {
- var groupID = uroGetNextCWLGroupID();
- var groupName = uroGetElmValue('_uroCWLGroupEntry');
- if(uroFindCWLGroupByName(groupName) == -1)
- {
- uroCWLGroups.push(new uroOWLGroupObj(groupID,groupName,false));
- uroPopulateCWLGroupSelect();
- }
- }
- function uroRemoveCWLGroup()
- {
- var loop;
- var selector = document.getElementById('_uroCWLGroupSelect');
- var groupID = parseInt(selector.selectedOptions[0].value);
- if(groupID === 0) return false; // prevent deletion of the default group
- for(loop=0;loop<uroCamWatchObjects.length;loop++)
- {
- var cwObj = uroCamWatchObjects[loop];
- if(cwObj.groupID == groupID)
- {
- cwObj.groupID = 0;
- }
- }
- for(loop=0;loop<uroCWLGroups.length;loop++)
- {
- var groupObj = uroCWLGroups[loop];
- if(groupObj.groupID == groupID)
- {
- groupObj.groupID = -1;
- }
- }
- uroOWLUpdateHTML();
- }
- function uroAssignCameraToGroup()
- {
- var camidx = this.id.substr(13);
- var selector = document.getElementById('_uroCWLGroupSelect');
- uroCamWatchObjects[camidx].groupID = parseInt(selector.selectedOptions[0].value);
- uroOWLUpdateHTML();
- return false;
- }
- function uroAddBtnEvl(btnID, evlType, evlFunction)
- {
- var btnObj = document.getElementById(btnID);
- if(btnObj !== null)
- {
- btnObj.addEventListener(evlType, evlFunction, true);
- }
- }
- function uroCWLGroupCollapseExpand()
- {
- var groupidx = this.id.substr(18);
- if(uroCWLGroups[groupidx].groupCollapsed === true) uroCWLGroups[groupidx].groupCollapsed = false;
- else uroCWLGroups[groupidx].groupCollapsed = true;
- uroOWLUpdateHTML();
- return false;
- }
- var uroSelectedOWLGroup = null;
- function uroOWLUpdateHTML(doFullUpdate)
- {
- var camTypes = new Array("","","Speed", "Dummy", "Red Light");
- var iHTML = '';
- if(document.getElementById('_uroCWLGroupSelect') !== null)
- {
- uroSelectedOWLGroup = document.getElementById('_uroCWLGroupSelect').selectedIndex;
- }
- iHTML = '<br><b>Camera Watchlist:</b><br><br>';
- iHTML += '<div id="_uroCWLCamList" style="height:65%;overflow:auto;">';
- if(uroCWLGroups.length > 0)
- {
- var camidx;
- for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
- {
- var groupObj = uroCWLGroups[groupidx];
- iHTML += '<div id="_uroCWLGroup-'+groupidx+'">';
- if(groupObj.groupCollapsed === true)
- {
- iHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroCWLGroupState-'+groupidx+'"></i>';
- }
- else
- {
- iHTML += '<i class="fa fa-minus-square-o" style="cursor:pointer;font-size:14px;" id="_uroCWLGroupState-'+groupidx+'"></i>';
- }
- iHTML += '<b>'+groupObj.groupName+'</b><br>';
- groupObj.groupCount = 0;
- if(uroCamWatchObjects.length > 0)
- {
- for(camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- var camObj = uroCamWatchObjects[camidx];
- if(camObj.groupID == groupObj.groupID)
- {
- groupObj.groupCount++;
- var changed = uroCamDataChanged(camidx);
- var deleted = (camObj.loaded === false);
- iHTML += '<div id="_uroCWL-'+camidx+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF;background-color:';
- if(camObj.server != W.location.code)
- {
- if(camObj.server == '??') iHTML += '#A0A0A0;';
- else iHTML += '#AAFFAA;';
- }
- else if(changed) iHTML += '#AAAAFF;';
- else if(deleted) iHTML += '#FFAAAA;';
- else iHTML += '#FFFFFF;';
- if(groupObj.groupCollapsed === true) iHTML += 'display:none;">';
- else iHTML += 'display:block;">';
- iHTML += 'ID: '+camObj.fid;
- iHTML += ' ('+camObj.server+')';
- iHTML += ' Type: '+camTypes[camObj.watch.type];
- if(camObj.server != W.location.code)
- {
- if(camObj.server == '??')
- {
- iHTML += '<br><i>Unknown server</i>';
- }
- else
- {
- iHTML += '<br><i>Not on this server</i>';
- }
- }
- else if(deleted)
- {
- iHTML += '<br>DELETED';
- }
- else if(changed)
- {
- if(camObj.current.type != camObj.watch.type)
- {
- iHTML += '<br> Type changed';
- iHTML += ' ('+camObj.watch.type+' to '+camObj.current.type+')';
- }
- if(camObj.current.azymuth != camObj.watch.azymuth)
- {
- iHTML += '<br> Azimuth changed';
- iHTML += ' ('+camObj.watch.azymuth+' to '+camObj.current.azymuth+')';
- }
- if(camObj.current.speed != camObj.watch.speed)
- {
- iHTML += '<br> Speed changed';
- iHTML += ' ('+camObj.watch.speed+' to '+camObj.current.speed+')';
- }
- if(camObj.current.validated != camObj.watch.validated)
- {
- iHTML += '<br> Approval state changed';
- iHTML += ' ('+camObj.watch.validated+' to '+camObj.current.validated+')';
- }
- if(camObj.current.lat != camObj.watch.lat)
- {
- iHTML += '<br> Latitude changed';
- iHTML += ' ('+camObj.watch.lat+' to '+camObj.current.lat+')';
- }
- if(camObj.current.lon != camObj.watch.lon)
- {
- iHTML += '<br> Longitude changed';
- iHTML += ' ('+camObj.watch.lon+' to '+camObj.current.lon+')';
- }
- }
- if(camObj.server == W.location.code)
- {
- if(deleted === false)
- {
- iHTML += ' <i class="fa fa-group" style="cursor:pointer;font-size:14px;color:#ccccff;" id="_uroCWLIcon1-'+camidx+'"></i>';
- }
- iHTML += ' <i class="fa fa-arrow-circle-right" style="cursor:pointer;font-size:14px;color:#ccccff;" id="_uroCWLIcon2-'+camidx+'"></i>';
- }
- iHTML += '</div>';
- }
- }
- }
- iHTML += '</div>';
- }
- }
- iHTML += '</div><div id="_uroCWLControls">';
- iHTML += '<hr>Group control:<br>';
- iHTML += '<select id="_uroCWLGroupSelect" style="width:40%;height:22px;"></select> <input type="button" id="_btnCWLGroupDel" value="Delete group"><br>';
- iHTML += '<input type="text" id="_uroCWLGroupEntry" style="width:40%;height:22px;"> <input type="button" id="_btnCWLGroupAdd" value="Add group">';
- iHTML += '<br><input type="button" id="_btnRescanCamWatchList" value="Refresh Camera Data"><br><br>';
- iHTML += '<b>Remove cameras from OWL:</b><br>';
- iHTML += '<input type="button" id="_btnRemoveDeletedCameras" value="Deleted"> ';
- iHTML += '<input type="button" id="_btnRemoveUnknownServerCameras" value="Unknown Server"> ';
- iHTML += '<input type="button" id="_btnClearCamWatchList" value="ALL Cameras">';
- iHTML += '</div>';
- uroOWL.innerHTML = iHTML;
- uroFinaliseOWLHTMLUpdate();
- }
- function uroFinaliseOWLHTMLUpdate()
- {
- if(uroCamWatchObjects.length > 0)
- {
- if(document.getElementById("_uroCWL-0") == null)
- {
- setTimeout(uroFinaliseOWLHTMLUpdate,100);
- return;
- }
- for(var camidx=0;camidx<uroCamWatchObjects.length;camidx++)
- {
- document.getElementById("_uroCWL-"+camidx).onmouseover = uroHighlightCWLEntry;
- document.getElementById("_uroCWL-"+camidx).onmouseleave = uroUnhighlightCWLEntry;
- if(uroCamWatchObjects[camidx].server == W.location.code)
- {
- var icon1 = document.getElementById("_uroCWLIcon1-"+camidx);
- var icon2 = document.getElementById("_uroCWLIcon2-"+camidx);
- if(icon1 !== null)
- {
- icon1.onmouseover = uroCWLIconHighlight;
- icon1.onmouseleave = uroCWLIconLowlight;
- icon1.onclick = uroAssignCameraToGroup;
- }
- if(icon2 !== null)
- {
- icon2.onmouseover = uroCWLIconHighlight;
- icon2.onmouseleave = uroCWLIconLowlight;
- icon2.onclick = uroGotoCam;
- }
- }
- }
- }
- if(document.getElementById('_btnClearCamWatchList') == null)
- {
- setTimeout(uroFinaliseOWLHTMLUpdate,100);
- return;
- }
- uroAddBtnEvl('_btnClearCamWatchList', 'click', uroClearCamWatchList);
- uroAddBtnEvl('_btnRemoveDeletedCameras', 'click', uroClearDeletedCameras);
- uroAddBtnEvl('_btnRemoveUnknownServerCameras', 'click', uroClearUnknownServerCameras);
- uroAddBtnEvl('_btnRescanCamWatchList', 'click', uroRescanCamWatchList);
- uroAddBtnEvl('_btnCWLGroupDel', 'click', uroRemoveCWLGroup);
- uroAddBtnEvl('_btnCWLGroupAdd', 'click', uroAddCWLGroup);
- if(document.getElementById('_uroCWLGroupSelect') !== null)
- {
- uroAddLog('populating CWL group list');
- uroPopulateCWLGroupSelect();
- var selector = document.getElementById('_uroCWLGroupSelect');
- if(uroSelectedOWLGroup >= selector.length)
- {
- uroSelectedOWLGroup = 0;
- }
- selector.selectedIndex = uroSelectedOWLGroup;
- }
- if(uroCWLGroups.length > 0)
- {
- for(var groupidx=0;groupidx<uroCWLGroups.length;groupidx++)
- {
- if(uroCWLGroups[groupidx].groupCount === 0)
- {
- uroSetStyleDisplay('_uroCWLGroup-'+groupidx,'none');
- }
- else
- {
- uroSetOnClick('_uroCWLGroupState-'+groupidx,uroCWLGroupCollapseExpand);
- }
- }
- }
- }
- // --------------------------------------------------------------------------------------------------------------------
- // END OF WATCHLIST STUFF
- // --------------------------------------------------------------------------------------------------------------------
- function uroIsOnIgnoreList(fid)
- {
- if(sessionStorage.UROverview_FID_IgnoreList.indexOf('fid:'+fid) == -1) return false;
- else return true;
- }
- function uroEnableIgnoreListControls()
- {
- var btnState = "visible";
- if(sessionStorage.UROverview_FID_IgnoreList === '')
- {
- btnState = "hidden";
- }
- document.getElementById('_btnUndoLastHide').style.visibility = btnState;
- document.getElementById('_btnClearSessionHides').style.visibility = btnState;
- uroFilterItems();
- }
- function uroAddToIgnoreList()
- {
- if(!uroIsOnIgnoreList(uroShownFID))
- {
- sessionStorage.UROverview_FID_IgnoreList += 'fid:'+uroShownFID;
- uroAddLog('added fid '+uroShownFID+' to ignore list');
- uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
- uroDiv.style.visibility = 'hidden';
- uroEnableIgnoreListControls();
- W.map.events.register("mousemove", null, uroFilterItemsOnMove);
- }
- return false;
- }
- function uroRemoveLastAddedIgnore()
- {
- var ignorelist = sessionStorage.UROverview_FID_IgnoreList;
- var fidpos = ignorelist.lastIndexOf('fid:');
- if(fidpos != -1)
- {
- ignorelist = ignorelist.slice(0,fidpos);
- sessionStorage.UROverview_FID_IgnoreList = ignorelist;
- uroAddLog('removed last fid from ignore list');
- uroAddLog(sessionStorage.UROverview_FID_IgnoreList);
- uroEnableIgnoreListControls();
- }
- }
- function uroRemoveAllIgnores()
- {
- sessionStorage.UROverview_FID_IgnoreList = '';
- uroEnableIgnoreListControls();
- }
- function uroKeywordPresent(desc, keyword)
- {
- var re;
- if(uroGetCBChecked('_cbCaseInsensitive') === true) re = RegExp(keyword,'i');
- else re = RegExp(keyword);
- if(desc.search(re) != -1) return true;
- else return false;
- }
- function uroClickify(desc)
- {
- var linkStartPos = desc.indexOf('http://');
- if(linkStartPos == -1) linkStartPos = desc.indexOf('https://');
- if(linkStartPos != -1)
- {
- var descPreLink = desc.slice(0,linkStartPos);
- var descURL = desc.slice(linkStartPos);
- var linkEndPos = descURL.indexOf(' ');
- var descPostLink = '';
- if(linkEndPos != -1)
- {
- descPostLink = descURL.slice(linkEndPos);
- descURL = descURL.slice(0,linkEndPos);
- }
- var linkTarget = '';
- if(descURL.indexOf('cryosphere') != -1) linkTarget = '_cryosphere';
- else if(descURL.indexOf('waze.com') != -1) linkTarget = '_wazeUR';
- desc = descPreLink + '<a target="'+linkTarget+'" href="'+descURL+'">here</a>' + descPostLink;
- }
- return desc;
- }
- function uroGetUpdateRequestSessions()
- {
- var idList = [];
- while((idList.length < 50) && (uroPendingURSessionIDs.length))
- {
- var id = uroPendingURSessionIDs.shift();
- idList.push(id);
- }
- if(idList.length > 0)
- {
- uroAddLog('grabbing '+idList.length+' updateRequestSessions, IDs: '+idList);
- W.model.updateRequestSessions.get(idList);
- }
- if((uroPendingURSessionIDs.length) || (uroRequestedURSessionIDs.length))
- {
- setTimeout(uroGetUpdateRequestSessions,1000);
- }
- }
- function uroRefreshUpdateRequestSessions()
- {
- var urcount = 0;
- uroPendingURSessionIDs = [];
- uroRequestedURSessionIDs = [];
- for (var urID in W.model.mapUpdateRequests.objects)
- {
- if(W.model.mapUpdateRequests.objects.hasOwnProperty(urID))
- {
- if(W.model.updateRequestSessions.objects[urID] === undefined)
- {
- uroPendingURSessionIDs.push(urID);
- }
- urcount++;
- }
- }
- uroGetUpdateRequestSessions();
- }
- function uroURHasMyComments(fid)
- {
- if(uroUserID === -1) return false;
- var nComments = W.model.updateRequestSessions.objects[fid].comments.length;
- if(nComments === 0) return false;
- for(var cidx=0; cidx<nComments; cidx++)
- {
- if(W.model.updateRequestSessions.objects[fid].comments[cidx].userID == uroUserID) return true;
- }
- return false;
- }
- function uroACMObj(urID, markerType, customType, hasMyComments, nComments)
- {
- this.urID = urID;
- this.markerType = markerType;
- this.customType = customType;
- this.hasMyComments = hasMyComments;
- this.nComments = nComments;
- }
- function uroAddCustomMarkers(urID, markerType, customType, hasMyComments, nComments)
- {
- var useCustomMarker = false;
- if(uroGetCBChecked('_cbMasterEnable') === true)
- {
- if(customType === 0) useCustomMarker = (uroGetCBChecked('_cbCustomRoadworksMarkers'));
- else if(customType === 1) useCustomMarker = (uroGetCBChecked('_cbCustomConstructionMarkers'));
- else if(customType === 2) useCustomMarker = (uroGetCBChecked('_cbCustomClosuresMarkers'));
- else if(customType === 3) useCustomMarker = (uroGetCBChecked('_cbCustomEventsMarkers'));
- else if(customType === 4) useCustomMarker = (uroGetCBChecked('_cbCustomNotesMarkers'));
- else if(customType === 5) useCustomMarker = (uroGetCBChecked('_cbCustomWSLMMarkers'));
- else if(customType === 6) useCustomMarker = (uroGetCBChecked('_cbCustomBOGMarkers'));
- else if(customType === 7) useCustomMarker = (uroGetCBChecked('_cbCustomDifficultMarkers'));
- else if(customType === 98) useCustomMarker = (uroGetCBChecked('_cbCustomNativeSLMarkers'));
- else if(customType === 99) useCustomMarker = (uroGetCBChecked('_cbCustomKeywordMarkers'));
- else if(customType === 100) useCustomMarker = (uroGetCBChecked('_cbCustomElginMarkers'));
- else if(customType === 101) useCustomMarker = (uroGetCBChecked('_cbCustomTrafficCastMarkers'));
- else if(customType === 102) useCustomMarker = (uroGetCBChecked('_cbCustomTrafficMasterMarkers'));
- else if(customType === 103) useCustomMarker = (uroGetCBChecked('_cbCustomCaltransMarkers'));
- else if(customType === 104) useCustomMarker = (uroGetCBChecked('_cbCustomTFLMarkers'));
- }
- if(!useCustomMarker) customType = -1;
- uroCustomMarkerList.push(new uroACMObj(urID, markerType, customType, hasMyComments, nComments));
- }
- function uroRenderCustomMarkers(markerType)
- {
- var urID;
- var elmID;
- var newSpan;
- var divElem;
- var objIdx;
- var customType;
- var cmlObj;
- var defaultMarkerURL = "url('"+document.location.origin + '/assets-editor/sprites/vectors/' + uroNativeMarkerImage+"')";
- var touchedByURO = false;
- if(markerType == 'ur')
- {
- var useDefaultConvoMarker = false;
- var addCommentCount = false;
- if(uroGetCBChecked('_cbMasterEnable') === true)
- {
- if((uroGetCBChecked('_cbNativeConvoMarkers')) && (uroBetaEditor === false)) useDefaultConvoMarker = true;
- if((uroGetCBChecked('_cbNativeBetaConvoMarkers')) && (uroBetaEditor === true)) useDefaultConvoMarker = true;
- if(uroGetCBChecked('_cbCommentCount')) addCommentCount = true;
- }
- else
- {
- useDefaultConvoMarker = true;
- }
- var uRCM_masterEnable = uroGetCBChecked('_cbMasterEnable');
- divElem = document.getElementById(W.map.updateRequestLayer.id);
- if(divElem.childNodes.length > 0)
- {
- for(objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++)
- {
- customType = -1;
- cmlObj = uroCustomMarkerList[objIdx];
- if(cmlObj.markerType == 'ur')
- {
- if(uRCM_masterEnable === true)
- {
- customType = cmlObj.customType;
- }
- if(customType < 100)
- {
- urID = cmlObj.urID;
- var nComments = cmlObj.nComments;
- var iconObj = W.map.updateRequestLayer.markers[urID].icon;
- newSpan = '';
- if(nComments !== 0)
- {
- var classList = iconObj.imageDiv.classList;
- elmID = "commentCount_"+urID;
- if(addCommentCount)
- {
- // add a new comment count bubble if the UR doesn't already have one
- if(document.getElementById(elmID) === null)
- {
- newSpan += '<span id="'+elmID+'" style="position:absolute;top:-9px;left:-11px;pointer-events:none;z-index:1">';
- // define the comment-count holding span within the span used to hold the empty bubble image, and before the image is
- // added to the HTML, to avoid z-indexing issues when adjacent comment count bubbles are overlapped...
- newSpan += '<span id="'+elmID+"_inner"+'" style="position:absolute;top:4px;left:11px;font-size:11px;;pointer-events:none"></span>';
- newSpan += '<img src="'+uroMarkers[0]+'">';
- newSpan += '</span>';
- }
- }
- else
- {
- // remove comment count bubble from this UR marker if one has previously been
- // added and the user has now disabled the option...
- if(document.getElementById(elmID) !== null)
- {
- document.getElementById(elmID).remove();
- }
- if(document.getElementById(elmID+"_inner") !== null)
- {
- document.getElementById(elmID+"_inner").remove();
- }
- }
- elmID = "convoMarker_"+urID;
- if(useDefaultConvoMarker === false)
- {
- if(document.getElementById(elmID) === null)
- {
- var hasMyComments = cmlObj.hasMyComments;
- // z-index needs to be set to 1 here so that when a new comment is added to a UR and WME re-renders the native
- // conversation marker, the custom marker remains on top...
- newSpan += '<span id="'+elmID+'" style="position:absolute;top:-9px;left:18px;pointer-events:none;z-index:1">';
- if(hasMyComments) newSpan += '<img src="'+uroMarkers[2]+'">';
- else newSpan += '<img src="'+uroMarkers[1]+'">';
- newSpan += '</span>';
- classList.remove("has-comments");
- }
- }
- else
- {
- // remove custom conversation marker from this UR if one has previously been
- // added and the user has now disabled this option
- if(document.getElementById(elmID) !== null)
- {
- document.getElementById(elmID).remove();
- }
- if(nComments > 0)
- {
- // only replace the native marker class if the UR has comments - if we're just clearing the custom
- // marker following a master enable switchoff, we don't then want to add native markers to URs which
- // didn't have them in the first place...
- classList.add("has-comments");
- }
- }
- }
- // change main marker if required
- touchedByURO = W.map.updateRequestLayer.markers[urID].touchedByURO;
- /*
- //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
- if(customType != -1)
- {
- if((touchedByURO === undefined) || (touchedByURO === false))
- {
- customType = uroGetCustomMarkerIdx(customType);
- W.map.updateRequestLayer.markers[urID].icon.imageDiv.style.backgroundImage = uroAltMarkers[customType];
- W.map.updateRequestLayer.markers[urID].touchedByURO = true;
- }
- }
- else
- {
- if((touchedByURO === undefined) || (touchedByURO === true))
- {
- W.map.updateRequestLayer.markers[urID].icon.imageDiv.style.backgroundImage = defaultMarkerURL;
- W.map.updateRequestLayer.markers[urID].touchedByURO = false;
- }
- }
- */
- if(newSpan !== '')
- {
- iconObj.$div.prepend(newSpan);
- if(addCommentCount)
- {
- var styleLeft;
- if(nComments < 10) styleLeft = '11px';
- else if(nComments < 100) styleLeft = '8px';
- else styleLeft = '5px';
- elmID = "commentCount_"+urID;
- if(document.getElementById(elmID+"_inner") !== null)
- {
- document.getElementById(elmID+"_inner").innerHTML = nComments;
- document.getElementById(elmID+"_inner").style.left = styleLeft;
- }
- }
- }
- }
- }
- }
- }
- }
- else if(markerType == 'mp')
- {
- divElem = document.getElementById(W.map.problemLayer.id);
- if(divElem.childNodes.length > 0)
- {
- for(objIdx = 0; objIdx < uroCustomMarkerList.length; objIdx++)
- {
- cmlObj = uroCustomMarkerList[objIdx];
- if(cmlObj.markerType == 'mp')
- {
- customType = cmlObj.customType;
- if((customType >= 100) || (customType == -1))
- {
- urID = cmlObj.urID;
- // change main marker if required
- touchedByURO = W.map.problemLayer.markers[urID].touchedByURO;
- /*
- //// TEMPORARY REMOVAL UNTIL CUSTOM ICON SUPPORT IS FIXED IN NEW WME
- if(customType != -1)
- {
- if((touchedByURO === undefined) || (touchedByURO === false))
- {
- customType = uroGetCustomMarkerIdx(customType);
- W.map.problemLayer.markers[urID].icon.imageDiv.style.backgroundImage = uroAltMarkers[customType];
- W.map.problemLayer.markers[urID].touchedByURO = true;
- }
- }
- else
- {
- if((touchedByURO === undefined) || (touchedByURO === true))
- {
- W.map.problemLayer.markers[urID].icon.imageDiv.style.backgroundImage = defaultMarkerURL;
- W.map.problemLayer.markers[urID].touchedByURO = false;
- }
- }
- */
- }
- }
- }
- }
- }
- }
- function uroFilterPlaces()
- {
- if(uroFilterPreamble() === false) return;
- if(uroPlaceSelected === true) return;
- if(uroGetCBChecked('_cbDisablePlacesFiltering') === true) return;
- uroUpdateVenueEditorList();
- var filterNameID = null;
- var tbUserName = uroGetElmValue('_textPlacesEditor');
- var selector = document.getElementById('_selectPlacesUserID');
- if(selector.selectedIndex > 0)
- {
- var selUserName = document.getElementById('_selectPlacesUserID').selectedOptions[0].innerHTML;
- if(selUserName == tbUserName)
- {
- filterNameID = document.getElementById('_selectPlacesUserID').selectedOptions[0].value;
- }
- }
- if(filterNameID === null)
- {
- var userObj = W.model.users.getByAttributes({userName:tbUserName})[0];
- if(userObj !== undefined)
- {
- filterNameID = userObj.id;
- }
- }
- var filterCats = [];
- for(var i=0; i<W.Config.venues.categories.length; i++)
- {
- var parentCategory = W.Config.venues.categories[i];
- var subCategory;
- if(uroGetCBChecked('_cbPlacesFilter-'+parentCategory) === true)
- {
- filterCats.push(parentCategory);
- for(var i1=0; i1<W.Config.venues.subcategories[parentCategory].length; i1++)
- {
- subCategory = W.Config.venues.subcategories[parentCategory][i1];
- filterCats.push(subCategory);
- }
- }
- else
- {
- for(var i2=0; i2<W.Config.venues.subcategories[parentCategory].length; i2++)
- {
- subCategory = W.Config.venues.subcategories[parentCategory][i2];
- if(uroGetCBChecked('_cbPlacesFilter-'+subCategory) === true)
- {
- filterCats.push(subCategory);
- }
- }
- }
- }
- var placeStyle;
- var uFP_filterEditedLessThan = uroGetCBChecked('_cbPlaceFilterEditedLessThan');
- var uFP_filterEditedMoreThan = uroGetCBChecked('_cbPlaceFilterEditedMoreThan');
- var uFP_filterL0 = uroGetCBChecked('_cbHidePlacesL0');
- var uFP_filterL1 = uroGetCBChecked('_cbHidePlacesL1');
- var uFP_filterL2 = uroGetCBChecked('_cbHidePlacesL2');
- var uFP_filterL3 = uroGetCBChecked('_cbHidePlacesL3');
- var uFP_filterL4 = uroGetCBChecked('_cbHidePlacesL4');
- var uFP_filterL5 = uroGetCBChecked('_cbHidePlacesL5');
- var uFP_filterStaff = uroGetCBChecked('_cbHidePlacesStaff');
- var uFP_filterAL = uroGetCBChecked('_cbHidePlacesAdLocked');
- var uFP_filterOnLockLevel = (uFP_filterL0 || uFP_filterL1 || uFP_filterL2 || uFP_filterL3 || uFP_filterL4 || uFP_filterL5 || uFP_filterStaff);
- var uFP_filterNoPhotos = uroGetCBChecked('_cbHideNoPhotoPlaces');
- var uFP_filterWithPhotos = uroGetCBChecked('_cbHidePhotoPlaces');
- var uFP_filterNoLinks = uroGetCBChecked('_cbHideNoLinkedPlaces');
- var uFP_filterWithLinks = uroGetCBChecked('_cbHideLinkedPlaces');
- var uFP_filterNoKeyword = uroGetCBChecked('_cbHideKeywordPlaces');
- var uFP_filterKeyword = uroGetCBChecked('_cbHideNoKeyeordPlaces');
- var uFP_filterPrivate = uroGetCBChecked('_cbFilterPrivatePlaces');
- var uFP_invertFilters = uroGetCBChecked('_cbInvertPlacesFilter');
- var uFP_masterEnable = uroGetCBChecked('_cbMasterEnable');
- var uFP_filterAreaPlaces = uroGetCBChecked('_cbHideAreaPlaces');
- var uFP_filterPointPlaces = uroGetCBChecked('_cbHidePointPlaces');
- var uFP_filterCreatedBy = uroGetCBChecked('_cbShowOnlyPlacesCreatedBy');
- var uFP_filterEditedBy = uroGetCBChecked('_cbShowOnlyPlacesEditedBy');
- var uFP_NameKeyword = document.getElementById('_textKeywordPlace').value.toLowerCase();
- var uFP_thresholdMinDays = document.getElementById('_inputFilterPlaceEditMinDays').value;
- var uFP_thresholdMaxDays = document.getElementById('_inputFilterPlaceEditMaxDays').value;
- for(var v=0; v<W.map.landmarkLayer.features.length; v++)
- {
- placeStyle = 'visible';
- if(uFP_masterEnable === true)
- {
- var lmObj = W.map.landmarkLayer.features[v];
- // when an area place is selected, the drag points for editing the place outline now get added as objects into W.map.landmarkLayer.features,
- // however none of these objects have the .model property - we must therefore check each entry in features[] to see if it has .model before
- // attempting to filter it...
- if(lmObj.model != null)
- {
- if(lmObj.model.attributes.id < 0)
- {
- // don't apply filtering to newly-created places - this allows the user to leave their filtering settings unchanged whilst
- // adding a new place which, once saved, would then be hidden...
- break;
- }
- if(uFP_filterAreaPlaces)
- {
- if(lmObj.model.attributes.geometry.id.indexOf('Polygon') !== -1)
- {
- placeStyle = 'hidden';
- }
- }
- if(uFP_filterPointPlaces)
- {
- if(lmObj.model.attributes.geometry.id.indexOf('Point') !== -1)
- {
- placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if((uFP_filterEditedLessThan) || (uFP_filterEditedMoreThan))
- {
- var editDate = lmObj.model.attributes.updatedOn;
- if(editDate === undefined)
- {
- // where a place has never been edited since its creation, use the creation date instead...
- editDate = lmObj.model.attributes.createdOn;
- }
- if(editDate != null)
- {
- var editDaysAgo = uroDateToDays(editDate);
- if(uFP_filterEditedLessThan)
- {
- if(editDaysAgo < uFP_thresholdMinDays)
- {
- placeStyle = 'hidden';
- }
- }
- if(uFP_filterEditedMoreThan)
- {
- if(editDaysAgo > uFP_thresholdMaxDays)
- {
- placeStyle = 'hidden';
- }
- }
- }
- }
- }
- if(placeStyle == 'visible')
- {
- if(uFP_filterOnLockLevel)
- {
- var lockLevel = lmObj.model.attributes.lockRank;
- if ((uFP_filterL0) && (lockLevel === 0)) placeStyle = 'hidden';
- if ((uFP_filterL1) && (lockLevel === 1)) placeStyle = 'hidden';
- if ((uFP_filterL2) && (lockLevel === 2)) placeStyle = 'hidden';
- if ((uFP_filterL3) && (lockLevel === 3)) placeStyle = 'hidden';
- if ((uFP_filterL4) && (lockLevel === 4)) placeStyle = 'hidden';
- if ((uFP_filterL5) && (lockLevel === 5)) placeStyle = 'hidden';
- if ((uFP_filterStaff) && (lockLevel === 6)) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if(uFP_filterAL)
- {
- if(lmObj.model.attributes.adLocked) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if(uFP_filterNoPhotos || uFP_filterWithPhotos)
- {
- var nPhotos = 0;
- for(var loop=0; loop<lmObj.model.attributes.images.length; loop++)
- {
- if(lmObj.model.attributes.images[loop].attributes.approved) nPhotos++;
- }
- if((uFP_filterNoPhotos) && (nPhotos === 0)) placeStyle = 'hidden';
- if((uFP_filterWithPhotos) && (nPhotos !== 0)) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if(uFP_filterNoLinks || uFP_filterWithLinks)
- {
- var nLinks = lmObj.model.attributes.externalProviderIDs.length;
- if((uFP_filterNoLinks) && (nLinks === 0)) placeStyle = 'hidden';
- if((uFP_filterWithLinks) && (nLinks !== 0)) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if((uFP_filterPrivate === true) && (lmObj.model.attributes.residential === true))
- {
- placeStyle = 'hidden';
- }
- else
- {
- for(var cat=0; cat<filterCats.length; cat++)
- {
- if(lmObj.model.attributes.categories.contains(filterCats[cat]))
- {
- placeStyle = 'hidden';
- break;
- }
- }
- }
- }
- if(placeStyle == 'visible')
- {
- if(uFP_filterNoKeyword || uFP_filterKeyword)
- {
- var venueName = lmObj.model.attributes.name.toLowerCase();
- var noKeywordMatch = true;
- if(uFP_NameKeyword === '')
- {
- noKeywordMatch = (venueName !== '');
- }
- else
- {
- noKeywordMatch = (venueName.indexOf(uFP_NameKeyword) === -1);
- }
- if(!noKeywordMatch && uFP_filterNoKeyword) placeStyle = 'hidden';
- if(noKeywordMatch && uFP_filterKeyword) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- if(filterNameID != null)
- {
- if(uFP_filterCreatedBy === true)
- {
- if(filterNameID != lmObj.model.attributes.createdBy) placeStyle = 'hidden';
- }
- if(uFP_filterEditedBy === true)
- {
- if(filterNameID != lmObj.model.attributes.updatedBy) placeStyle = 'hidden';
- }
- }
- }
- }
- if(uFP_invertFilters === true)
- {
- if(placeStyle == 'hidden') placeStyle = 'visible';
- else placeStyle = 'hidden';
- }
- }
- var geoID = W.map.landmarkLayer.features[v].geometry.id;
- if(document.getElementById(geoID) !== null)
- {
- document.getElementById(geoID).style.visibility = placeStyle;
- }
- }
- var uFP_filterUneditable = uroGetCBChecked('_cbFilterUneditablePlaceUpdates');
- var uFP_filterLockRanked = uroGetCBChecked('_cbFilterLockRankedPlaceUpdates');
- var uFP_filterFlagged = uroGetCBChecked("_cbFilterFlaggedPUR");
- var uFP_filterNewPlace = uroGetCBChecked("_cbFilterNewPlacePUR");
- var uFP_filterUpdatedDetails = uroGetCBChecked("_cbFilterUpdatedDetailsPUR");
- var uFP_filterNewPhoto = uroGetCBChecked("_cbFilterNewPhotoPUR");
- var uFP_filterMinPURAge = uroGetCBChecked('_cbEnablePURMinAgeFilter');
- var uFP_filterMaxPURAge = uroGetCBChecked('_cbEnablePURMaxAgeFilter');
- var uFP_invertPURFilters = uroGetCBChecked('_cbInvertPURFilters');
- var uFP_filterHighSeverity = uroGetCBChecked('_cbPURFilterHighSeverity');
- var uFP_filterMedSeverity = uroGetCBChecked('_cbPURFilterMediumSeverity');
- var uFP_filterLowSeverity = uroGetCBChecked('_cbPURFilterLowSeverity');
- var uFP_leavePURGeos = uroGetCBChecked('_cbLeavePURGeos');
- var uFP_thresholdMinPURDays = uroGetElmValue('_inputPURFilterMinDays');
- var uFP_thresholdMaxPURDays = uroGetElmValue('_inputPURFilterMaxDays');
- var uFP_isLoggedIn = W.loginManager.isLoggedIn();
- var uFP_userRank = W.loginManager.user.rank;
- var purAge = null;
- for(var pu in W.map.placeUpdatesLayer.markers)
- {
- if(W.map.placeUpdatesLayer.markers.hasOwnProperty(pu))
- {
- var puObj = W.map.placeUpdatesLayer.markers[pu];
- if(W.map.placeUpdatesLayer.getVisibility() === true)
- {
- placeStyle = 'visible';
- if(uFP_masterEnable === true)
- {
- if(uFP_masterEnable === true)
- {
- if(uFP_filterUneditable === true)
- {
- if(puObj.model.attributes.permissions === 0)
- {
- placeStyle = 'hidden';
- }
- if((placeStyle == 'visible') && (uFP_isLoggedIn))
- {
- if(uFP_userRank < puObj.model.attributes.lockRank)
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (puObj.model.attributes.adLocked))
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (uFP_filterLockRanked === true))
- {
- if(puObj.model.attributes.lockRank !== 0)
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (uFP_filterFlagged === true))
- {
- if(puObj.icon.imageDiv.className.indexOf('flag') != -1)
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (uFP_filterNewPlace === true))
- {
- if(puObj.icon.imageDiv.className.indexOf('add_venue') != -1)
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (uFP_filterUpdatedDetails === true))
- {
- if((puObj.icon.imageDiv.className.indexOf('update_venue') != -1) || (puObj.icon.imageDiv.className.indexOf('multiple') != -1))
- {
- placeStyle = 'hidden';
- }
- }
- if((placeStyle == 'visible') && (uFP_filterNewPhoto === true))
- {
- if(puObj.icon.imageDiv.className.indexOf('add_image') != -1)
- {
- placeStyle = 'hidden';
- }
- }
- if(uFP_invertPURFilters === true)
- {
- if(placeStyle == 'hidden') placeStyle = 'visible';
- else placeStyle = 'hidden';
- }
- if(uFP_filterMinPURAge || uFP_filterMaxPURAge)
- {
- purAge = uroGetPURAge(puObj.model);
- if(uFP_filterMinPURAge === true)
- {
- if(purAge < uFP_thresholdMinPURDays) placeStyle = 'hidden';
- }
- if(uFP_filterMaxPURAge === true)
- {
- if(purAge > uFP_thresholdMaxPURDays) placeStyle = 'hidden';
- }
- }
- if(placeStyle == 'visible')
- {
- var purSeverity = puObj._getSeverity();
- if((uFP_filterHighSeverity) && (purSeverity == "high")) placeStyle = 'hidden';
- if((placeStyle == 'visible') && (uFP_filterMedSeverity) && (purSeverity == "medium")) placeStyle = 'hidden';
- if((placeStyle == 'visible') && (uFP_filterLowSeverity) && (purSeverity == "low")) placeStyle = 'hidden';
- }
- }
- }
- puObj.icon.imageDiv.style.visibility = placeStyle;
- if(uFP_leavePURGeos === false)
- {
- if(puObj.model != null)
- {
- if(puObj.model.geometry != null)
- {
- var puGeo = document.getElementById(puObj.model.geometry.id);
- if(puGeo !== null)
- {
- puGeo.style.visibility = placeStyle;
- }
- }
- }
- }
- }
- }
- }
- }
- function uroFilterCameras()
- {
- if(uroFilterPreamble() === false) return;
- var camLayer = document.getElementById(uroRootContainer+'_svgRoot');
- if(camLayer === null)
- {
- if(uroNullCamLayer === false)
- {
- uroAddLog('caught null camLayer');
- uroNullCamLayer = true;
- }
- return;
- }
- uroNullCamLayer = false;
- if(uroMouseIsDown === false) W.map.camerasLayer.redraw();
- if(uroGetCBChecked('_cbMasterEnable') === true)
- {
- uroUpdateCamEditorList();
- var filterNameID = null;
- var tbUserName = uroGetElmValue('_textCameraEditor');
- var selector = document.getElementById('_selectCameraUserID');
- if(selector.selectedIndex > 0)
- {
- var selUserName = document.getElementById('_selectCameraUserID').selectedOptions[0].innerHTML;
- if(selUserName == tbUserName)
- {
- filterNameID = document.getElementById('_selectCameraUserID').selectedOptions[0].value;
- }
- }
- if(filterNameID === null)
- {
- var userObj = W.model.users.getByAttributes({userName:tbUserName})[0];
- if(userObj !== undefined)
- {
- filterNameID = userObj.id;
- }
- }
- for (var uroCamObj in W.model.cameras.objects)
- {
- if(W.model.cameras.objects.hasOwnProperty(uroCamObj))
- {
- var uroCamUpdater = '';
- var uroCamUpdaterRank = -1;
- var uroCamCreator = '';
- var uroCamCreatorRank = -1;
- var uroCam = W.model.cameras.objects[uroCamObj];
- var uroCamStyle = 'visible';
- if(uroCam.attributes.createdBy !== null)
- {
- if(W.model.users.objects[uroCam.attributes.createdBy] != null)
- {
- uroCamCreator = W.model.users.objects[uroCam.attributes.createdBy].userName;
- uroCamCreatorRank = W.model.users.objects[uroCam.attributes.createdBy].rank;
- }
- }
- if(uroCam.attributes.updatedBy !== null)
- {
- if(W.model.users.objects[uroCam.attributes.updatedBy] != null)
- {
- uroCamUpdater = W.model.users.objects[uroCam.attributes.updatedBy].userName;
- uroCamUpdaterRank = W.model.users.objects[uroCam.attributes.updatedBy].rank;
- }
- }
- var uroCamApproved = uroCam.attributes.validated;
- var uroCamType = uroCam.attributes.type;
- if(filterNameID != null)
- {
- if(uroGetCBChecked('_cbShowOnlyCamsCreatedBy') === true)
- {
- if(filterNameID != uroCam.attributes.createdBy) uroCamStyle = 'hidden';
- }
- if(uroGetCBChecked('_cbShowOnlyCamsEditedBy') === true)
- {
- if(filterNameID != uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
- }
- }
- if(uroGetCBChecked('_cbShowOnlyMyCams') === true)
- {
- if((uroUserID != uroCam.attributes.createdBy)&&(uroUserID != uroCam.attributes.updatedBy)) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbShowWorldCams') === false) || (uroGetCBChecked('_cbShowUSACams') === false) || (uroGetCBChecked('_cbShowNonWorldCams') === false))
- {
- var posWorld = uroCamCreator.indexOf('world_');
- var posUSA = uroCamCreator.indexOf('usa_');
- if((uroGetCBChecked('_cbShowWorldCams') === false) && (posWorld === 0)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowUSACams') === false) && (posUSA === 0)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowNonWorldCams') === false) && (posWorld !== 0) && (posUSA !== 0)) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbShowApprovedCams') === false) || (uroGetCBChecked('_cbShowNonApprovedCams') === false))
- {
- if((uroGetCBChecked('_cbShowApprovedCams') === false) && (uroCamApproved === true)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowNonApprovedCams') === false) && (uroCamApproved === false)) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbShowNonApprovedCams') === true) && (uroCamApproved === false))
- {
- if(((uroGetCBChecked('_cbShowOlderCreatedNonApproved') === true)) && (uroGetCameraAge(uroCam,1) <= uroGetElmValue('_inputCameraMinCreatedDays'))) uroCamStyle = 'hidden';
- if(((uroGetCBChecked('_cbShowOlderUpdatedNonApproved') === true)) && (uroGetCameraAge(uroCam,0) <= uroGetElmValue('_inputCameraMinUpdatedDays'))) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbShowSpeedCams') === false) || (uroGetCBChecked('_cbShowRedLightCams') === false) || (uroGetCBChecked('_cbShowDummyCams') === false))
- {
- if((uroGetCBChecked('_cbShowSpeedCams') === false) && (uroCamType == 2)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowRedLightCams') === false) && (uroCamType == 4)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowDummyCams') === false) && (uroCamType == 3)) uroCamStyle = 'hidden';
- }
- if(uroGetCBChecked('_cbShowSpeedCams') === true)
- {
- if((uroGetCBChecked('_cbShowIfNoSpeedSet') === false) && (uroCam.attributes.speed === null)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbShowIfSpeedSet') === false) && (uroCam.attributes.speed !== null)) uroCamStyle = 'hidden';
- }
- if(uroGetCBChecked('_cbHideCreatedByMe') === true)
- {
- if(uroUserID == uroCam.attributes.createdBy) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbHideCreatedByRank0') === true) && (uroCamCreatorRank === 0)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCreatedByRank1') === true) && (uroCamCreatorRank == 1)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCreatedByRank2') === true) && (uroCamCreatorRank == 2)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCreatedByRank3') === true) && (uroCamCreatorRank == 3)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCreatedByRank4') === true) && (uroCamCreatorRank == 4)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCreatedByRank5') === true) && (uroCamCreatorRank == 5)) uroCamStyle = 'hidden';
- if(uroGetCBChecked('_cbHideUpdatedByMe') === true)
- {
- if(uroUserID == uroCam.attributes.updatedBy) uroCamStyle = 'hidden';
- }
- if((uroGetCBChecked('_cbHideUpdatedByRank0') === true) && (uroCamUpdaterRank === 0)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideUpdatedByRank1') === true) && (uroCamUpdaterRank == 1)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideUpdatedByRank2') === true) && (uroCamUpdaterRank == 2)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideUpdatedByRank3') === true) && (uroCamUpdaterRank == 3)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideUpdatedByRank4') === true) && (uroCamUpdaterRank == 4)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideUpdatedByRank5') === true) && (uroCamUpdaterRank == 5)) uroCamStyle = 'hidden';
- if((uroGetCBChecked('_cbHideCWLCams') === true) && (uroIsCamOnWatchList(uroCam.attributes.id) != -1)) uroCamStyle = 'hidden';
- var uroCamGeometryID = uroCam.geometry.id;
- if(camLayer.getElementById(uroCamGeometryID) !== null)
- {
- if(uroCamStyle == "hidden")
- {
- camLayer.getElementById(uroCamGeometryID).remove();
- }
- }
- }
- }
- }
- }
- function uroFilterURs_onObjectsChanged()
- {
- if(uroFilterPreamble())
- {
- if(uroBackfilling === false)
- {
- if(uroURDialogIsOpen === false)
- {
- uroURBackfill();
- }
- else
- {
- uroFilterURs();
- }
- }
- }
- }
- function uroFilterURs_onObjectsAdded()
- {
- if(uroFilterPreamble())
- {
- if(uroBackfilling === false)
- {
- uroURBackfill();
- }
- }
- }
- function uroFilterURs_onObjectsRemoved()
- {
- if(uroFilterPreamble())
- {
- if(uroBackfilling === false)
- {
- uroURBackfill();
- }
- }
- }
- function uroBackfillQueueObj(lon, lat, blockSize)
- {
- this.lon = lon;
- this.lat = lat;
- this.blockSize = blockSize;
- }
- function uroURBackfill_GetData()
- {
- if(uroBackfillQueue.length === 0)
- {
- uroBackfilling = false;
- uroFilterURs();
- return;
- }
- var nextBFQueueObj = uroBackfillQueue.shift();
- var lon = parseFloat(nextBFQueueObj.lon);
- var lat = parseFloat(nextBFQueueObj.lat);
- var blockSize = parseFloat(nextBFQueueObj.blockSize);
- uroAddLog('Backfill square '+lon+','+lat);
- var backfillReq = new XMLHttpRequest();
- backfillReq.onreadystatechange = function ()
- {
- if (backfillReq.readyState == 4)
- {
- uroAddLog('backfill data request, response '+backfillReq.status+' received');
- if (backfillReq.status == 200)
- {
- var tResp = JSON.parse(backfillReq.responseText);
- var urCount = tResp.mapUpdateRequests.objects.length;
- uroAddLog(urCount+' URs loaded for backfill processing');
- if(urCount == 500)
- {
- uroAddLog('WARNING - backfill data may have been pre-filtered by server');
- }
- var backfilled = 0;
- for(var i=0; i<urCount; i++)
- {
- var urID = tResp.mapUpdateRequests.objects[i].id;
- if(W.model.mapUpdateRequests.objects[urID] === undefined)
- {
- var newUR = require('Waze/Feature/Vector/UpdateRequest');
- var tUR = new newUR(tResp.mapUpdateRequests.objects[i]);
- var tPoint = new OpenLayers.Geometry.Point();
- tPoint.x = tResp.mapUpdateRequests.objects[i].geometry.coordinates[0];
- tPoint.y = tResp.mapUpdateRequests.objects[i].geometry.coordinates[1];
- tPoint.transform(new OpenLayers.Projection("EPSG:4326"),new OpenLayers.Projection("EPSG:900913"));
- tUR.geometry = tPoint;
- var tReqBounds = new OpenLayers.Geometry.Polygon();
- var tBounds = new OpenLayers.Bounds();
- tBounds.left = tPoint.x;
- tBounds.right = tPoint.x;
- tBounds.top = tPoint.y;
- tBounds.bottom = tPoint.y;
- tReqBounds.bounds = tBounds;
- tUR.requestBounds = tReqBounds;
- W.model.mapUpdateRequests.put(tUR);
- backfilled++;
- }
- }
- uroAddLog(backfilled+' URs backfilled');
- }
- uroURBackfill_GetData();
- }
- };
- var tURL = 'https://' + document.location.host;
- tURL += Waze.Config.api_base;
- tURL += '/Features?language=en&mapUpdateRequestFilter=0';
- tURL += '&bbox='+(lon)+','+(lat)+','+(lon + blockSize)+','+(lat + blockSize);
- backfillReq.open('GET',tURL,true);
- backfillReq.send();
- }
- function uroURBackfill()
- {
- if((uroGetCBChecked('_cbURBackfill') === false) || (uroGetCBChecked('_cbMasterEnable') === false))
- {
- uroFilterURs();
- return;
- }
- var nativeURCount = Object.keys(W.model.mapUpdateRequests.objects).length;
- if(nativeURCount < 500)
- {
- uroAddLog(nativeURCount+' URs loaded natively, no backfilling required');
- uroFilterURs();
- return;
- }
- uroAddLog('exactly 500 URs loaded, possible server-side filtering requiring backfill...');
- var subSize = 0.1;
- var vpWidth = W.map.getExtent().getWidth();
- var vpHeight = W.map.getExtent().getHeight();
- var vpCentre = W.map.getCenter();
- var vpLL = new OpenLayers.LonLat();
- var vpUR = new OpenLayers.LonLat();
- vpLL.lon = vpCentre.lon - (vpWidth / 2);
- vpLL.lat = vpCentre.lat - (vpHeight / 2);
- vpUR.lon = vpCentre.lon + (vpWidth / 2);
- vpUR.lat = vpCentre.lat + (vpHeight / 2);
- vpLL = vpLL.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- vpUR = vpUR.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- vpLL.lon -= (subSize / 2);
- vpLL.lat -= (subSize / 2);
- vpUR.lon += (subSize / 2);
- vpUR.lat += (subSize / 2);
- vpLL.lon = +vpLL.lon.toFixed(1);
- vpLL.lat = +vpLL.lat.toFixed(1);
- vpUR.lon = +vpUR.lon.toFixed(1);
- vpUR.lat = +vpUR.lat.toFixed(1);
- uroBackfilling = true;
- uroBackfillQueue = [];
- for(var bfLat = vpLL.lat; bfLat <= vpUR.lat; bfLat += subSize)
- {
- for(var bfLon = vpLL.lon; bfLon <= vpUR.lon; bfLon += subSize)
- {
- uroBackfillQueue.push(new uroBackfillQueueObj(bfLon, bfLat, subSize));
- }
- }
- uroURBackfill_GetData();
- }
- function uroFilterURs()
- {
- if(uroUserID === -1) return;
- // compatibility fix for URComments - based on code supplied by RickZabel
- var hasActiveURFilters = false;
- if(uroGetCBChecked('_cbMasterEnable') === true)
- {
- var urTabInputs = document.getElementById('uroCtrlURs').getElementsByTagName('input');
- for(var loop = 0; loop < urTabInputs.length; loop++)
- {
- if(urTabInputs[loop].type == 'checkbox')
- {
- var ignoreCB = false;
- ignoreCB = ignoreCB || (urTabInputs[loop].id == '_cbCaseInsensitive');
- ignoreCB = ignoreCB || (urTabInputs[loop].id == '_cbNoFilterForTaggedURs');
- if((urTabInputs[loop].checked) && (ignoreCB === false))
- {
- hasActiveURFilters = true;
- break;
- }
- }
- }
- }
- sessionStorage.UROverview_hasActiveURFilters = hasActiveURFilters;
- if(uroFilterPreamble() === false) return;
- uroRefreshUpdateRequestSessions();
- var selectorResolver = document.getElementById('_selectURResolverID');
- var selectorCommentUser = document.getElementById('_selectURUserID');
- if(uroGetCBChecked('_cbURResolverIDFilter') === false)
- {
- while(selectorResolver.options.length > 0)
- {
- selectorResolver.options.remove(0);
- }
- }
- if(uroGetCBChecked('_cbURUserIDFilter') === false)
- {
- while(selectorCommentUser.options.length > 0)
- {
- selectorCommentUser.options.remove(0);
- }
- }
- if(Object.keys(W.model.updateRequestSessions.objects).length === 0)
- {
- return;
- }
- var commenterUser = null;
- if(uroGetCBChecked('_cbURUserIDFilter') === true)
- {
- if(selectorCommentUser.options.length === 0)
- {
- uroUpdateUserList();
- }
- if(selectorCommentUser.selectedOptions[0] != null)
- {
- commenterUser = parseInt(selectorCommentUser.selectedOptions[0].value);
- }
- }
- var resolverUser = null;
- if(uroGetCBChecked('_cbURResolverIDFilter') === true)
- {
- if(selectorResolver.options.length === 0)
- {
- uroUpdateResolverList();
- }
- if(selectorResolver.selectedOptions[0] != null)
- {
- resolverUser = parseInt(selectorResolver.selectedOptions[0].value);
- }
- }
- uroCustomMarkerList = [];
- var uFURs_masterEnable = uroGetCBChecked('_cbMasterEnable');
- var filterOutsideEditableArea = uroGetCBChecked('_cbURFilterOutsideArea');
- var filterSolved = uroGetCBChecked('_cbFilterSolved');
- var filterUnidentified = uroGetCBChecked('_cbFilterUnidentified');
- var filterClosed = uroGetCBChecked('_cbFilterClosedUR');
- var filterOpen = uroGetCBChecked('_cbFilterOpenUR');
- var filterDescMustBePresent = uroGetCBChecked('_cbURDescriptionMustBePresent');
- var filterDescMustBeAbsent = uroGetCBChecked('_cbURDescriptionMustBeAbsent');
- var filterKeywordMustBePresent = uroGetCBChecked('_cbEnableKeywordMustBePresent');
- var filterKeywordMustBeAbsent = uroGetCBChecked('_cbEnableKeywordMustBeAbsent');
- var filterMinURAge = uroGetCBChecked('_cbEnableMinAgeFilter');
- var filterMaxURAge = uroGetCBChecked('_cbEnableMaxAgeFilter');
- var filterMinComments = uroGetCBChecked('_cbEnableMinCommentsFilter');
- var filterMaxComments = uroGetCBChecked('_cbEnableMaxCommentsFilter');
- var filterReporterLastCommenter = uroGetCBChecked('_cbHideIfReporterLastCommenter');
- var filterReporterNotLastCommenter = uroGetCBChecked('_cbHideIfReporterNotLastCommenter');
- var filterHideAnyComments = uroGetCBChecked('_cbHideAnyComments');
- var filterHideNotLastCommenter = uroGetCBChecked('_cbHideIfNotLastCommenter');
- var filterHideMyComments = uroGetCBChecked('_cbHideMyComments');
- var filterIfLastCommenter = uroGetCBChecked('_cbHideIfLastCommenter');
- var filterIfNotLastCommenter = uroGetCBChecked('_cbHideIfNotLastCommenter');
- var filterCommentMinAge = uroGetCBChecked('_cbEnableCommentAgeFilter2');
- var filterCommentMaxAge = uroGetCBChecked('_cbEnableCommentAgeFilter');
- var filterUserID = uroGetCBChecked('_cbURUserIDFilter');
- var filterMyFollowed = uroGetCBChecked('_cbHideMyFollowed');
- var filterMyUnfollowed = uroGetCBChecked('_cbHideMyUnfollowed');
- var filterWazeAuto = uroGetCBChecked('_cbFilterWazeAuto');
- var filterRoadworks = uroGetCBChecked('_cbFilterRoadworks');
- var filterConstruction = uroGetCBChecked('_cbFilterConstruction');
- var filterClosure = uroGetCBChecked('_cbFilterClosure');
- var filterEvent = uroGetCBChecked('_cbFilterEvent');
- var filterNote = uroGetCBChecked('_cbFilterNote');
- var filterWSLM = uroGetCBChecked('_cbFilterWSLM');
- var filterBOG = uroGetCBChecked('_cbFilterBOG');
- var filterDifficult = uroGetCBChecked('_cbFilterDifficult');
- var filterIncorrectTurn = uroGetCBChecked('_cbFilterIncorrectTurn');
- var filterIncorrectAddress = uroGetCBChecked('_cbFilterIncorrectAddress');
- var filterIncorrectRoute = uroGetCBChecked('_cbFilterIncorrectRoute');
- var filterMissingRoundabout = uroGetCBChecked('_cbFilterMissingRoundabout');
- var filterGeneralError = uroGetCBChecked('_cbFilterGeneralError');
- var filterTurnNotAllowed = uroGetCBChecked('_cbFilterTurnNotAllowed');
- var filterIncorrectJunction = uroGetCBChecked('_cbFilterIncorrectJunction');
- var filterMissingBridgeOverpass = uroGetCBChecked('_cbFilterMissingBridgeOverpass');
- var filterWrongDrivingDirection = uroGetCBChecked('_cbFilterWrongDrivingDirection');
- var filterMissingExit = uroGetCBChecked('_cbFilterMissingExit');
- var filterMissingRoad = uroGetCBChecked('_cbFilterMissingRoad');
- var filterMissingLandmark = uroGetCBChecked('_cbFilterMissingLandmark');
- var filterNativeSpeedLimit = uroGetCBChecked('_cbFilterSpeedLimits');
- var filterBlockedRoad = uroGetCBChecked('_cbFilterBlockedRoad');
- var filterUndefined = uroGetCBChecked('_cbFilterUndefined');
- var invertURFilters = uroGetCBChecked('_cbInvertURFilter');
- var invertURStateFilters = uroGetCBChecked('_cbInvertURStateFilter');
- var noFilterTaggedURs = uroGetCBChecked('_cbNoFilterForTaggedURs');
- var noFilterURInURL = uroGetCBChecked('_cbNoFilterForURInURL');
- var keywordPresent = uroGetElmValue('_textKeywordPresent');
- var keywordAbsent = uroGetElmValue('_textKeywordAbsent');
- var thresholdMinAge = uroGetElmValue('_inputFilterMinDays');
- var thresholdMaxAge = uroGetElmValue('_inputFilterMaxDays');
- var thresholdMinComments = uroGetElmValue('_inputFilterMinComments');
- var thresholdMaxComments = uroGetElmValue('_inputFilterMaxComments');
- var thresholdMaxCommentAge = uroGetElmValue('_inputFilterCommentDays');
- var thresholdMinCommentAge = uroGetElmValue('_inputFilterCommentDays2');
- var ignoreOtherEditorComments = uroGetCBChecked('_cbIgnoreOtherEditorComments');
- var urcFilteringIsActive = false;
- var urcCB = document.getElementById('URCommentsFilterEnabled');
- if(urcCB !== null)
- {
- if(urcCB.checked)
- {
- urcFilteringIsActive = true;
- }
- }
- urcCB = document.getElementById('URCommentUROOnlyMyUR');
- if(urcCB !== null)
- {
- if(urcCB.checked)
- {
- urcFilteringIsActive = true;
- }
- }
- urcCB = document.getElementById('URCommentUROHideTagged');
- if(urcCB !== null)
- {
- if(urcCB.checked)
- {
- urcFilteringIsActive = true;
- }
- }
- for (var urobj in W.model.mapUpdateRequests.objects)
- {
- if(W.model.mapUpdateRequests.objects.hasOwnProperty(urobj))
- {
- var ureq = W.model.mapUpdateRequests.objects[urobj];
- var ureqID = null;
- if(ureq.fid === null) ureqID = ureq.attributes.id;
- else ureqID = ureq.fid;
- var urStyle = 'visible';
- var inhibitFiltering = ((ureqID == uroURIDInURL) && (noFilterURInURL));
- var hasMyComments = false;
- var nComments = 0;
- var customType = uroGetCustomType(ureqID, "ur");
- if(W.model.updateRequestSessions.objects[ureqID] != null)
- {
- nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
- if((uFURs_masterEnable === false) && (nComments === 0))
- {
- // when master enable is turned off, we want to make sure that all URs, including ones that were previously hidden, are correctly
- // displayed in their native form - i.e. no comment count or custom conversation bubbles. The easiest way to achieve this is to
- // force the uroRenderCustomMarkers code to test for the presence of these bubbles on each UR, which we do by setting a non-zero
- // comment count for each UR... For URs which genuinely do have no comments we use -1 to indicate that we're not really setting
- // a comment count, but that we still need to do something that wouldn't be achieved by using 0.
- nComments = -1;
- }
- }
- if((uFURs_masterEnable === true) && (inhibitFiltering === false))
- {
- var wazeauto_ur = false;
- var ukroadworks_ur = false;
- var construction_ur = false;
- var closure_ur = false;
- var event_ur = false;
- var note_ur = false;
- var wslm_ur = false;
- var bog_ur = false;
- var difficult_ur = false;
- var filterByNotIncludedKeyword = false;
- var filterByIncludedKeyword = true;
- var desc = '';
- if(ureq.attributes.description !== null) desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");
- if(customType === 0) ukroadworks_ur = true;
- else if(customType === 1) construction_ur = true;
- else if(customType === 2) closure_ur = true;
- else if(customType === 3) event_ur = true;
- else if(customType === 4) note_ur = true;
- else if(customType === 5) wslm_ur = true;
- else if(customType === 6) bog_ur = true;
- else if(customType === 7) difficult_ur = true;
- // check UR against editable area...
- if(filterOutsideEditableArea === true)
- {
- if(ureq.canEdit() === false) urStyle = 'hidden';
- }
- // check UR against current session ignore list...
- if(uroIsOnIgnoreList(ureqID)) urStyle = 'hidden';
- // state-age filtering
- if(urStyle == 'visible')
- {
- // check against closed/not identified filtering if enabled...
- if(filterSolved === true)
- {
- if(ureq.attributes.resolution === 0) urStyle = 'hidden';
- }
- if(filterUnidentified === true)
- {
- if(ureq.attributes.resolution == 1) urStyle = 'hidden';
- }
- if((ureq.attributes.resolvedOn !== null) && (filterClosed === true))
- {
- urStyle = 'hidden';
- }
- if((ureq.attributes.resolvedOn === null) && (filterOpen === true))
- {
- urStyle = 'hidden';
- }
- if(urStyle == 'visible')
- {
- // check UR against keyword filtering if enabled...
- if(filterDescMustBePresent === true)
- {
- if(desc === '') urStyle = 'hidden';
- }
- if(filterDescMustBeAbsent === true)
- {
- if(desc !== '') urStyle = 'hidden';
- }
- if(filterKeywordMustBePresent === true)
- {
- var keywordIsPresentInDesc = uroKeywordPresent(desc,keywordPresent);
- filterByIncludedKeyword &= (!keywordIsPresentInDesc);
- }
- if(filterKeywordMustBeAbsent === true)
- {
- var keywordIsAbsentInDesc = uroKeywordPresent(desc,keywordAbsent);
- filterByNotIncludedKeyword |= keywordIsAbsentInDesc;
- }
- }
- if(urStyle == 'visible')
- {
- // do age-based filtering if enabled
- if(filterMinURAge === true)
- {
- if(uroGetURAge(ureq,0,false) < thresholdMinAge) urStyle = 'hidden';
- }
- if(filterMaxURAge === true)
- {
- if(uroGetURAge(ureq,0,false) > thresholdMaxAge) urStyle = 'hidden';
- }
- }
- if(urStyle == 'visible')
- {
- if(resolverUser !== null)
- {
- if(ureq.attributes.resolvedBy != resolverUser) urStyle = 'hidden';
- }
- }
- if(urStyle == 'visible')
- {
- // do comments/following filtering
- if(W.model.updateRequestSessions.objects[ureqID] != null)
- {
- nComments = W.model.updateRequestSessions.objects[ureqID].comments.length;
- var commentDaysOld = -1;
- if(filterMinComments === true)
- {
- if(nComments < thresholdMinComments) urStyle = 'hidden';
- }
- if(filterMaxComments === true)
- {
- if(nComments > thresholdMaxComments) urStyle = 'hidden';
- }
- if(nComments > 0)
- {
- var reporterIsLastCommenter = false;
- if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == -1) reporterIsLastCommenter = true;
- if(filterReporterLastCommenter === true)
- {
- if(reporterIsLastCommenter === true) urStyle = 'hidden';
- }
- else if(filterReporterNotLastCommenter === true)
- {
- if(reporterIsLastCommenter === false) urStyle = 'hidden';
- }
- hasMyComments = uroURHasMyComments(ureqID);
- if(hasMyComments === false)
- {
- if(filterHideAnyComments === true) urStyle = 'hidden';
- if(filterHideNotLastCommenter === true) urStyle = 'hidden';
- }
- else
- {
- if(filterHideMyComments === true) urStyle = 'hidden';
- var userIsLastCommenter = false;
- if(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1].userID == uroUserID) userIsLastCommenter = true;
- if(filterIfLastCommenter === true)
- {
- if(userIsLastCommenter === true) urStyle = 'hidden';
- }
- else if(filterIfNotLastCommenter === true)
- {
- if(userIsLastCommenter === false) urStyle = 'hidden';
- }
- }
- var cidx;
- if(ignoreOtherEditorComments === false)
- {
- commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[ureqID].comments[nComments-1]);
- }
- else
- {
- for(cidx=0; cidx<nComments; cidx++)
- {
- var cObj = W.model.updateRequestSessions.objects[ureqID].comments[cidx];
- if((cObj.userID == uroUserID) || (cObj.userID == -1))
- {
- commentDaysOld = uroGetCommentAge(cObj);
- }
- }
- }
- if((filterCommentMinAge === true) && (commentDaysOld != -1))
- {
- if(thresholdMinCommentAge > commentDaysOld) urStyle = 'hidden';
- }
- if((filterCommentMaxAge === true) && (commentDaysOld != -1))
- {
- if(thresholdMaxCommentAge < commentDaysOld) urStyle = 'hidden';
- }
- if((commenterUser !== null) && (urStyle != 'hidden'))
- {
- urStyle = 'hidden';
- for(cidx=0; cidx<nComments; cidx++)
- {
- if(W.model.updateRequestSessions.objects[ureqID].comments[cidx].userID == commenterUser)
- {
- urStyle = 'visible';
- break;
- }
- }
- }
- var commentText = '';
- for(cidx=0; cidx<nComments; cidx++)
- {
- commentText += W.model.updateRequestSessions.objects[ureqID].comments[cidx].text;
- }
- if(filterKeywordMustBePresent === true)
- {
- var keywordIsPresentInComments = uroKeywordPresent(commentText,keywordPresent);
- filterByIncludedKeyword &= (!keywordIsPresentInComments);
- }
- if(filterKeywordMustBeAbsent === true)
- {
- var keywordIsAbsentInComments = uroKeywordPresent(commentText,keywordAbsent);
- filterByNotIncludedKeyword |= keywordIsAbsentInComments;
- }
- }
- else
- {
- if(filterUserID === true)
- {
- urStyle = 'hidden';
- }
- }
- filterByNotIncludedKeyword &= filterKeywordMustBeAbsent;
- filterByIncludedKeyword &= filterKeywordMustBePresent;
- if(filterByNotIncludedKeyword || filterByIncludedKeyword)
- {
- urStyle = 'hidden';
- }
- if(W.model.updateRequestSessions.objects[ureqID].isFollowing === true)
- {
- if(filterMyFollowed === true) urStyle = 'hidden';
- }
- else
- {
- if(filterMyUnfollowed === true) urStyle = 'hidden';
- }
- }
- }
- if(invertURStateFilters === true)
- {
- if(urStyle == 'hidden') urStyle = 'visible';
- else urStyle = 'hidden';
- }
- }
- // type filtering
- if(urStyle == 'visible')
- {
- // Test for Waze automatic URs before any others - these always (?) get inserted as General Error URs,
- // so we can't filter them by type...
- if(desc.indexOf('Waze Automatic:') != -1)
- {
- wazeauto_ur = true;
- }
- if(wazeauto_ur === true)
- {
- if(filterWazeAuto === true) urStyle = 'hidden';
- }
- else if(ukroadworks_ur === true)
- {
- if(filterRoadworks === true) urStyle = 'hidden';
- }
- else if(construction_ur === true)
- {
- if(filterConstruction === true) urStyle = 'hidden';
- }
- else if(closure_ur === true)
- {
- if(filterClosure === true) urStyle = 'hidden';
- }
- else if(event_ur === true)
- {
- if(filterEvent === true) urStyle = 'hidden';
- }
- else if(note_ur === true)
- {
- if(filterNote === true) urStyle = 'hidden';
- }
- else if(wslm_ur === true)
- {
- if(filterWSLM === true) urStyle = 'hidden';
- }
- else if(bog_ur === true)
- {
- if(filterBOG === true) urStyle = 'hidden';
- }
- else if(difficult_ur === true)
- {
- if(filterDifficult === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 6)
- {
- if(filterIncorrectTurn === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 7)
- {
- if (filterIncorrectAddress === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 8)
- {
- if(filterIncorrectRoute === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 9)
- {
- if(filterMissingRoundabout === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 10)
- {
- if(filterGeneralError === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 11)
- {
- if(filterTurnNotAllowed === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 12)
- {
- if(filterIncorrectJunction === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 13)
- {
- if(filterMissingBridgeOverpass === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 14)
- {
- if(filterWrongDrivingDirection === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 15)
- {
- if(filterMissingExit === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 16)
- {
- if(filterMissingRoad === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 18)
- {
- if(filterMissingLandmark === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 19)
- {
- if(filterBlockedRoad === true) urStyle = 'hidden';
- }
- else if(ureq.attributes.type == 23)
- {
- if(filterNativeSpeedLimit === true) urStyle = 'hidden';
- }
- else if(filterUndefined === true) urStyle = 'hidden';
- if(invertURFilters === true)
- {
- if(urStyle == 'hidden') urStyle = 'visible';
- else urStyle = 'hidden';
- }
- }
- // stage-age filtering override for tagged URs
- if(noFilterTaggedURs === true)
- {
- if(ukroadworks_ur === true)
- {
- if(filterRoadworks === false) urStyle = 'visible';
- }
- else if(construction_ur === true)
- {
- if(filterConstruction === false) urStyle = 'visible';
- }
- else if(closure_ur === true)
- {
- if(filterClosure === false) urStyle = 'visible';
- }
- else if(event_ur === true)
- {
- if(filterEvent === false) urStyle = 'visible';
- }
- else if(note_ur === true)
- {
- if(filterNote === false) urStyle = 'visible';
- }
- else if(wslm_ur === true)
- {
- if(filterWSLM === false) urStyle = 'visible';
- }
- }
- }
- // only touch marker visibility if we've got active filter settings, or if URComments is not
- // doing any filtering of its own
- if((hasActiveURFilters === true) || (urcFilteringIsActive === false) || (uFURs_masterEnable === false))
- {
- W.map.updateRequestLayer.markers[urobj].icon.imageDiv.style.visibility = urStyle;
- }
- if(urStyle != 'hidden')
- {
- uroAddCustomMarkers(ureqID,'ur',customType, hasMyComments, nComments);
- }
- }
- }
- uroRenderCustomMarkers('ur');
- }
- function uroGetProblemTypes()
- {
- uroKnownProblemTypeIDs = [];
- uroKnownProblemTypeNames = [];
- var tProblemList = I18n.lookup("problems.types");
- for(var tObj in tProblemList)
- {
- if(tObj !== undefined)
- {
- uroKnownProblemTypeIDs.push(parseInt(tObj));
- uroKnownProblemTypeNames.push(tProblemList[tObj].title);
- }
- }
- }
- function uroFilterProblems()
- {
- if(uroFilterPreamble() === false) return;
- var selector;
- if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') === false) && (uroGetCBChecked('_cbMPClosedUserIDFilter') === false))
- {
- selector = document.getElementById('_selectMPUserID');
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- }
- var solverUser = null;
- if((uroGetCBChecked('_cbMPNotClosedUserIDFilter') === true) || (uroGetCBChecked('_cbMPClosedUserIDFilter') === true))
- {
- selector = document.getElementById('_selectMPUserID');
- if(selector.options.length === 0)
- {
- uroUpdateMPSolverList();
- }
- if(selector.selectedOptions[0] != null)
- {
- solverUser = parseInt(selector.selectedOptions[0].value);
- }
- }
- var urobj;
- var problem;
- var problemStyle;
- var problem_marker_img;
- var uFP_masterEnable = uroGetCBChecked('_cbMasterEnable');
- var filter_OutsideEditableArea = uroGetCBChecked('_cbMPFilterOutsideArea');
- var filter_Solved = uroGetCBChecked('_cbMPFilterSolved');
- var filter_Unidentified = uroGetCBChecked('_cbMPFilterUnidentified');
- var filter_Closed = uroGetCBChecked('_cbMPFilterClosed');
- var filter_NotClosedUserID = uroGetCBChecked('_cbMPNotClosedUserIDFilter');
- var filter_ClosedUserID = uroGetCBChecked('_cbMPClosedUserIDFilter');
- var filter_Reopened = uroGetCBChecked('_cbMPFilterReopenedProblem');
- var filter_LowSeverity = uroGetCBChecked('_cbMPFilterLowSeverity');
- var filter_MediumSeverity = uroGetCBChecked('_cbMPFilterMediumSeverity');
- var filter_HighSeverity = uroGetCBChecked('_cbMPFilterHighSeverity');
- var filter_TurnProblems = uroGetCBChecked('_cbMPFilterTurnProblem');
- var filterTypes = [];
- var i;
- for(i=0; i<uroKnownProblemTypeIDs.length; i++)
- {
- if(uroGetCBChecked('_cbMPFilter_T'+uroKnownProblemTypeIDs[i])) filterTypes.push(uroKnownProblemTypeIDs[i]);
- }
- var filter_TypeUnknown = uroGetCBChecked('_cbMPFilterUnknownProblem');
- var filter_TaggedElgin = uroGetCBChecked('_cbFilterElgin');
- var filter_TaggedTrafficCast = uroGetCBChecked('_cbFilterTrafficCast');
- var filter_TaggedTrafficMaster = uroGetCBChecked('_cbFilterTrafficMaster');
- var filter_TaggedCaltrans = uroGetCBChecked('_cbFilterCaltrans');
- var filter_TaggedTFL = uroGetCBChecked('_cbFilterTFL');
- var filter_Invert = uroGetCBChecked('_cbInvertMPFilter');
- for (urobj in W.model.problems.objects)
- {
- if(W.model.problems.objects.hasOwnProperty(urobj))
- {
- problem = W.model.problems.objects[urobj];
- problemStyle = 'visible';
- var ureqID = null;
- var customType = null;
- if(uFP_masterEnable === true)
- {
- var elgin_mp = false;
- var trafficcast_mp = false;
- var trafficmaster_mp = false;
- var caltrans_mp = false;
- var tfl_mp = false;
- ureqID = problem.attributes.id;
- customType = uroGetCustomType(ureqID, "mp");
- if(customType === 100) elgin_mp = true;
- else if(customType === 101) trafficcast_mp = true;
- else if(customType === 102) trafficmaster_mp = true;
- else if(customType === 103) caltrans_mp = true;
- else if(customType === 104) tfl_mp = true;
- // check problem against current session ignore list...
- if(uroIsOnIgnoreList(ureqID)) problemStyle = 'hidden';
- if(filter_OutsideEditableArea === true)
- {
- if(problem.canEdit() === false)
- {
- problemStyle = 'hidden';
- }
- }
- // check against closed/not identified filtering if enabled...
- problem_marker_img = '';
- if(problem.geometry.id !== null)
- {
- if(document.getElementById(problem.geometry.id) !== null)
- {
- problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
- if(filter_Solved === true)
- {
- if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
- }
- if(filter_Unidentified === true)
- {
- if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
- }
- }
- }
- if(filter_Closed === true)
- {
- if(problem.attributes.open === false)
- {
- problemStyle = 'hidden';
- }
- }
- if(problemStyle == 'visible')
- {
- if(solverUser !== null)
- {
- if((filter_NotClosedUserID === true) && (problem.attributes.resolvedBy == solverUser)) problemStyle = 'hidden';
- if((filter_ClosedUserID === true) && (problem.attributes.resolvedBy != solverUser)) problemStyle = 'hidden';
- }
- }
- if(problemStyle == 'visible')
- {
- var problemType = null;
- if(uroDOMHasTurnProblems)
- {
- problemType = problem.attributes.problemType;
- }
- else
- {
- problemType = problem.attributes.subType;
- }
- if(elgin_mp === true)
- {
- if(filter_TaggedElgin === true) problemStyle = 'hidden';
- }
- else if(trafficcast_mp === true)
- {
- if(filter_TaggedTrafficCast === true) problemStyle = 'hidden';
- }
- else if(trafficmaster_mp === true)
- {
- if(filter_TaggedTrafficMaster === true) problemStyle = 'hidden';
- }
- else if(caltrans_mp === true)
- {
- if(filter_TaggedCaltrans === true) problemStyle = 'hidden';
- }
- else if(tfl_mp === true)
- {
- if(filter_TaggedTFL === true) problemStyle = 'hidden';
- }
- else if(uroKnownProblemTypeIDs.indexOf(problemType) !== -1)
- {
- if(filterTypes.indexOf(problemType) !== -1)
- {
- problemStyle = 'hidden';
- }
- }
- else if(filter_TypeUnknown === true) problemStyle = 'hidden';
- if(filter_Reopened === true)
- {
- if((problem.attributes.open === true) && (problem.attributes.resolvedOn !== null))
- {
- problemStyle = 'hidden';
- }
- }
- if(filter_Invert === true)
- {
- if(problemStyle == 'hidden') problemStyle = 'visible';
- else problemStyle = 'hidden';
- }
- if(problem.attributes.weight <= 3)
- {
- if(filter_LowSeverity === true) problemStyle = 'hidden';
- }
- else if(problem.attributes.weight <= 7)
- {
- if(filter_MediumSeverity === true) problemStyle = 'hidden';
- }
- else if(filter_HighSeverity === true) problemStyle = 'hidden';
- }
- }
- W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle;
- if((problemStyle != 'hidden') && (ureqID !== null) && (customType !== null))
- {
- uroAddCustomMarkers(ureqID,'mp',customType, false, 0);
- }
- }
- }
- if(uroDOMHasTurnProblems)
- {
- for (urobj in W.model.turnProblems.objects)
- {
- if(W.model.turnProblems.objects.hasOwnProperty(urobj))
- {
- problem = W.model.turnProblems.objects[urobj];
- problemStyle = 'visible';
- if(uFP_masterEnable === true)
- {
- // check problem against current session ignore list...
- if(uroIsOnIgnoreList(problem.attributes.id)) problemStyle = 'hidden';
- // check against closed/not identified filtering if enabled...
- problem_marker_img = '';
- if(problem.geometry.id !== null)
- {
- if(document.getElementById(problem.geometry.id) !== null)
- {
- problem_marker_img = document.getElementById(problem.geometry.id).href.baseVal;
- if(filter_Solved === true)
- {
- if(problem_marker_img.indexOf('_solved') != -1) problemStyle = 'hidden';
- }
- if(filter_Unidentified === true)
- {
- if(problem_marker_img.indexOf('_rejected') != -1) problemStyle = 'hidden';
- }
- }
- }
- if(filter_Closed === true)
- {
- if(problem.attributes.open === false)
- {
- problemStyle = 'hidden';
- }
- }
- if(problemStyle == 'visible')
- {
- if(filter_TurnProblems === true) problemStyle = 'hidden';
- if(filter_Reopened === true)
- {
- if((problem.attributes.open === true) && (problem.attributes.resolvedOn !== null))
- {
- problemStyle = 'hidden';
- }
- }
- if(filter_Invert === true)
- {
- if(problemStyle == 'hidden') problemStyle = 'visible';
- else problemStyle = 'hidden';
- }
- }
- }
- W.map.problemLayer.markers[urobj].icon.imageDiv.style.visibility = problemStyle;
- }
- }
- }
- uroRenderCustomMarkers('mp');
- }
- function uroToHex(decValue,digits)
- {
- var modifier = 1;
- for(var i=0; i<digits; i++)
- {
- modifier *= 16;
- }
- decValue = parseInt(decValue);
- decValue += modifier;
- var retval = decValue.toString(16);
- retval = retval.substr(-digits);
- retval = retval.toUpperCase();
- return retval;
- }
- function uroFilterPreamble()
- {
- var mapviewport = document.getElementsByClassName("olMapViewport")[0];
- if(mapviewport === null)
- {
- if(uroNullMapViewport === false)
- {
- uroAddLog('caught null mapviewport');
- uroNullMapViewport = true;
- }
- return false;
- }
- var uiElms = document.getElementById('uroCtrlMisc');
- if(uiElms == null)
- {
- uroAddLog('caught missing UI');
- return false;
- }
- if(uiElms.innerHTML.length === 0)
- {
- uroAddLog('caught empty UI');
- return false;
- }
- uroNullMapViewport = false;
- return true;
- }
- function uroFilterItems_URTabClick()
- {
- uroFilterURs();
- }
- function uroFilterItems_MPTabClick()
- {
- uroFilterProblems();
- }
- function uroFilterItems_PlacesTabClick()
- {
- uroFilterPlaces();
- }
- function uroFilterItems_CamerasTabClick()
- {
- uroFilterCameras();
- }
- function uroFilterItems_MiscTabClick()
- {
- uroFilterItems();
- }
- function uroFilterItems_MasterEnableClick()
- {
- if(uroGetCBChecked('_cbMasterEnable') === false)
- {
- uroHidePopup();
- }
- uroFilterItems();
- }
- function uroScaleTheScaleBar()
- {
- // adjust the scale bar to more accurately reflect true distances at all latitudes
- var currLat = W.map.getCenter().transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326")).lat;
- if((currLat < 85) && (currLat > -85))
- {
- var cosLat = Math.cos((currLat * Math.PI) / 180);
- var scaleElm;
- var elmWidth;
- scaleElm = document.getElementsByClassName('olControlScaleLineTop')[0];
- if(scaleElm.innerHTML.indexOf(' ') !== -1)
- {
- elmWidth = Math.round((scaleElm.clientWidth + 2) / cosLat);
- scaleElm.innerHTML = scaleElm.innerHTML.replace(' ','');
- scaleElm.style.width = elmWidth + 'px';
- }
- scaleElm = document.getElementsByClassName('olControlScaleLineBottom')[0];
- if(scaleElm.innerHTML.indexOf(' ') !== -1)
- {
- elmWidth = Math.round((scaleElm.clientWidth + 2) / cosLat);
- scaleElm.innerHTML = scaleElm.innerHTML.replace(' ','');
- scaleElm.style.width = elmWidth + 'px';
- }
- }
- }
- function uroFilterItems()
- {
- uroScaleTheScaleBar();
- uroFilterProblems();
- uroFilterPlaces();
- uroFilterCameras();
- uroFilterURs();
- }
- function uroFilterItemsOnMove()
- {
- W.map.events.unregister('mousemove',null,uroFilterItemsOnMove);
- uroFilterItems();
- }
- function uroDeleteObject()
- {
- uroAddLog('delete camera ID '+uroShownFID);
- if(W.model.cameras.objects[uroShownFID] === null)
- {
- uroAddLog('camera object not found...');
- return false;
- }
- uroRemoveCamFromWatchList();
- var actionObj = require('Waze/Action/DeleteObject');
- var deleteAction = new actionObj(W.model.cameras.objects[uroShownFID], null);
- W.model.actionManager.add(deleteAction);
- uroExitPopup();
- uroHidePopup();
- return false;
- }
- function uroGetUserNameAndRank(userID)
- {
- var userName;
- var userLevel;
- if(W.model.users.objects[userID] != null)
- {
- userName = W.model.users.objects[userID].userName;
- if(userName === undefined)
- {
- userName = userID;
- }
- userLevel = W.model.users.objects[userID].rank + 1;
- }
- else
- {
- userName = userID;
- userLevel = '?';
- }
- return userName + ' (' + userLevel + ')';
- }
- function uroCheckCommentsForTag(idSrc, customText)
- {
- var ursObj = W.model.updateRequestSessions.objects[idSrc];
- if(typeof(ursObj) == 'undefined') return -1;
- if(ursObj.comments.length === 0) return -1;
- for(var idx=ursObj.comments.length-1; idx>=0; idx--)
- {
- for(var tag=0; tag<uroCustomURTags.length; tag++)
- {
- var keyword = uroCustomURTags[tag];
- if(ursObj.comments[idx].text.indexOf(keyword) != -1)
- {
- return tag;
- }
- }
- if(customText !== '')
- {
- if(ursObj.comments[idx].text.toLowerCase().indexOf(customText) != -1)
- {
- return 99;
- }
- }
- }
- return -1;
- }
- function uroGetCustomMarkerIdx(customType)
- {
- if(customType === 0) return 1; // ROADWORKS
- if(customType === 1) return 1; // CONSTRUCTION
- if(customType === 2) return 0; // CLOSURE
- if(customType === 3) return 4; // EVENT
- if(customType === 4) return 3; // NOTE
- if(customType === 5) return 5; // WSLM
- if(customType === 6) return 11; // BOG
- if(customType === 7) return 12; // DIFFICULT
- if(customType === 98) return 5; // Native speed limit URs
- if(customType === 99) return 2; // custom text
- if(customType === 100) return 6; // ELGIN
- if(customType === 101) return 7; // TRAFFICCAST
- if(customType === 102) return 8; // TRAFFICMASTER
- if(customType === 103) return 9; // CALTRANS
- if(customType === 104) return 10; // TFL
- return -1;
- }
- function uroGetCustomType(idSrc, markerType)
- {
- var desc = '';
- var provider = '';
- var customText = '';
- if(uroGetCBChecked('_cbCustomKeywordMarkers')) customText = document.getElementById('_textCustomKeyword').value.toLowerCase();
- if(markerType == "ur")
- {
- var ureq = W.model.mapUpdateRequests.objects[idSrc];
- // early test for native speed limit URs
- if(ureq.attributes.type == 23) return 98;
- // UR objects always have a .description attribute, which is set to null if empty...
- if(ureq.attributes.description !== null)
- {
- desc = ureq.attributes.description;
- }
- }
- else if(markerType == "mp")
- {
- var mp = W.model.problems.objects[idSrc];
- // ...whereas MP objects with a blank description don't even get the attribute
- if(mp.attributes.description != null)
- {
- desc = mp.attributes.description;
- }
- if(mp.attributes.provider != null)
- {
- provider = mp.attributes.provider;
- }
- }
- if(desc !== '')
- {
- if(markerType == 'ur')
- {
- for(var tag=0; tag<uroCustomURTags.length; tag++)
- {
- var keyword = uroCustomURTags[tag];
- if(desc.indexOf(keyword) != -1)
- {
- return tag;
- }
- }
- }
- if((uroGetCBChecked('_cbCustomKeywordMarkers')) && (customText !== ''))
- {
- if(desc.toLowerCase().indexOf(customText) != -1) return 99;
- }
- if(markerType == 'mp')
- {
- if(desc.indexOf('[Elgin]') != -1) return 100;
- if(desc.indexOf('[TrafficCast]') != -1) return 101;
- if(desc.indexOf('[TM]') != -1) return 102;
- if(desc.indexOf('[Caltrans]') != -1) return 103;
- if(desc.indexOf('[TfL Open Data]') != -1) return 104;
- if(provider.indexOf('London TFL Closures') != -1) return 104;
- }
- }
- if(markerType == "ur")
- {
- return uroCheckCommentsForTag(idSrc, customText);
- }
- return -1;
- }
- function uroFormatRestriction(restObj)
- {
- var retval = '<tr>';
- retval += '<td style="text-align:center;">';
- if((restObj._days & 1) == 1) retval += 'S';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 2) == 2) retval += 'M';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 4) == 4) retval += 'T';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 8) == 8) retval += 'W';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 16) == 16) retval += 'T';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 32) == 32) retval += 'F';
- else retval += '-';
- retval += '</td><td style="text-align:center;">';
- if((restObj._days & 64) == 64) retval += 'S';
- else retval += '-';
- retval += '</td><td>';
- if(restObj._fromDate === null) retval += 'All dates';
- else retval += restObj._fromDate+' to '+restObj._toDate;
- retval += '</td><td>';
- if(restObj._allDay === true) retval += 'All day';
- else retval += restObj._fromTime+' to '+restObj._toTime;
- retval += '</td><td>';
- if(restObj.allVehicleTypes == restObj._vehicleTypes) retval += 'All vehicles';
- else retval += 'Some vehicles';
- retval += '</td><td>';
- if(restObj._description !== null)
- {
- var desc = restObj._description.replace(/<\/?[^>]+(>|$)/g, "");
- desc = uroClickify(desc);
- retval += desc;
- }
- retval += '</td></tr>';
- return retval;
- }
- function uroHidePopup()
- {
- if(uroPopupShown)
- {
- uroDiv.style.visibility = 'hidden';
- uroPopupShown = false;
- uroPopupTimer = -2;
- uroShownFID = -1;
- }
- uroPopupSuppressed = false;
- }
- function uroSuppressPopup()
- {
- uroDiv.style.visibility = 'hidden';
- window.getSelection().removeAllRanges();
- uroPopupSuppressed = true;
- }
- function uroRecentreSessionOnUR()
- {
- W.map.updateRequestLayer.markers[uroShownFID].icon.imageDiv.click();
- W.map.moveTo(W.map.updateRequestLayer.markers[uroShownFID].lonlat, 5);
- uroHidePopup();
- return false;
- }
- function uroRecentreSessionOnMP()
- {
- W.map.problemLayer.markers[uroShownFID].icon.imageDiv.click();
- W.map.moveTo(W.map.problemLayer.markers[uroShownFID].lonlat, 5);
- uroHidePopup();
- return false;
- }
- function uroRecentreSessionOnPUR()
- {
- W.map.placeUpdatesLayer.markers[uroShownFID].icon.imageDiv.click();
- W.map.moveTo(W.map.placeUpdatesLayer.markers[uroShownFID].lonlat, 5);
- uroHidePopup();
- return false;
- }
- function uroRecentreSessionOnVenueNavPoint()
- {
- W.map.moveTo(uroGetVenueNavPoint(uroShownFID), 5);
- uroHidePopup();
- return false;
- }
- function uroGetDateTimeString(ts)
- {
- var tDateObj = new Date(ts);
- var dateLocale;
- var timeLocale;
- if(uroGetCBChecked('_cbDateFmtDDMMYY')) dateLocale = 'en-gb';
- if(uroGetCBChecked('_cbDateFmtMMDDYY')) dateLocale = 'en-us';
- if(uroGetCBChecked('_cbDateFmtYYMMDD')) dateLocale = 'ja';
- if(uroGetCBChecked('_cbTimeFmt24H')) timeLocale = 'en-gb';
- if(uroGetCBChecked('_cbTimeFmt12H')) timeLocale = 'en-us';
- return tDateObj.toLocaleDateString(dateLocale) + ' ' + tDateObj.toLocaleTimeString(timeLocale);
- }
- function uroParsePxString(pxString)
- {
- return parseInt(pxString.split("px")[0]);
- }
- function uroStackListObj(fid,x,y)
- {
- this.fid = fid;
- this.x = uroTypeCast(x);
- this.y = uroTypeCast(y);
- }
- function uroRestackMarkers()
- {
- if(uroStackList.length === 0) return;
- var markerCollection = null;
- if(uroStackType == 1) markerCollection = W.map.updateRequestLayer.markers;
- else if(uroStackType == 2) markerCollection = W.map.problemLayer.markers;
- else if(uroStackType == 3) markerCollection = W.map.placeUpdatesLayer.markers;
- if(markerCollection !== null)
- {
- uroAddLog('restacking markers...');
- // strip off the .realX/realY attributes from any UR object we've previously added it to, to allow
- // the native recentering to work again...
- for(var marker in markerCollection)
- {
- if(markerCollection.hasOwnProperty(marker))
- {
- var testMarkerObj = markerCollection[marker];
- if(testMarkerObj.model.attributes.geometry.realX != null)
- {
- testMarkerObj.model.attributes.geometry.x = testMarkerObj.model.attributes.geometry.realX;
- testMarkerObj.model.attributes.geometry.y = testMarkerObj.model.attributes.geometry.realY;
- delete(testMarkerObj.model.attributes.geometry.realX);
- delete(testMarkerObj.model.attributes.geometry.realY);
- }
- }
- }
- // now restack any markers that were repositioned...
- for(var idx=0; idx<uroStackList.length; idx++)
- {
- var orig_x = uroStackList[idx].x + 'px';
- var orig_y = uroStackList[idx].y + 'px';
- var fid = uroStackList[idx].fid;
- if(markerCollection[fid] != null)
- {
- markerCollection[fid].icon.imageDiv.style.left = orig_x;
- markerCollection[fid].icon.imageDiv.style.top = orig_y;
- }
- }
- uroStackList = [];
- uroUnstackedMasterID = null;
- uroStackType = null;
- }
- }
- function uroIsIDAlreadyUnstacked(idSrc)
- {
- if(uroStackList.length === 0) return false;
- for(var idx=0; idx<uroStackList.length; idx++)
- {
- if(uroStackList[idx].fid == idSrc) return true;
- }
- return false;
- }
- function uroCheckStacking(stackType, masterID, unstackedX, unstackedY)
- {
- if(uroIsIDAlreadyUnstacked(masterID) === true) return;
- if(uroStackType !== null) return;
- if(uroPopupDwellTimer > 0) return;
- uroAddLog('checking for marker stack, masterID: '+masterID+', stackType: '+stackType);
- var stackList = [];
- stackList.push(masterID);
- var threshSquared = uroGetElmValue('_inputUnstackSensitivity');
- threshSquared *= threshSquared;
- var markerCollection = null;
- var marker;
- if(stackType == 1) markerCollection = W.map.updateRequestLayer.markers;
- else if(stackType == 2) markerCollection = W.map.problemLayer.markers;
- else if(stackType == 3) markerCollection = W.map.placeUpdatesLayer.markers;
- var offset = 1000000000;
- if(markerCollection !== null)
- {
- for(marker in markerCollection)
- {
- if(markerCollection.hasOwnProperty(marker))
- {
- var testMarkerObj = markerCollection[marker];
- var includeInStack = (testMarkerObj.icon.imageDiv.style.visibility != 'hidden');
- var suppressClosed = (testMarkerObj.icon.imageDiv.classList.contains("recently-closed") & (W.map.updateRequestLayer.showHidden === false));
- // if multiple markers are stacked exactly on top of one another, WME will always open up the one which it would have rendered on the
- // top of the stack in the absence of any URO+ filtering, regardless of which UR pin actually receives the click event. To prevent
- // this, we give each pin in the stack a unique set of false coordinates, storing the original coordinates in newly created
- // properties so they can be restored later on
- //
- // originally this fix changed the x coordinate for each UR in the stack to be a unique value that ought to have been well out of the range
- // of any real coordinate and therefore unable to clash with any UR marker coordinates that weren't in the current stack. However it now
- // appears this could then cause WME to think a completely different UR was being opened - possibly as a result of some change in coordinate
- // handling allowing out of range values to be wrapped around back into the normal range? As a workaround for this new WME behaviour, both the
- // x and y coordinates are now set to valid values somewhere in the North Atlantic Ocean - the likelihood of there being any real URs in this
- // area is so vanishingly small as to be not worth worrying about...
- if(testMarkerObj.model.attributes.geometry.realX === undefined)
- {
- testMarkerObj.model.attributes.geometry.realX = testMarkerObj.model.attributes.geometry.x;
- testMarkerObj.model.attributes.geometry.x += offset;
- testMarkerObj.model.attributes.geometry.realY = testMarkerObj.model.attributes.geometry.y;
- testMarkerObj.model.attributes.geometry.y += offset;
- offset += 1000;
- }
- if((includeInStack) && (!suppressClosed))
- {
- if(testMarkerObj.id != masterID)
- {
- var xdiff = unstackedX - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.left);
- var ydiff = unstackedY - uroParsePxString(markerCollection[testMarkerObj.id].icon.imageDiv.style.top);
- var distSquared = ((xdiff * xdiff) + (ydiff * ydiff));
- if(distSquared < threshSquared)
- {
- stackList.push(testMarkerObj.id);
- }
- }
- }
- }
- }
- }
- // as it's the fiddling with .geometry.x which seems to inhibit the autocentering behaviour when a UR/MP marker is clicked, we need to
- // allow this to occur even if unstacking isn't required at this zoom level. To then reenable recentering when clicking on the crosshairs
- // or feed entry, we need to reinstate the correct .x value once the marker is no longer being highlighted, which means we pretty much need
- // to do all of the unstacking *except* for actually unstacking the stack and hiding the other markers...
- var inhibitUnstacking = (W.map.getZoom() < uroGetElmValue('_inputUnstackZoomLevel'));
- // also inhibit unstacking if there's only a single marker in the list - this will be true if we're highlighting an isolated marker that
- // doesn't need to be unstacked, and where we're only using the .geometry.x fiddle to prevent autocentering...
- inhibitUnstacking |= (stackList.length == 1);
- uroStackType = stackType;
- if(stackList.length > 0)
- {
- if(inhibitUnstacking) uroAddLog('single marker highlighted, adjusting geometry properties to prevent recentering...');
- else uroAddLog('markers are stacked!');
- if(uroUnstackedMasterID != masterID)
- {
- uroAddLog('unstacked ID mismatch, relocating markers...');
- uroRestackMarkers();
- uroUnstackedMasterID = masterID;
- uroStackList = [];
- // push the highlighted marker onto the stacklist so uroIsIDAlreadyUnstacked() will return true
- uroStackList.push(new uroStackListObj(masterID,unstackedX,unstackedY));
- for(var shoveIdx=0; shoveIdx < stackList.length; shoveIdx++)
- {
- var fid = stackList[shoveIdx];
- var x = uroParsePxString(markerCollection[fid].icon.imageDiv.style.left);
- var y = uroParsePxString(markerCollection[fid].icon.imageDiv.style.top);
- // store the unstacked marker positions so they can be reinstated later
- uroStackList.push(new uroStackListObj(fid,x,y));
- if(!inhibitUnstacking)
- {
- markerCollection[fid].icon.imageDiv.style.left = unstackedX + 'px';
- markerCollection[fid].icon.imageDiv.style.top = unstackedY + 'px';
- unstackedX += 10;
- unstackedY -= 30;
- }
- }
- if(!inhibitUnstacking)
- {
- // hide other markers to prevent confusion with the unstacked markers
- for(marker in markerCollection)
- {
- if(markerCollection.hasOwnProperty(marker))
- {
- var toHideID = markerCollection[marker].id;
- if(uroIsIDAlreadyUnstacked(toHideID) === false)
- {
- markerCollection[toHideID].icon.imageDiv.style.visibility = 'hidden';
- }
- }
- }
- }
- }
- }
- else
- {
- uroRestackMarkers();
- }
- }
- function uroGetVenueNavPoint(uroFID)
- {
- for(var vObj in W.model.venues.objects)
- {
- if(W.model.venues.objects.hasOwnProperty(vObj))
- {
- if(uroFID == vObj)
- {
- return W.model.venues.objects[vObj].getNavigationPoint().point.toLonLat();
- }
- }
- }
- // just in case... return a safe value if the requested venue object wasn't found
- return W.map.getCenter();
- }
- function uroOpenNewTab()
- {
- // flush the current settings into localStorage before the new tab opens, so that when its instance of
- // URO+ fires up it'll have the same settings as this one
- uroSaveSettings();
- return true;
- }
- function uroEditTBR()
- {
- if(uroTBRObj === null)
- {
- return;
- }
- uroTBRObj.getElementsByClassName('waze-icon-clock')[0].click();
- return false;
- }
- function uroKillCentering()
- {
- return W.map.getExtent();
- }
- function uroRestoreCentering()
- {
- if(uroAutoCentreDisabledOn.length > 0)
- {
- if(uroAutoCentreDisabledOn[0] == 'PUR')
- {
- if(W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]] != null)
- {
- W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]].model.geometry.getBounds = W.map.placeUpdatesLayer.markers[uroAutoCentreDisabledOn[1]].model.geometry.origGetBounds;
- }
- }
- else if(uroAutoCentreDisabledOn[0] == 'MP')
- {
- if(W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]] != null)
- {
- W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]].model.getDisconnectBounds = W.map.problemLayer.markers[uroAutoCentreDisabledOn[1]].model.origGetDisconnectBounds;
- }
- }
- uroAutoCentreDisabledOn = [];
- }
- }
- function uroAddClosureRowToTable(rcObj)
- {
- var result = '';
- if(rcObj.active === true)
- {
- result += '<tr>';
- }
- else
- {
- result += '<tr bgcolor="#C0C0C0">';
- }
- var startDate = rcObj.startDate;
- var endDate = "unknown";
- if(rcObj.endDate !== null)
- {
- endDate = rcObj.endDate;
- }
- var provider = "---";
- if(rcObj.provider !== null)
- {
- provider = rcObj.provider;
- }
- else if(rcObj.createdBy !== null)
- {
- provider = uroGetUserNameAndRank(rcObj.createdBy);
- }
- var reason = "---";
- if(rcObj.reason !== null)
- {
- reason = rcObj.reason;
- }
- var mte = "---";
- if(rcObj.eventId !== null)
- {
- try
- {
- mte = W.model.majorTrafficEvents.objects[rcObj.eventId].attributes.names[0].value;
- }
- catch(err)
- {
- }
- }
- result += '<td>' + startDate + ' to ' + endDate + '</td>';
- result += '<td>' + provider + '</td>';
- result += '<td>' + reason + '</td>';
- result += '<td>' + mte + '</td>';
- result += '</td></tr>';
- return result;
- }
- function uroGetAddress(streetID, houseNumber, formatForSegmentPopup)
- {
- var result = '';
- if((houseNumber !== undefined) && (houseNumber !== null))
- {
- result += houseNumber + ' ';
- }
- if(streetID != null)
- {
- var streetName = I18n.lookup('edit.address.no_street');
- var doesStreetIDExist = true;
- if(W.model.streets.objects[streetID] === undefined)
- {
- streetName = 'non-existent streetID';
- doesStreetIDExist = false;
- }
- else
- {
- if((streetName !== null) && (W.model.streets.objects[streetID].isEmpty === false))
- {
- streetName = W.model.streets.objects[streetID].name;
- }
- }
- if(formatForSegmentPopup === true)
- {
- result += '<b>'+streetName+'</b><br>';
- }
- else
- {
- result += streetName + ', ';
- }
- if(doesStreetIDExist === true)
- {
- var cityName = I18n.lookup('edit.address.no_city');
- var doesCityIDExist = true;
- var cityID = W.model.streets.objects[streetID].cityID;
- if(W.model.cities.objects[cityID] === undefined)
- {
- cityName = 'non-existent cityID';
- doesCityIDExist = false;
- }
- else
- {
- if(W.model.cities.objects[cityID].attributes.name !== "")
- {
- cityName = W.model.cities.objects[cityID].attributes.name;
- }
- }
- result += cityName + ', ';
- if(doesCityIDExist === true)
- {
- var stateID = W.model.cities.objects[cityID].attributes.stateID;
- if(W.model.states.objects[stateID] === undefined)
- {
- result += 'non-existent stateID';
- }
- else
- {
- result += W.model.states.objects[stateID].name;
- }
- }
- }
- }
- result += '<br>';
- return result;
- }
- function uroNewLookHighlightedItemsCheck(e)
- {
- var result = '';
- var rw;
- var rh;
- var objHasIgnoreLink = false;
- var objHasDeleteLink = false;
- var objHasAddWatchLink = false;
- var objHasRemoveWatchLink = false;
- var objHasUpdateWatchLink = false;
- var objHasRecentreSessionLink = false;
- var objHasOpenInNewTabLink = false;
- var objHasCloneLink = false;
- var isVenue = false;
- var isMapComment = false;
- var newPopupType = null;
- var markerObj;
- var markerPos;
- var markerImg;
- var ureq = null;
- var idx;
- var hovered = false;
- var targetTab = '';
- var unstackedX;
- var unstackedY;
- var ureqID = null;
- var isUR = false;
- var isProblem = false;
- var isTurnProb = false;
- var isPlaceUpdate = false;
- var idSrc = null;
- var mouseX;
- var mouseY;
- var uroDaysResolved;
- var renderIntent;
- // function preamble...
- {
- if(uroMTEMode) return;
- if(!uroInitialised) return;
- if(e == 'dwellTimeout')
- {
- }
- else
- {
- if((uroMouseIsDown) && (e.buttons === 0))
- {
- uroAddLog('trapped erroneous mousedown state');
- uroMouseIsDown = false;
- }
- }
- if(uroMouseIsDown)
- {
- return;
- }
- if(OpenLayers === null)
- {
- if(uroNullOpenLayers === false)
- {
- uroAddLog('caught null OpenLayers');
- uroNullOpenLayers = true;
- }
- return;
- }
- uroNullOpenLayers = false;
- if(W.map.updateRequestLayer === null)
- {
- if(uroNullURLayer === false)
- {
- uroAddLog('caught null UR layer');
- uroNullURLayer = true;
- }
- return;
- }
- uroNullURLayer = false;
- if(W.map.problemLayer === null)
- {
- if(uroNullProblemLayer === false)
- {
- uroAddLog('caught null problem layer');
- uroNullProblemLayer = true;
- }
- return;
- }
- uroNullProblemLayer = false;
- if(uroGetCBChecked('_cbMasterEnable') === false)
- {
- return;
- }
- if(e == 'dwellTimeout')
- {
- mouseX = uroPrevMouseX;
- mouseY = uroPrevMouseY;
- }
- else
- {
- mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
- mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top;
- var maxJitter = uroGetElmValue('_inputMaxJitter');
- if((Math.abs(uroPrevMouseX - mouseX) > maxJitter) || (Math.abs(uroPrevMouseY - mouseY) > maxJitter))
- {
- uroPopupDwellTimer = uroGetElmValue('_inputPopupDwellTimeout');
- }
- uroPrevMouseX = mouseX;
- uroPrevMouseY = mouseY;
- }
- }
- var popupXOffset = uroParsePxString(window.getComputedStyle(document.getElementById('sidebar')).getPropertyValue("width"));
- var popupYOffset = $(document.getElementById("WazeMap")).offset().top - 80;
- var uroPopupX = mouseX + popupXOffset + 10;
- var uroPopupY = mouseY + popupYOffset - 10;
- // popup for segment restrictions
- if((uroMousedOverMarkerType === null) && (uroGetCBChecked('_cbInhibitSegPopup') === false))
- {
- for(var slIdx=0; slIdx < W.map.segmentLayer.features.length; slIdx++)
- {
- if(W.map.segmentLayer.features[slIdx].renderIntent == 'highlight')
- {
- if(W.map.getExtent().intersectsBounds(W.map.segmentLayer.features[slIdx].geometry.getBounds()))
- {
- var doPopUp = false;
- var segObj;
- var restObj;
- if(W.map.segmentLayer.features[slIdx].fid === null) segObj = W.map.segmentLayer.features[slIdx].model;
- else segObj = W.map.segmentLayer.features[slIdx];
- // generic segment data
- if(uroGetCBChecked('_cbInhibitSegGenericPopup') === false)
- {
- doPopUp = true;
- var streetID = segObj.attributes.primaryStreetID;
- uroAddLog('building popup for segment '+streetID);
- result += uroGetAddress(streetID, null, true);
- result += '<b>ID: </b>'+segObj.attributes.id+'<br>';
- var fwdSpeed = segObj.attributes.fwdMaxSpeed;
- var revSpeed = segObj.attributes.revMaxSpeed;
- var fwdUnverified = segObj.attributes.fwdMaxSpeedUnverified;
- var revUnverified = segObj.attributes.revMaxSpeedUnverified;
- var roadType = segObj.attributes.roadType;
- var verifyLimits = true;
- if((roadType === 17) || (roadType === 20))
- {
- verifyLimits = false;
- }
- if(segObj.attributes.fwdDirection)
- {
- result += '<b>A-B speed: </b>'+uroGetLocalisedSpeedString(fwdSpeed, verifyLimits);
- if(fwdUnverified) result += ' (unverified)';
- result += '<br>';
- }
- if(segObj.attributes.revDirection)
- {
- result += '<b>B-A speed: </b>'+uroGetLocalisedSpeedString(revSpeed, verifyLimits);
- if(revUnverified) result += ' (unverified)';
- result += '<br>';
- }
- if((segObj.attributes.fwdDirection) && (segObj.attributes.revDirection) && (fwdSpeed != revSpeed) && (!fwdUnverified) && (!revUnverified))
- {
- result += 'Two-way segment has different verified speed limits...<br>';
- }
- }
- // segment restrictions
- result += '<table cellpadding=4 border=1">';
- if(segObj.attributes.fwdRestrictions.length > 0)
- {
- doPopUp = true;
- result += '<tr><td colspan=11><b>A-B restrictions:</b></td></tr>';
- for(idx = 0; idx < segObj.attributes.fwdRestrictions.length; idx++)
- {
- restObj = segObj.attributes.fwdRestrictions[idx];
- result += uroFormatRestriction(restObj);
- }
- }
- if (segObj.attributes.revRestrictions.length > 0)
- {
- doPopUp = true;
- result += '<tr><td colspan=11><b>B-A restrictions:</b></td></tr>';
- for(idx = 0; idx < segObj.attributes.revRestrictions.length; idx++)
- {
- restObj = segObj.attributes.revRestrictions[idx];
- result += uroFormatRestriction(restObj);
- }
- }
- result += '</table>';
- if(W.map.closuresMarkerLayer.getVisibility() === true)
- {
- result += '<table cellpadding=4 border=1" width="100%">';
- if(segObj.attributes.hasClosures === true)
- {
- var hasFwd = false;
- var hasRev = false;
- var rcObj;
- var roadClosure;
- for(roadClosure in W.model.roadClosures.objects)
- {
- if(W.model.roadClosures.objects.hasOwnProperty(roadClosure))
- {
- rcObj = W.model.roadClosures.objects[roadClosure];
- if(rcObj.segID == segObj.attributes.id)
- {
- if(rcObj.forward === true)
- {
- if(hasFwd === false)
- {
- result += '<tr><td colspan=4><b>A-B closures:</b></td></tr>';
- hasFwd = true;
- }
- result += uroAddClosureRowToTable(rcObj);
- }
- else
- {
- hasRev = true;
- }
- }
- }
- }
- if(hasRev === true)
- {
- result += '<tr><td colspan=4><b>B-A closures:</b></td></tr>';
- for(roadClosure in W.model.roadClosures.objects)
- {
- if(W.model.roadClosures.objects.hasOwnProperty(roadClosure))
- {
- rcObj = W.model.roadClosures.objects[roadClosure];
- if(rcObj.segID == segObj.attributes.id)
- {
- if(rcObj.forward === false)
- {
- result += uroAddClosureRowToTable(rcObj);
- }
- }
- }
- }
- }
- if((hasFwd === true) || (hasRev === true))
- {
- doPopUp = true;
- }
- }
- result += '</table>';
- }
- if(doPopUp === true)
- {
- if(segObj.attributes.id === null) uroFID = segObj.id;
- else uroFID = segObj.attributes.id;
- newPopupType = 'segment_restriction';
- }
- break;
- }
- else
- {
- uroAddLog('segment '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
- }
- }
- }
- }
- // popup for restricted turns
- if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitTurnsPopup') === false))
- {
- var turnMarkerCount = W.map.layers[uroTurnsLayerIdx].markers.length;
- if(turnMarkerCount > 0)
- {
- for(idx=0; idx<turnMarkerCount; idx++)
- {
- markerObj = W.map.layers[uroTurnsLayerIdx].markers[idx];
- var arrowElm = markerObj.icon.imageDiv.childNodes[0];
- markerImg = window.getComputedStyle(arrowElm).getPropertyValue("background-image");
- markerPos = window.getComputedStyle(arrowElm).getPropertyValue("background-position");
- hovered = false;
- if(markerImg.indexOf('turns96765f551688fd5082b619129499bbb3.png') != -1)
- {
- if(markerPos == '-72px 0px')
- {
- hovered = true;
- }
- }
- if(hovered === true)
- {
- uroAddLog('hover over restricted turn marker');
- uroTBRObj = arrowElm.childNodes[0];
- var trObj = ($(arrowElm).data('model'));
- var Vertex = new require("Waze/Model/Graph/Vertex");
- var turnGraph = W.model.getTurnGraph().getTurn(Vertex.forwardOf(trObj.fromSeg.attributes.id),Vertex.reverseOf(trObj.toSeg.attributes.id));
- var resObj = turnGraph._turnData._restrictions;
- uroAddLog('building popup for turn restriction');
- result += '<label id="_editTBR">Click to edit</label><br>';
- result += '<table cellpadding=4 border=1">';
- for(var resIdx=0; resIdx < resObj.length; resIdx++)
- {
- result += uroFormatRestriction(resObj[resIdx]);
- }
- result += '</table>';
- uroFID = markerObj.icon.imageDiv._eventCacheID;
- newPopupType = 'turn_restriction';
- break;
- }
- }
- }
- }
- // popup for landmarks
- if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitLandmarkPopup') === false))
- {
- uroPlaceSelected = false;
- var venueObj = null;
- renderIntent = null;
- var navpointPos=new OpenLayers.LonLat();
- for(var llFeatureIdx=0; llFeatureIdx < W.map.landmarkLayer.features.length; llFeatureIdx++)
- {
- renderIntent = W.map.landmarkLayer.features[llFeatureIdx].renderIntent;
- if(renderIntent == 'highlight')
- {
- if(W.map.getExtent().intersectsBounds(W.map.landmarkLayer.features[llFeatureIdx].geometry.getBounds()))
- {
- if(W.map.landmarkLayer.features[llFeatureIdx].fid === null) venueObj = W.map.landmarkLayer.features[llFeatureIdx].model;
- else venueObj = W.map.landmarkLayer.features[llFeatureIdx];
- if(newPopupType === null)
- {
- if(venueObj.attributes.id === null) uroFID = venueObj.id;
- else uroFID = venueObj.attributes.id;
- uroAddLog('building popup for place '+uroFID);
- navpointPos = uroGetVenueNavPoint(uroFID);
- navpointPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- result += '<b>';
- if(venueObj.attributes.name === '')
- {
- if(venueObj.attributes.residential === true) result += '<i>Residential</i>';
- else result += '<i>Unnamed</i>';
- }
- else result += venueObj.attributes.name;
- if(venueObj.attributes.externalProviderIDs.length > 0)
- {
- result += ' <i>(linked)</i>';
- }
- if(venueObj.attributes.adLocked)
- {
- result += ' <i>(AdLocked)</i>';
- }
- result += '</b><br>';
- result += uroGetAddress(venueObj.attributes.streetID, venueObj.attributes.houseNumber, false);
- result += '<ul>';
- for(idx = 0; idx < venueObj.attributes.categories.length; idx++)
- {
- result += '<li>' + I18n.lookup("venues.categories." + venueObj.attributes.categories[idx]);
- }
- result += '</ul>';
- if(venueObj.attributes.residential === true)
- {
- if(venueObj.geometry.CLASS_NAME == 'OpenLayers.Geometry.Point')
- {
- result += '<a href="#" id="_cloneRP">Clone place</a>';
- objHasCloneLink = true;
- }
- }
- var npLink = document.location.href;
- ////var npLayers = '&layers='+...
- var npLayers = '';
- npLink = npLink.substr(0,npLink.indexOf('?zoom'));
- npLink += '?zoom=5&lat='+navpointPos.lat+'&lon='+navpointPos.lon+npLayers;
- targetTab = "_uroTab_" + Math.round(Math.random()*1000000);
- result += '<hr>Jump to nav point: <a href="'+npLink+'" id="_openInNewTab" target="'+targetTab+'">in new tab</a> - ';
- objHasOpenInNewTabLink = true;
- result += '<a href="#" id="_recentreSession">in this tab</a>';
- objHasRecentreSessionLink = true;
- newPopupType = 'venue';
- isVenue = true;
- break;
- }
- else
- {
- var otherID;
- if(venueObj.attributes.id === null) otherID = venueObj.id;
- else otherID = venueObj.attributes.id;
- uroAddLog('venue '+otherID+' is also highlighted');
- }
- }
- else
- {
- uroAddLog('landmark '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
- }
- }
- else if((renderIntent == 'select') || (renderIntent == 'highlightselected'))
- {
- uroPlaceSelected = true;
- }
- }
- }
- // popup for map comments
- if((uroMousedOverMarkerType === null) && (newPopupType === null) && (uroGetCBChecked('_cbInhibitMapCommentPopup') === false))
- {
- uroMCSelected = false;
- var mcObj = null;
- renderIntent = null;
- for(var mcFeatureIdx=0; mcFeatureIdx < W.map.layers[uroMCLayerIdx].features.length; mcFeatureIdx++)
- {
- renderIntent = W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].renderIntent;
- if(renderIntent == 'highlight')
- {
- if(W.map.getExtent().intersectsBounds(W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].geometry.getBounds()))
- {
- mcObj = W.map.layers[uroMCLayerIdx].features[mcFeatureIdx].model;
- if(newPopupType === null)
- {
- uroFID = mcObj.attributes.id;
- uroAddLog('building popup for map comment '+uroFID);
- result += '<b>';
- if(mcObj.attributes.subject === '')
- {
- result += '<i>No subject</i>';
- }
- else result += mcObj.attributes.subject;
- result += '</b><br>';
- if(mcObj.attributes.body !== '')
- {
- var mcDesc = mcObj.attributes.body.replace(/<\/?[^>]+(>|$)/g, "");
- if(mcDesc != "null")
- {
- mcDesc = uroClickify(mcDesc);
- result += mcDesc + '<br>';
- }
- }
- var mcDaysOld = uroGetMCAge(mcObj,0,false);
- var mcSubmittedTS = uroGetMCAge(mcObj,0,true);
- if(mcSubmittedTS != -1)
- {
- mcSubmittedTS = uroGetDateTimeString(mcSubmittedTS);
- }
- if(mcDaysOld != -1)
- {
- result += '<i>Submitted ' + uroParseDaysAgo(mcDaysOld) + ' ';
- if(mcSubmittedTS != -1) result += '(' + mcSubmittedTS + ') ';
- if(mcObj.attributes.createdBy != null)
- {
- result += ' by '+uroGetUserNameAndRank(mcObj.attributes.createdBy);
- }
- result += '</i><br>';
- }
- mcDaysOld = uroGetMCAge(mcObj,1,false);
- mcSubmittedTS = uroGetMCAge(mcObj,1,true);
- if(mcSubmittedTS != -1)
- {
- mcSubmittedTS = uroGetDateTimeString(mcSubmittedTS);
- }
- if(mcDaysOld != -1)
- {
- result += '<i>Updated ' + uroParseDaysAgo(mcDaysOld) + ' ';
- if(mcSubmittedTS != -1) result += '(' + mcSubmittedTS + ') ';
- if(mcObj.attributes.createdBy != null)
- {
- result += ' by '+uroGetUserNameAndRank(mcObj.attributes.updatedBy);
- }
- result += '</i><br>';
- }
- var mcHasMyComments = false;
- var mcNComments = mcObj.attributes.conversation.length;
- if(mcNComments > 0)
- {
- for(var i=0; i<mcNComments; i++)
- {
- if(mcObj.attributes.conversation[i].userID == uroUserID)
- {
- mcHasMyComments = true;
- break;
- }
- }
- }
- result += '<br>' + mcNComments +' comment';
- if(mcNComments != 1) result += 's';
- if((mcHasMyComments === false) && (mcNComments > 0)) result += ' (none by me)';
- newPopupType = 'map_comment';
- isMapComment = true;
- break;
- }
- else
- {
- var mcOtherID = mcObj.attributes.id;
- uroAddLog('map comment '+mcOtherID+' is also highlighted');
- }
- }
- else
- {
- uroAddLog('map comment '+uroFID+' has renderIntent==highlight but is offscreen... blocking popup');
- }
- }
- else if((renderIntent == 'select') || (renderIntent == 'highlightselected'))
- {
- uroMCSelected = true;
- }
- }
- }
- // look for URs, place updates and problems
- if(newPopupType === null)
- {
- if((uroMousedOverMarkerType == 'ur') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitURPopup') === false))
- {
- hovered = true;
- isUR = true;
- newPopupType = 'ur';
- ureq = W.model.mapUpdateRequests.objects[uroMousedOverMarkerID];
- unstackedX = uroParsePxString(W.map.updateRequestLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
- unstackedY = uroParsePxString(W.map.updateRequestLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);
- // override popup base position
- uroPopupX = unstackedX + popupXOffset + 6;
- uroPopupY = unstackedY + popupYOffset + 66;
- uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
- uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);
- // check for stacking...
- if(uroShownFID != uroMousedOverMarkerID)
- {
- uroCheckStacking(1,uroMousedOverMarkerID, unstackedX, unstackedY);
- }
- uroFID = uroMousedOverMarkerID;
- uroAddLog('building popup for UR '+uroMousedOverMarkerID);
- result = '<b>Update Request ('+uroMousedOverMarkerID+'): ' + I18n.lookup("update_requests.types." + ureq.attributes.type) + '</b><br>';
- if(ureq.attributes.description !== null)
- {
- var desc = ureq.attributes.description.replace(/<\/?[^>]+(>|$)/g, "");
- if(desc != "null")
- {
- desc = uroClickify(desc);
- result += desc + '<br>';
- }
- }
- var uroDaysOld = uroGetURAge(ureq,0,false);
- var uroSubmittedTS = uroGetURAge(ureq,0,true);
- if(uroSubmittedTS != -1)
- {
- uroSubmittedTS = uroGetDateTimeString(uroSubmittedTS);
- }
- if(uroDaysOld != -1)
- {
- result += '<i>Submitted ' + uroParseDaysAgo(uroDaysOld) + ' ';
- if(uroSubmittedTS != -1) result += '(' + uroSubmittedTS + ') ';
- if(ureq.attributes.guestUserName != null)
- {
- result += 'via Livemap';
- if(ureq.attributes.guestUserName !== '')
- {
- result += ' by '+ureq.attributes.guestUserName.replace(/<\/?[^>]+(>|$)/g, "");
- }
- }
- result += '</i>';
- }
- if(ureq.attributes.resolvedOn !== null)
- {
- uroDaysResolved = uroGetURAge(ureq,1,false);
- var uroResolvedTS = uroGetURAge(ureq,1,true);
- if(uroResolvedTS != -1)
- {
- uroResolvedTS = uroGetDateTimeString(uroResolvedTS);
- }
- if(uroDaysResolved != -1)
- {
- result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
- if(uroResolvedTS != -1) result += '(' + uroResolvedTS + ')</i>';
- result += '<br><i>Marked as ';
- if(ureq.attributes.resolution === 0) result += 'solved';
- else if(ureq.attributes.resolution == 1) result += 'not identified';
- else result += 'unknown';
- if(ureq.attributes.resolvedBy !== null)
- {
- result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
- }
- result += '</i>';
- }
- }
- if(W.model.updateRequestSessions.objects[uroMousedOverMarkerID] != null)
- {
- var hasMyComments = uroURHasMyComments(uroMousedOverMarkerID);
- var nComments = W.model.updateRequestSessions.objects[uroMousedOverMarkerID].comments.length;
- result += '<br>' + nComments + ' comment';
- if(nComments != 1) result += 's';
- if((hasMyComments === false) && (nComments > 0)) result += ' (none by me)';
- if(nComments > 0)
- {
- var commentDaysOld = uroGetCommentAge(W.model.updateRequestSessions.objects[uroMousedOverMarkerID].comments[nComments-1]);
- if(commentDaysOld != -1)
- {
- result += ', last update '+uroParseDaysAgo(commentDaysOld);
- }
- }
- }
- }
- if((uroMousedOverMarkerType == 'pur') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitPUPopup') === false))
- {
- hovered = true;
- isPlaceUpdate = true;
- newPopupType = 'pur';
- ureq = W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model;
- unstackedX = uroParsePxString(W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
- unstackedY = uroParsePxString(W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);
- // override popup base position
- uroPopupX = unstackedX + popupXOffset + 6;
- uroPopupY = unstackedY + popupYOffset + 66;
- uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
- uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);
- if(uroShownFID != uroMousedOverMarkerID)
- {
- // check for stacking...
- uroCheckStacking(3,uroMousedOverMarkerID, unstackedX, unstackedY);
- }
- uroFID = uroMousedOverMarkerID;
- // to inhibit auto-centering only when the PUR marker is clicked, we wait for the marker to get highlighted, then
- // make a copy of the original getBounds() function before replacing it with a call to W.map.getExtent(). Clicking
- // the marker causes a call to getBounds() which will then return the current map extent, and thus no change in the
- // map view will occur...
- uroRestoreCentering();
- W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.origGetBounds = W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.getBounds;
- W.map.placeUpdatesLayer.markers[uroMousedOverMarkerID].model.geometry.getBounds = uroKillCentering;
- uroAutoCentreDisabledOn.push('PUR', uroMousedOverMarkerID);
- uroAddLog('building popup for placeUpdate '+uroMousedOverMarkerID);
- result = '<b>';
- if(ureq.attributes.name === '') result += 'Unnamed landmark';
- else result += ureq.attributes.name;
- result += '</b><br>';
- result += '<ul>';
- for(idx = 0; idx < ureq.attributes.categories.length; idx++)
- {
- result += '<li>' + I18n.lookup("venues.categories." + ureq.attributes.categories[idx]);
- }
- result += '</ul>';
- if(ureq.attributes.residential === true)
- {
- result += '<i>Residential</i>';
- }
- var daysOld = uroGetPURAge(ureq);
- if(daysOld != -1)
- {
- result += '<br><i>Submitted '+uroParseDaysAgo(daysOld)+'</i>';
- }
- }
- if((uroMousedOverMarkerType == 'mp') && (newPopupType === null) && (uroGetCBChecked('_cbInhibitMPPopup') === false))
- {
- hovered = true;
- isProblem = true;
- newPopupType = 'map_problem';
- ureq = W.model.problems.objects[uroMousedOverMarkerID];
- if(ureq === undefined)
- {
- if(uroDOMHasTurnProblems)
- {
- ureq = W.model.turnProblems.objects[uroMousedOverMarkerID];
- if(ureq != null) isTurnProb = true;
- }
- }
- unstackedX = uroParsePxString(W.map.problemLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.left);
- unstackedY = uroParsePxString(W.map.problemLayer.markers[uroMousedOverMarkerID].icon.imageDiv.style.top);
- // override popup base position
- uroPopupX = unstackedX + popupXOffset + 6;
- uroPopupY = unstackedY + popupYOffset + 66;
- uroPopupX -= uroParsePxString(W.map.segmentLayer.div.style.left);
- uroPopupY -= uroParsePxString(W.map.segmentLayer.div.style.top);
- // check for stacking...
- if(uroShownFID != uroMousedOverMarkerID)
- {
- uroCheckStacking(2,uroMousedOverMarkerID, unstackedX, unstackedY);
- }
- uroFID = uroMousedOverMarkerID;
- // same method of disabling the on-click auto-centre behaviour as for PURs above...
- uroRestoreCentering();
- W.map.problemLayer.markers[uroMousedOverMarkerID].model.origGetDisconnectBounds = W.map.problemLayer.markers[uroMousedOverMarkerID].model.getDisconnectBounds;
- W.map.problemLayer.markers[uroMousedOverMarkerID].model.getDisconnectBounds = uroKillCentering;
- uroAutoCentreDisabledOn.push('MP', uroMousedOverMarkerID);
- uroAddLog('building popup for problem '+uroMousedOverMarkerID);
- if(isTurnProb) result = '<b>Turn Problem ('+uroMousedOverMarkerID+'): ' + I18n.lookup("problems.types.turn.title");
- else
- {
- result = '<b>Map Problem ('+uroMousedOverMarkerID+'): ';
- var problemType = null;
- if(uroDOMHasTurnProblems)
- {
- problemType = ureq.attributes.problemType;
- }
- else
- {
- problemType = ureq.attributes.subType;
- }
- if(problemType == 300)
- {
- result += I18n.lookup("problems.panel.closure.title");
- }
- else
- {
- if(I18n.lookup("problems.types." + problemType) === undefined) result += 'Unknown problem type ('+problemType+')';
- else result += I18n.lookup("problems.types." + problemType + ".title");
- }
- }
- result += '</b><br>';
- if(ureq.attributes.description != null)
- {
- result += 'Description: ' + ureq.attributes.description + '<br>';
- }
- if(ureq.attributes.extraInfo != null)
- {
- result += 'ExtraInfo: ' + ureq.attributes.extraInfo + '<br>';
- }
- if(ureq.attributes.provider != null)
- {
- result += 'Provider: ' + ureq.attributes.provider + '<br>';
- }
- if(ureq.attributes.resolvedOn != null)
- {
- uroDaysResolved = uroGetURAge(ureq,1,false);
- if(uroDaysResolved != -1)
- {
- result += '<br><i>Closed ' + uroParseDaysAgo(uroDaysResolved) + ' ';
- if(ureq.attributes.resolvedBy != null)
- {
- result += ' by '+uroGetUserNameAndRank(ureq.attributes.resolvedBy);
- }
- if((ureq.attributes.open === true) && (ureq.attributes.resolvedOn != null))
- {
- result += '<br>Reopened by Waze';
- }
- result += '</i>';
- }
- }
- }
- if(hovered === false)
- {
- uroFID = -1;
- if(uroStackType !== null)
- {
- var tStackType = uroStackType;
- uroRestackMarkers();
- if(tStackType == 1) uroFilterURs();
- else if(tStackType == 2) uroFilterProblems();
- else if(tStackType == 3) uroFilterPlaces();
- }
- }
- else
- {
- // add "open new WME tab" link
- var urPos=new OpenLayers.LonLat();
- if(isPlaceUpdate)
- {
- urPos=ureq.geometry.bounds.centerLonLat.clone();
- }
- else
- {
- if(ureq.geometry.realX === undefined)
- {
- urPos.lon = ureq.geometry.x;
- urPos.lat = ureq.geometry.y;
- }
- else
- {
- urPos.lon = ureq.geometry.realX;
- urPos.lat = ureq.geometry.realY;
- }
- }
- urPos.transform(new OpenLayers.Projection("EPSG:900913"),new OpenLayers.Projection("EPSG:4326"));
- var urLink = document.location.href;
- ////var urLayers = '&layers='+...
- var urLayers = '';
- urLink = urLink.substr(0,urLink.indexOf('?zoom'));
- urLink += '?zoom=5&lat='+urPos.lat+'&lon='+urPos.lon+urLayers;
- if(isUR) urLink += '&mapUpdateRequest='+idSrc;
- else if(isTurnProb) urLink += '&showturn='+idSrc+'&endshow';
- else if(isProblem) urLink += '&mapProblem='+idSrc;
- else if(isPlaceUpdate) urLink += '&showpur='+idSrc+'&endshow';
- targetTab = "_uroTab_" + Math.round(Math.random()*1000000);
- result += '<hr><ul><li><a href="'+urLink+'" id="_openInNewTab" target="'+targetTab+'">Open in new tab</a> - ';
- objHasOpenInNewTabLink = true;
- result += '<a href="#" id="_recentreSession">centre in current tab</a>';
- objHasRecentreSessionLink = true;
- // add "open new livemap tab" link
- var lmLink = null;
- if(document.getElementById("livemap-link") != null)
- {
- uroAddLog('Livemap link in livemap-link id element');
- lmLink = document.getElementById("livemap-link").href;
- }
- else if(document.getElementsByClassName("livemap-link") != null)
- {
- uroAddLog('Livemap link in livemap-link class element');
- lmLink = document.getElementsByClassName("livemap-link")[0].href;
- }
- else
- {
- uroAddLog('Livemap link not found...');
- }
- if(lmLink !== null)
- {
- var zpos = lmLink.indexOf('?');
- if(zpos > -1) lmLink = lmLink.substr(0,zpos);
- lmLink += '?zoom=17&lat='+urPos.lat+'&lon='+urPos.lon+'&layers=BTTTT';
- result += '<li><a href="'+lmLink+'" target="_lmTab">Open in new livemap tab</a>';
- }
- if(!isPlaceUpdate)
- {
- // add "ignore for this session" link
- result += '<li><a href="#" id="_addtoignore">Hide for this session</a></ul>';
- objHasIgnoreLink = true;
- }
- }
- }
- if((newPopupType != 'map_problem') && (newPopupType != 'pur'))
- {
- uroRestoreCentering();
- }
- // look for cameras
- if((newPopupType === null) && (uroGetCBChecked('_cbInhibitCamPopup') === false))
- {
- for(var clFeature in W.map.camerasLayer._featureMap)
- {
- if(W.map.camerasLayer._featureMap[clFeature].renderIntent == 'highlight')
- {
- ureq = W.map.camerasLayer._featureMap[clFeature].model;
- ureqID = ureq.attributes.id;
- // test isSelected() so that we only do overview data on cameras that are being hovered over
- if(ureq.isSelected() === false)
- {
- uroPopupY -= 20;
- newPopupType = 'camera';
- uroFID = ureqID;
- uroAddLog('building popup for camera '+uroFID);
- if(I18n.lookup("edit.camera.fields.type") === undefined)
- {
- result += '<b>Camera: ' + ureq.TYPES[ureq.attributes.type] + '</b><br>';
- }
- else
- {
- result += '<b>Camera: ' + I18n.lookup("edit.camera.fields.type." + ureq.attributes.type) + '</b><br>';
- }
- result += 'ID: '+uroFID+'<br>';
- result += 'Created by ';
- var userID;
- if(W.model.users.get(ureq.attributes.createdBy) != null)
- {
- userID = ureq.attributes.createdBy;
- result += uroGetUserNameAndRank(userID);
- }
- else result += 'unknown';
- result += ', ';
- var camAge = uroGetCameraAge(ureq,1);
- if(camAge != -1)
- {
- result += uroParseDaysAgo(camAge);
- }
- else result += 'unknown days ago';
- result += '<br>Updated by ';
- if(W.model.users.get(ureq.attributes.updatedBy) != null)
- {
- userID = ureq.attributes.updatedBy;
- var userName = W.model.users.objects[userID].userName;
- var userLevel = W.model.users.objects[userID].rank + 1;
- result += userName + ' (' + userLevel + ')';
- }
- else result += 'unknown';
- result += ', ';
- camAge = uroGetCameraAge(ureq,0);
- if(camAge != -1)
- {
- result += uroParseDaysAgo(camAge);
- }
- else result += 'unknown days ago';
- result += '<br>Speed data: ';
- result += uroGetLocalisedSpeedString(ureq.attributes.speed, true);
- result += '<hr><ul>';
- if(uroIsCamOnWatchList(uroFID) != -1)
- {
- result += '<li><a href="#" id="_updatewatchlist">Update watchlist entry</a>';
- result += '<li><a href="#" id="_removefromwatchlist">Remove from watchlist</a>';
- objHasUpdateWatchLink = true;
- objHasRemoveWatchLink = true;
- }
- else
- {
- result += '<li><a href="#" id="_addtowatchlist">Add to watchlist</a>';
- objHasAddWatchLink = true;
- }
- if(ureq.attributes.permissions !== 0)
- {
- result += '<li><a href="#" id="_deleteobject">Delete Camera</a>';
- objHasDeleteLink = true;
- }
- result += '</ul>';
- }
- break;
- }
- }
- }
- if((newPopupType !== null) && (uroPopupDwellTimer === 0) && (uroPopupSuppressed === false))
- {
- if((uroFID != uroShownFID) || (newPopupType != uroShownPopupType))
- {
- if(uroFID != uroShownFID) uroAddLog('FID mismatch, show popup: '+uroFID+'/'+uroShownFID);
- else uroAddLog('Popup type mismatch: '+newPopupType+'/'+uroShownPopupType);
- uroShownFID = uroFID;
- uroShownPopupType = newPopupType;
- uroPopupShown = false;
- }
- if(uroPopupShown === false)
- {
- uroAddLog('display popup at '+uroPopupX+','+uroPopupY);
- uroPopupShown = true;
- uroDiv.style.height = "auto";
- uroDiv.style.width = "auto";
- uroDiv.innerHTML = result;
- if((uroFID != -1) && (objHasIgnoreLink === true))
- {
- uroAddEventListener('_addtoignore','click', uroAddToIgnoreList, true);
- }
- if(objHasDeleteLink === true)
- {
- uroAddEventListener('_deleteobject','click', uroDeleteObject, true);
- }
- if(objHasRemoveWatchLink === true)
- {
- uroAddEventListener('_removefromwatchlist','click', uroRemoveCamFromWatchList, true);
- }
- if(objHasAddWatchLink === true)
- {
- uroAddEventListener('_addtowatchlist','click', uroAddCamToWatchList, true);
- }
- if(objHasUpdateWatchLink === true)
- {
- uroAddEventListener('_updatewatchlist','click', uroUpdateCamWatchList, true);
- }
- if(objHasOpenInNewTabLink === true)
- {
- uroAddEventListener('_openInNewTab','mouseup', uroOpenNewTab, true);
- }
- if(objHasRecentreSessionLink === true)
- {
- if(isUR) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnUR, true);
- else if((isProblem)||(isTurnProb)) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnMP, true);
- else if(isPlaceUpdate) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnPUR, true);
- else if(isVenue) uroAddEventListener('_recentreSession', 'click', uroRecentreSessionOnVenueNavPoint, true);
- }
- if(objHasCloneLink === true)
- {
- uroAddEventListener('_cloneRP', 'click', uroCloneResidentialPlace, true);
- }
- if(newPopupType == 'turn_restriction')
- {
- uroAddEventListener('_editTBR','click', uroEditTBR, true);
- }
- // restrict the popup width to be no wider than just under half the window width to avoid it
- // completely overlapping the marker it's associated with - by keeping it to just below half
- // the window width we guarantee that it'll fit either to the left or the right of the marker
- // no matter how far across the screen the marker is located...
- rw = parseInt(uroDiv.clientWidth);
- if(rw > (window.innerWidth * 0.45))
- {
- rw = (window.innerWidth * 0.45);
- uroDiv.style.width = rw+'px';
- }
- // get the div height after any adjustment of the width above, to account for whatever content
- // reflow may have occurred as a result of reducing the width...
- rh = parseInt(uroDiv.clientHeight);
- if((uroPopupX + rw) > window.innerWidth)
- {
- // where the popup would be off the right hand side of the screen, move it completely over to the
- // other side of the mouse pointer
- uroPopupX -= (rw + 20);
- if(uroPopupX < 0) uroPopupX = 0;
- }
- if((uroPopupY + rh) > window.innerHeight)
- {
- // where the popup would be off the bottom of the screen, shift it up just far enough to be
- // fully visible
- uroPopupY -= (((uroPopupY + rh) - window.innerHeight) + 30);
- if(uroPopupY < 0) uroPopupY = 0;
- }
- uroDiv.style.top = uroPopupY+'px';
- uroDiv.style.left = uroPopupX+'px';
- uroDiv.style.visibility = 'visible';
- }
- uroPopupTimer = -1;
- }
- else if((newPopupType === null) && (uroPopupDwellTimer !== 0) && (uroPopupShown === true))
- {
- uroHidePopup();
- }
- else
- {
- if((uroPopupTimer == -1) && (uroFID != uroShownFID))
- {
- uroPopupTimer = uroGetElmValue('_inputPopupEntryTimeout');
- }
- }
- }
- function uroExclusiveCB()
- {
- var cbChecked = uroGetCBChecked(this.id);
- if(cbChecked === true)
- {
- var pairedList = this.attributes.pairedWith.value.split(',');
- for(var i=0; i<pairedList.length; i++)
- {
- uroSetCBChecked(pairedList[i], false);
- }
- }
- }
- function uroGetAMs(e)
- {
- if(uroMTEMode) return;
- if(!uroFilterPreamble) return;
- if(!uroInitialised) return;
- var amList = '';
- if(W.map.managedAreasLayer.getVisibility() === true)
- {
- var mouseX = e.pageX - document.getElementById('map').getBoundingClientRect().left;
- var mouseY = e.pageY - document.getElementById('map').getBoundingClientRect().top - document.getElementById('toolbar').clientHeight;
- var mousePixel = new OL.Pixel(mouseX, mouseY);
- var mousePoint = W.map.getLonLatFromPixel(mousePixel).toPoint();
- for(var amObj in W.model.managedAreas.objects)
- {
- if(W.model.managedAreas.objects[amObj].geometry.containsPoint(mousePoint))
- {
- if(amList !== '') amList += ', ';
- amList += uroGetUserNameAndRank(W.model.managedAreas.objects[amObj].userID);
- }
- }
- if(amList === '')
- {
- amList = 'none';
- }
- amList = "<b>Area Managers:</b> "+amList;
- }
- document.getElementById("uroAMList").innerHTML = amList;
- }
- function uroMouseDown()
- {
- uroMouseIsDown = true;
- }
- function uroMouseUp()
- {
- uroMouseIsDown = false;
- }
- function uroMouseOut()
- {
- //console.debug('Elvis has left the building...');
- }
- function uroUREvent_onObjectsChanged()
- {
- }
- function uroUREvent_onObjectsAdded()
- {
- if(uroGetCBChecked('_cbURResolverIDFilter') === true)
- {
- uroUpdateResolverList();
- }
- uroFilterURs();
- }
- function uroUREvent_onObjectsRemoved()
- {
- }
- function uroGetSelectedURCommentCount()
- {
- if(W.model.updateRequestSessions.objects[uroSelectedURID] != null)
- {
- var cachedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length;
- uroAddLog(uroSelectedURID+':'+cachedCommentCount+' '+uroExpectedCommentCount);
- // if there aren't the same number of cached comments as there are comments in the UR dialog list, initiate
- // a refresh of the comment data...
- if(cachedCommentCount != uroExpectedCommentCount)
- {
- if(uroPendingCommentDataRefresh === true)
- {
- if(cachedCommentCount > 0)
- {
- uroCachedLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id;
- }
- else
- {
- uroCachedLastCommentID = null;
- }
- uroAddLog('updateRequestSessions refresh required for UR '+uroSelectedURID);
- if(uroCachedLastCommentID !== null)
- {
- uroAddLog('last comment ID for this UR is '+uroCachedLastCommentID);
- }
- else
- {
- uroAddLog('first comment for this UR, no previous comment to ID');
- }
- var idList = [];
- idList.push(uroSelectedURID);
- // need to delete the existing cache object first, as .get() is only capable of creating new objects,
- // it doesn't seem able to update an existing object with new data
- W.model.updateRequestSessions.remove(W.model.updateRequestSessions.objects[uroSelectedURID]);
- W.model.updateRequestSessions.get(idList);
- // the call to .get() initiates a XMLHttpRequest for the data, so we now need to switch modes - the
- // refresh process has started so we're no longer pending, but we are now waiting for the XMLHttpRequest
- // to return something...
- uroPendingCommentDataRefresh = false;
- uroWaitingCommentDataRefresh = true;
- }
- else
- {
- if(cachedCommentCount > 0)
- {
- var currentLastCommentID = W.model.updateRequestSessions.objects[uroSelectedURID].comments[cachedCommentCount-1].id;
- if(currentLastCommentID == uroCachedLastCommentID)
- {
- // most recent comment loaded for this UR is the same one that was present at the start of this
- // refresh process, so kick back into pending mode so we can retry the .get()...
- uroAddLog('latest comment ID still the same, reverting to pending mode...');
- uroPendingCommentDataRefresh = true;
- }
- else
- {
- // something may have gone awry here - the most recent comment loaded for this UR doesn't have the
- // same ID as the one present at the start of the refresh process, yet the comment counts still don't
- // match up, which suggests either a comment got lost along the way or someone else has commented on
- // the same UR at almost the same time. To get out of the loop this would create, assume that a
- // mismatch in the IDs means the .get() has completed successfully no matter what the new comment
- // count is, and take this new count to be the count we were expecting all along...
- uroAddLog('latest comment ID different, but expected count not correct...');
- uroExpectedCommentCount = cachedCommentCount;
- }
- }
- else
- {
- uroAddLog('first comment on this UR not received yet, reverting to pending mode...');
- uroPendingCommentDataRefresh = true;
- }
- }
- }
- else
- {
- // if the WME session is loaded with a UR already selected, such that WME has opened the UR dialog as part
- // of the session startup process, adding new comments to the UR cause the cached data to be updated immediately.
- // This prevents URO+ from switching into waiting mode in the above block of code, so we have to instead do
- // it here by comparing the cached count against the expected count following the Send click event.
- if(cachedCommentCount >= uroExpectedCommentCount)
- {
- uroPendingCommentDataRefresh = false;
- uroWaitingCommentDataRefresh = true;
- uroExpectedCommentCount = null;
- }
- // once the cached data has been updated, refilter the URs so that the new comment count is taken into account
- // immediately for filtering and display purposes
- if(uroWaitingCommentDataRefresh === true)
- {
- uroWaitingCommentDataRefresh = false;
- uroFilterURs();
- uroAddLog('refresh complete');
- }
- }
- }
- }
- function uroAddedComment()
- {
- // when the user clicks the Send button to submit a new UR comment, this event handler fires before the new comment is
- // posted to the server and thus also before the comment list gets updated in the UR dialog. So we take the current
- // comment count and, if the new comment edit box isn't empty, increment it by 1 to get the expected count. Then we
- // set the pending flag true to initiate a session refresh on the next 100ms tick
- uroExpectedCommentCount = W.map.panelRegion.currentView.conversationView.viewModel.attributes.commentCount;
- if(document.getElementsByClassName('new-comment-text')[0].value !== '')
- {
- uroExpectedCommentCount++;
- uroAddLog('new comment added to UR '+uroSelectedURID+', cache refresh required...');
- uroPendingCommentDataRefresh = true;
- }
- else
- {
- uroPendingCommentDataRefresh = false;
- }
- }
- function uroInhibitNextUpdateRequestButton(e)
- {
- var doClick = true;
- e.stopPropagation();
- if(document.getElementsByClassName('form-control new-comment-text').length > 0)
- {
- if(document.getElementsByClassName('form-control new-comment-text')[0].textLength > 0)
- {
- doClick = (confirm('Comment not sent, close report panel anyway?'));
- }
- }
- if(doClick)
- {
- document.getElementsByClassName('close-panel')[0].click();
- }
- }
- function uroAddLZ(valueToPad, newLength)
- {
- var padString = '';
- for(var i=0; i<newLength; i++)
- {
- padString += '0';
- }
- padString += valueToPad.toString();
- return padString.slice(-newLength);
- }
- function uroIncrementClosureDate(oldDate, incByDays)
- {
- var dateBits = oldDate.split('-');
- var year = parseInt(dateBits[0]);
- var month = parseInt(dateBits[1])-1;
- var date = parseInt(dateBits[2])+1;
- var incrementedDate = new Date(year, month, date);
- return (uroAddLZ(incrementedDate.getFullYear(),4) + '-' + uroAddLZ(incrementedDate.getMonth()+1,2) + '-' + uroAddLZ(incrementedDate.getDate(),2));
- }
- function uroGetElementProperty(elmName, elmOffset, elmProperty)
- {
- var retval = null;
- if(document.getElementsByName(elmName).length !== 0)
- {
- retval = document.getElementsByName(elmName)[elmOffset][elmProperty];
- }
- return retval;
- }
- // Residential Place Cloning
- //{
- var uroCRPStreetID;
- var uroCRPHouseNumber;
- function uroCompleteRPClone()
- {
- // as with closure cloning, the place details edit form requires us to push the new value into the relevant
- // edit field and then generate a change event on that field, otherwise WME doesn't bother reading the value...
- // street name
- var streetObj = W.model.streets.get(uroCRPStreetID);
- if(streetObj !== undefined)
- {
- document.getElementsByClassName('street-name')[0].value = streetObj.name;
- document.getElementsByClassName('street-name')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
- // city name
- var cityObj = W.model.cities.get(streetObj.cityID);
- if(cityObj !== undefined)
- {
- if(cityObj.attributes.isEmpty === true)
- {
- // The donor point place we create to take the cloned RPP properties may have been automatically given
- // a city name by WME, and thus the city name field will already be filled in and activated... If our
- // RPP doesn't however have a city name, we need to deactivate the city name field again, so that WME
- // doesn't complain about the user trying to save the new RPP with an empty city name
- if(document.getElementsByClassName("empty-city")[0].checked === false)
- {
- document.getElementsByClassName("empty-city")[0].click();
- }
- }
- document.getElementsByClassName('city-name')[0].value = cityObj.attributes.name;
- document.getElementsByClassName('city-name')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
- // county
- document.getElementsByClassName('state-id')[0].value = cityObj.attributes.stateID;
- document.getElementsByClassName('state-id')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
- // country
- document.getElementsByClassName('country-id')[0].value = cityObj.attributes.countryID;
- document.getElementsByClassName('country-id')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
- }
- }
- // house number
- document.getElementsByClassName('house-number')[0].value = uroCRPHouseNumber;
- document.getElementsByClassName('house-number')[0].dispatchEvent(new Event('change', { 'bubbles': true }));
- // now wait for the user to confirm everything and click Apply...
- }
- function uroConvertToRP()
- {
- // panel isn't open yet, which means the user either hasn't clicked yet or WME is still processing the
- // placement of the venue, so wait a while and then check again...
- if(document.getElementById('edit-panel').getElementsByClassName('landmark').length === 0)
- {
- setTimeout(uroConvertToRP, 100);
- return;
- }
- // panel is open, so move to the next step of the cloning procedure by converting the newly created
- // place to residential by generating a click event on the "convert to residential" link...
- document.getElementsByClassName("toggle-residential")[0].click();
- // and then click on the address edit icon...
- document.getElementsByClassName('waze-icon-edit')[0].click();
- // now click on the "none" checkbox for the street name edit field so we can enter the street name
- document.getElementById('empty-street').click();
- // WME automatically clears the checkbox associated with the city name edit field if we set the street
- // name to be one that has a city associated with it, which is nice :-)
- // the click event seems to take a while to execute, and if we call dispatchEvent on the edit field whilst
- // it's still tagged as disabled then it gets ignored, causing the value in that field to be dropped when
- // we apply the changes to the place. Trying to programatically detect when the field has been activated
- // doesn't seem to be reliable, however a fixed delay of 1s seems to work nicely
- setTimeout(uroCompleteRPClone, 1000);
- }
- function uroCloneResidentialPlace()
- {
- // trying to clone a RPP when one is already selected causes the selected one to be changed back to
- // a non-residential, as uroConvertToRP() thinks the user has already clicked to place the new RPP...
- if(document.getElementById('edit-panel').getElementsByClassName('landmark').length === 0)
- {
- var venueObj = W.model.venues.objects[uroFID];
- if(venueObj !== undefined)
- {
- // copy address from highlighted residential place
- uroCRPHouseNumber = venueObj.attributes.houseNumber;
- uroCRPStreetID = venueObj.attributes.streetID;
- // generate a click event on the first new point venue entry in the venues menu in order to generate a
- // new point venue object that we can manipulate...
- document.getElementsByClassName('toolbar-group-venues')[0].getElementsByClassName("drawing-control main-control point")[0].click();
- // now wait for the user to click on the map to place the new point venue
- uroConvertToRP();
- }
- }
- }
- //}
- // Closure Cloning
- //{
- var uroConfirmClosureDelete = true;
- var uroClosuresToDelete = 0;
- var uroCLocation;
- var uroCReason;
- var uroCEvent;
- var uroCDirection;
- var uroCHasStartDate;
- var uroCStartDate;
- var uroCStartTime;
- var uroCEndDate;
- var uroCEndTime;
- var uroCIgnoreTraffic;
- function uroCompleteClosureCloning()
- {
- if(document.getElementsByClassName('edit-closure').length === 0)
- {
- window.setTimeout(uroCompleteClosureCloning,100);
- return;
- }
- // need to generate a change event on each of the form fields, because WME appears to be silently populating some hidden
- // closure object with the details as they're entered manually, and if we just set the form values without then forcing
- // the change event as well then WME will end up using its default values instead of the ones we've so lovingly copied...
- if(uroCLocation !== null)
- {
- document.getElementsByName('closure_location')[0].value = uroCLocation;
- document.getElementsByName('closure_location')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCReason !== null)
- {
- document.getElementsByName('closure_reason')[0].value = uroCReason;
- document.getElementsByName('closure_reason')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCDirection !== null)
- {
- document.getElementsByName('closure_direction')[0].selectedIndex = uroCDirection;
- document.getElementsByName('closure_direction')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCHasStartDate !== null)
- {
- document.getElementsByName('closure_hasStartDate')[0].checked = uroCHasStartDate;
- document.getElementsByName('closure_hasStartDate')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCStartDate !== null)
- {
- document.getElementsByName('closure_startDate')[0].value = uroCStartDate;
- document.getElementsByName('closure_startDate')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCStartTime !== null)
- {
- document.getElementsByName('closure_startTime')[0].value = uroCStartTime;
- document.getElementsByName('closure_startTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCIgnoreTraffic !== null)
- {
- document.getElementsByName('closure_permanent')[0].checked = uroCIgnoreTraffic;
- document.getElementsByName('closure_permanent')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- if(uroCEndTime !== null)
- {
- document.getElementsByName('closure_endTime')[0].value = uroCEndTime;
- // the cloning process doesn't alter the end time, which seems to confuse WME when it then receives the
- // change event - the MTE dropdown ends up being reset to just the "Choose event" and "None" entries
- // regardless of how many MTE entries there ought to be. The fix for this appears to simply be to then
- // submit a second change event...
- document.getElementsByName('closure_endTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- document.getElementsByName('closure_endTime')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- // the current version of WME wipes any existing end date as soon as the end time is altered, so we now need
- // to set the date after the time instead of before as in earlier versions of this function...
- if(uroCEndDate !== null)
- {
- document.getElementsByName('closure_endDate')[0].value = uroCEndDate;
- document.getElementsByName('closure_endDate')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- uroTempFixMTEDropDown();
- if(uroCEvent !== null)
- {
- if(document.getElementsByName('closure_eventId')[0].options.length > 1)
- {
- for(var loop=0; loop<document.getElementsByName('closure_eventId')[0].options.length; loop++)
- {
- if(document.getElementsByName('closure_eventId')[0].options[loop].value == uroCEvent)
- {
- document.getElementsByName('closure_eventId')[0].selectedIndex = loop;
- break;
- }
- }
- }
- else
- {
- document.getElementsByName('closure_eventId')[0].selectedIndex = 0;
- }
- document.getElementsByName('closure_eventId')[0].dispatchEvent(new Event('change', {'bubbles':true}));
- }
- }
- function uroCloneClosure()
- {
- var closureOffset = parseInt(this.id.split('-')[1]);
- // grab the current closure details from the UI...
- document.getElementsByClassName('closure-item')[closureOffset].children[0].children[0].children[1].click();
- uroCLocation = uroGetElementProperty('closure_location', 0, 'value');
- uroCReason = uroGetElementProperty('closure_reason', 0, 'value');
- uroCEvent = uroGetElementProperty('closure_eventId', 0, 'value');
- uroCDirection = uroGetElementProperty('closure_direction', 0, 'selectedIndex');
- uroCHasStartDate = uroGetElementProperty('closure_hasStartDate', 0, 'checked');
- uroCStartDate = uroGetElementProperty('closure_startDate', 0, 'value');
- uroCStartTime = uroGetElementProperty('closure_startTime', 0, 'value');
- uroCEndDate = uroGetElementProperty('closure_endDate', 0, 'value');
- uroCEndTime = uroGetElementProperty('closure_endTime', 0, 'value');
- uroCIgnoreTraffic = uroGetElementProperty('closure_permanent', 0, 'checked');
- document.getElementsByClassName('closures')[0].getElementsByClassName('cancel-button')[0].click();
- // auto-increment the start and end dates...
- uroCStartDate = uroIncrementClosureDate(uroCStartDate,1);
- uroCEndDate = uroIncrementClosureDate(uroCEndDate,1);
- // generate a click event on the Add a closure button to open up the closure editing UI, then
- // wait for the UI to finish opening...
- document.getElementsByClassName('add-closure-button')[0].click();
- window.setTimeout(uroCompleteClosureCloning,100);
- }
- function uroDeleteNextClosureOnList()
- {
- var nClosures = document.getElementsByClassName('closure-item').length;
- if(nClosures > 0)
- {
- if (nClosures != uroClosuresToDelete)
- {
- uroClosuresToDelete = nClosures;
- document.getElementsByClassName('closure-item')[0].getElementsByClassName('delete')[0].click();
- }
- setTimeout(uroDeleteNextClosureOnList,100);
- }
- else
- {
- uroConfirmClosureDelete = true;
- }
- }
- function uroDeleteAllClosures()
- {
- uroConfirmClosureDelete = true;
- if(window.confirm(I18n.lookup("closures.delete_confirm_no_reason")+' ('+I18n.lookup("closures.apply_to_all")+')'))
- {
- uroConfirmClosureDelete = false;
- var nClosures = document.getElementsByClassName('closure-item').length;
- if(nClosures > 0)
- {
- uroClosuresToDelete = -1;
- uroDeleteNextClosureOnList();
- }
- else
- {
- uroConfirmClosureDelete = true;
- }
- }
- }
- //}
- // Feed Filtering
- //{
- function uroToggleFFCtrls()
- {
- if(uroShowFeedFilter === false)
- {
- uroShowFeedFilter = true;
- document.getElementById('_uroFFCtrlVisibility').className = "fa fa-minus-square-o";
- document.getElementById('uroFFCtrls').style.display = "block";
- }
- else
- {
- uroShowFeedFilter = false;
- document.getElementById('_uroFFCtrlVisibility').className = "fa fa-plus-square-o";
- document.getElementById('uroFFCtrls').style.display = "none";
- }
- }
- function uroForceFeedRefresh()
- {
- uroFeedFilterReloads = 0;
- }
- function uroAddFeedFilterControls()
- {
- if(document.getElementById('sidepanel-feed') != null)
- {
- if(document.getElementById('sidepanel-feed').childNodes[0] != null)
- {
- var nDiv = document.createElement('div');
- var iHTML = '';
- nDiv.id = "uroFeedFilter";
- iHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroFFCtrlVisibility"> </i><b>Feed Filter Controls</b><br>';
- iHTML += '<div id="uroFFCtrls">';
- iHTML += '<b>Filter feed by listing type:</b><br>';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_TypeUR" />UR<br>';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_TypeMP" />MP<br>';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_TypePUR" />PUR<br>';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_TypePM" />PM notifications<br>';
- iHTML += '<br><b>Filter feed by listing reason:</b><br>';
- for(var loop=0; loop < uroFeedFilterFilters.length; loop++)
- {
- iHTML += '<input type="checkbox" id="_cbFeedFilter_'+loop+'" />'+I18n.lookup(uroFeedFilterFilters[loop][0])+'<br>';
- }
- iHTML += '<input type="checkbox" id="_cbFeedFilter_MotNone" />None of the above...<br>';
- iHTML += '<br><input type="checkbox" id="_cbFeedFilter_Invert" />Invert behaviour of above filters<br>';
- iHTML += '<br><b>Filter feed by keyword/phrase:</b><br>';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_HideKeyword" pairedWith="_cbFeedFilter_ShowKeyword" />Hide or ';
- iHTML += '<input type="checkbox" id="_cbFeedFilter_ShowKeyword" pairedWith="_cbFeedFilter_HideKeyword" />show if keyword is present<br>';
- iHTML += '<input type="text" id="_cbFeedFilter_Keyword" />';
- iHTML += '</div>';
- nDiv.innerHTML = iHTML;
- document.getElementById('sidepanel-feed').insertBefore(nDiv,document.getElementById('sidepanel-feed').childNodes[0]);
- uroAddEventListener('_uroFFCtrlVisibility','click',uroToggleFFCtrls, true);
- uroShowFeedFilter = true;
- uroToggleFFCtrls();
- var nDiv2 = document.createElement('div');
- nDiv2.id = "uroFeedRefresher";
- nDiv2.style.display = 'none';
- nDiv2.innerHTML = '<br><div id="_btnFeedRefresh" class="btn btn-block btn-default" style="display: block;"><i class="fa fa-refresh"></div>';
- document.getElementById('sidepanel-feed').appendChild(nDiv2);
- uroAddEventListener('_btnFeedRefresh','click',uroForceFeedRefresh, true);
- }
- }
- }
- function uroTSTFeedFilter()
- {
- var feedEntries = document.getElementsByClassName('feed-item');
- var feedLength = feedEntries.length;
- if(feedLength === 0) return;
- if(document.getElementById('uroFeedFilter') === null) return;
- var hideFI;
- var iHTML;
- var fClass;
- var ffKeyword = uroGetElmValue('_cbFeedFilter_Keyword');
- var ffShowKW = uroGetCBChecked('_cbFeedFilter_ShowKeyword');
- var ffHideKW = uroGetCBChecked('_cbFeedFilter_HideKeyword');
- var kwPresent;
- var isChecked_cbFeedFilter_TypeUR = uroGetCBChecked('_cbFeedFilter_TypeUR');
- var isChecked_cbFeedFilter_TypeMP = uroGetCBChecked('_cbFeedFilter_TypeMP');
- var isChecked_cbFeedFilter_TypePUR = uroGetCBChecked('_cbFeedFilter_TypePUR');
- var isChecked_cbFeedFilter_TypePM = uroGetCBChecked('_cbFeedFilter_TypePM');
- var isChecked_cbFeedFilter_MotNone = uroGetCBChecked('_cbFeedFilter_MotNone');
- var isChecked_cbFeedFilter_Invert = uroGetCBChecked('_cbFeedFilter_Invert');
- var trans = [];
- var isChecked = [];
- var nFilters = uroFeedFilterFilters.length;
- for(var loop=0; loop < nFilters; loop++)
- {
- trans.push(I18n.lookup(uroFeedFilterFilters[loop][0]));
- isChecked.push(uroGetCBChecked('_cbFeedFilter_'+loop));
- }
- for(var i=0; i<feedLength; i++)
- {
- hideFI = false;
- iHTML = feedEntries[i].innerHTML;
- fClass = feedEntries[i].className;
- if(isChecked_cbFeedFilter_TypeUR)
- {
- hideFI |= (fClass.indexOf('feed-issue-ur') != -1);
- }
- if(isChecked_cbFeedFilter_TypeMP)
- {
- hideFI |= (fClass.indexOf('feed-issue-mp') != -1);
- }
- if(isChecked_cbFeedFilter_TypePUR)
- {
- hideFI |= (fClass.indexOf('feed-issue-pu') != -1);
- }
- if(isChecked_cbFeedFilter_TypePM)
- {
- hideFI |= (fClass.indexOf('feed-notification-pm') != -1);
- }
- for(var filters=0; filters < nFilters; filters++)
- {
- if(isChecked[filters])
- {
- hideFI |= (iHTML.indexOf(trans[filters]) != -1);
- }
- }
- if(isChecked_cbFeedFilter_MotNone)
- {
- hideFI |= (iHTML.indexOf('motivation') == -1);
- }
- if(isChecked_cbFeedFilter_Invert)
- {
- hideFI = !hideFI;
- }
- if((ffShowKW) || (ffHideKW))
- {
- kwPresent = (iHTML.indexOf(ffKeyword) != -1);
- hideFI |= (kwPresent & ffHideKW);
- hideFI |= ((!kwPresent) & ffShowKW);
- }
- if(hideFI) feedEntries[i].style.display = 'none';
- else feedEntries[i].style.display = 'block';
- }
- var nFeedItems = document.getElementById('sidepanel-feed').getElementsByClassName('feed-item').length;
- var nVisibleItems = 0;
- for(var j=0; j < nFeedItems; j++)
- {
- if(document.getElementById('sidepanel-feed').getElementsByClassName('feed-item')[j].style.display == 'block')
- {
- nVisibleItems++;
- }
- }
- if(nVisibleItems < 5)
- {
- if(document.getElementById('sidepanel-feed').getElementsByClassName('feed-loading-more')[0].style.display == 'none')
- {
- if(uroFeedFilterReloads < 5)
- {
- document.getElementById('sidepanel-feed').getElementsByClassName('feed-load-more')[0].click();
- uroFeedFilterReloads++;
- document.getElementById('uroFeedRefresher').style.display = 'none';
- }
- else
- {
- document.getElementById('uroFeedRefresher').style.display = 'block';
- }
- }
- }
- else
- {
- uroFeedFilterReloads = 0;
- document.getElementById('uroFeedRefresher').style.display = 'none';
- }
- }
- //}
- function uroGetMarkerType(className)
- {
- var markerType = null;
- if(className.indexOf('user-generated') !== -1) markerType = 'ur';
- else if(className.indexOf('map-problem') !== -1) markerType = 'mp';
- else if(className.indexOf('place-update') !== -1) markerType = 'pur';
- return markerType;
- }
- function uroMarkerMouseOver(e)
- {
- var markerType;
- markerType = uroGetMarkerType(this.className);
- if(markerType !== null)
- {
- var markerID = null;
- markerID = this.attributes["data-id"].value;
- uroAddLog('hover over '+markerType+' ID '+markerID);
- uroMousedOverMarkerID = markerID;
- uroMousedOverMarkerType = markerType;
- if(markerType == 'ur') uroHoveredURID = markerID;
- }
- else
- {
- uroAddLog('hover over unknown object...');
- }
- }
- function uroMarkerMouseOut(e)
- {
- var markerType;
- markerType = uroGetMarkerType(this.className);
- if(markerType !== null)
- {
- var markerID = null;
- markerID = this.attributes["data-id"].value;
- uroAddLog('hover off '+markerType+' ID '+markerID);
- uroMousedOverMarkerID = null;
- uroMousedOverMarkerType = null;
- uroHoveredURID = null;
- }
- else
- {
- uroAddLog('hover off unknown object...');
- }
- }
- function uroMarkerClick()
- {
- var markerType = uroGetMarkerType(this.className);
- if(markerType !== null)
- {
- var markerID = this.attributes["data-id"].value;
- uroAddLog('clicked on '+markerType+' marker '+markerID);
- uroClickedOnMarkerID = markerID;
- uroClickedOnMarkerType = markerType;
- }
- }
- function uroBlobMouseOver(e)
- {
- var blobType = this.attributes.uroBlobType;
- if(blobType !== undefined)
- {
- var blobID = this.attributes.uroBlobID;
- uroAddLog('hover over '+blobType+' ID '+blobID);
- //uroMousedOverMarkerID = markerID;
- //uroMousedOverMarkerType = markerType;
- }
- else
- {
- uroAddLog('hover over unknown blob...');
- }
- }
- function uroBlobMouseOut(e)
- {
- var blobType = this.attributes.uroBlobType;
- if(blobType !== undefined)
- {
- var blobID = this.attributes.uroBlobID;
- uroAddLog('hover off '+blobType+' ID '+blobID);
- //uroMousedOverMarkerID = markerID;
- //uroMousedOverMarkerType = markerType;
- }
- else
- {
- uroAddLog('hover off unknown blob...');
- }
- }
- function uroBlobClick()
- {
- var blobType = this.attributes.uroBlobType;
- if(blobType !== undefined)
- {
- var blobID = this.attributes.uroBlobID;
- uroAddLog('clicked on '+blobType+' blob '+blobID);
- }
- }
- function uroMCLayerChanged()
- {
- if(uroMCLayerIdx != null)
- {
- uroAddLog('adding MC blob event handlers');
- for(var mObj=0; mObj<W.map.layers[uroMCLayerIdx].features.length; mObj++)
- {
- var mcBlobID = W.map.layers[uroMCLayerIdx].features[mObj].model.attributes.geometry.id;
- var mcID = W.map.layers[uroMCLayerIdx].features[mObj].model.attributes.id;
- var mcBlob = document.getElementById(mcBlobID);
- if(mcBlob !== null)
- {
- mcBlob.addEventListener("mouseover", uroBlobMouseOver, false);
- mcBlob.addEventListener("mouseout", uroBlobMouseOut, false);
- mcBlob.addEventListener("click", uroBlobClick, false);
- mcBlob.attributes.uroBlobID = mcID;
- mcBlob.attributes.uroBlobType = "map_comment";
- }
- }
- }
- }
- function uroPlaceLayerChanged()
- {
- uroAddLog('adding place blob event handlers');
- for(var mObj=0; mObj<W.map.landmarkLayer.features.length; mObj++)
- {
- var mcBlobID = W.map.landmarkLayer.features[mObj].model.attributes.geometry.id;
- var mcID = W.map.landmarkLayer.features[mObj].model.attributes.id;
- var mcBlob = document.getElementById(mcBlobID);
- if(mcBlob !== null)
- {
- mcBlob.addEventListener("mouseover", uroBlobMouseOver, false);
- mcBlob.addEventListener("mouseout", uroBlobMouseOut, false);
- mcBlob.addEventListener("click", uroBlobClick, false);
- mcBlob.attributes.uroBlobID = mcID;
- mcBlob.attributes.uroBlobType = "place";
- }
- }
- }
- function uroURLayerChanged()
- {
- uroAddLog('adding UR marker event handlers');
- for(var mObj in W.map.updateRequestLayer.markers)
- {
- var mIcon = W.map.updateRequestLayer.markers[mObj].icon.div;
- mIcon.addEventListener("mouseover",uroMarkerMouseOver, false);
- mIcon.addEventListener("mouseout",uroMarkerMouseOut, false);
- mIcon.addEventListener("click",uroMarkerClick, false);
- }
- }
- function uroMPLayerChanged()
- {
- uroAddLog('adding MP marker event handlers');
- for(var mObj in W.map.problemLayer.markers)
- {
- var mIcon = W.map.problemLayer.markers[mObj].icon.div;
- mIcon.addEventListener("mouseover", uroMarkerMouseOver, false);
- mIcon.addEventListener("mouseout", uroMarkerMouseOut, false);
- mIcon.addEventListener("click", uroMarkerClick, false);
- }
- }
- function uroPURLayerChanged()
- {
- uroAddLog('adding PUR marker event handlers');
- for(var mObj in W.map.placeUpdatesLayer.markers)
- {
- var mIcon = W.map.placeUpdatesLayer.markers[mObj].icon.div;
- mIcon.addEventListener("mouseover", uroMarkerMouseOver, false);
- mIcon.addEventListener("mouseout", uroMarkerMouseOut, false);
- mIcon.addEventListener("click", uroMarkerClick, false);
- }
- }
- function uroFinalizeListenerSetup()
- {
- uroFinalisingListenerSetup = true;
- // filter markers when the marker objects are modified (this happens whenever WME needs to load fresh marker data
- // due to having panned/zoomed the map beyond the extents of the previously loaded data)
- W.model.mapUpdateRequests.on("objectschanged", uroFilterURs_onObjectsChanged);
- W.model.mapUpdateRequests.on("objectsadded", uroFilterURs_onObjectsAdded);
- W.model.mapUpdateRequests.on("objectsremoved", uroFilterURs_onObjectsRemoved);
- W.model.updateRequestSessions.on("objectschanged", uroUREvent_onObjectsChanged);
- W.model.updateRequestSessions.on("objectsadded", uroUREvent_onObjectsAdded);
- W.model.updateRequestSessions.on("objectsremoved", uroUREvent_onObjectsRemoved);
- W.model.cameras.on("objectschanged", uroFilterCameras);
- W.model.cameras.on("objectsadded", uroFilterCameras);
- W.model.cameras.on("objectsremoved", uroFilterCameras);
- W.model.problems.on("objectschanged", uroFilterProblems);
- W.model.problems.on("objectsadded", uroFilterProblems);
- W.model.problems.on("objectsremoved", uroFilterProblems);
- W.model.venues.on("objectschanged", uroFilterPlaces);
- W.model.venues.on("objectsadded", uroFilterPlaces);
- W.model.venues.on("objectsremoved", uroFilterPlaces);
- ////var uroMO_MCLayer = new MutationObserver(uroMCLayerChanged);
- ////uroMO_MCLayer.observe(W.map.layers[uroMCLayerIdx].div,{childList: true, attributes : true, characterData: true, subtree: true});
- ////var uroMO_PlaceLayer = new MutationObserver(uroPlaceLayerChanged);
- ////uroMO_PlaceLayer.observe(W.map.landmarkLayer.div,{childList: true, attributes : true, characterData : true, subtree: true});
- var uroMO_URLayer = new MutationObserver(uroURLayerChanged);
- uroMO_URLayer.observe(W.map.updateRequestLayer.div,{childList : true});
- var uroMO_MPLayer = new MutationObserver(uroMPLayerChanged);
- uroMO_MPLayer.observe(W.map.problemLayer.div,{childList : true});
- var uroMO_PURLayer = new MutationObserver(uroPURLayerChanged);
- uroMO_PURLayer.observe(W.map.placeUpdatesLayer.div,{childList : true});
- var userTabs = document.getElementById(uroUserTabId);
- var tabContent = null;
- var navTabs = userTabs.getElementsByClassName('nav-tabs')[0];
- tabContent = document.getElementById('user-info').getElementsByClassName('tab-content')[0];
- var newtabUR = document.createElement('li');
- newtabUR.innerHTML = '<a href="#sidepanel-uroverview" data-toggle="tab">URO+</a>';
- navTabs.appendChild(newtabUR);
- uroControls.id = "sidepanel-uroverview";
- uroControls.className = "tab-pane";
- tabContent.appendChild(uroControls);
- uroAddEventListener('_btnUndoLastHide',"click", uroRemoveLastAddedIgnore, true);
- uroAddEventListener('_btnClearSessionHides',"click", uroRemoveAllIgnores, true);
- uroEnableIgnoreListControls();
- uroAddEventListener('_btnClearCamWatchList',"click", uroClearCamWatchList, true);
- uroAddEventListener('_btnSettingsToText',"click", uroSettingsToText, true);
- uroAddEventListener('_btnTextToSettings',"click", uroTextToSettings, true);
- uroAddEventListener('_btnResetSettings',"click", uroDefaultSettings, true);
- uroAddEventListener('_btnClearSettingsText',"click", uroClearSettingsText, true);
- uroAddEventListener('_cbMasterEnable',"click", uroFilterItems_MasterEnableClick, true);
- /*
- uroAddEventListener('_btnDebugToScreen',"click", uroDumpDebug, true);
- */
- uroAddEventListener('uroDiv',"dblclick",uroSuppressPopup,true);
- uroAddEventListener('_selectCameraUserID',"change", uroCamEditorSelected, true);
- uroAddEventListener('_selectPlacesUserID',"change", uroPlacesEditorSelected, true);
- uroAddEventListener('uroAlertTickBtn','click',uroCloseAlertBoxWithTick,true);
- uroAddEventListener('uroAlertCrossBtn','click',uroCloseAlertBoxWithCross,true);
- uroSetOnClick("_linkSelectUserRequests",uroShowURTab);
- uroSetOnClick("_linkSelectMapProblems",uroShowMPTab);
- uroSetOnClick("_linkSelectPlaces",uroShowPlacesTab);
- uroSetOnClick("_linkSelectCameras",uroShowCameraTab);
- uroSetOnClick("_linkSelectMisc",uroShowMiscTab);
- uroSetOnClick("_linkSelectOWL",uroShowOWLTab);
- for(var idx=0;idx<W.Config.venues.categories.length;idx++)
- {
- uroSetOnClick('_uroPlacesGroupState-'+idx,uroPlacesGroupCollapseExpand);
- }
- uroAddLog('finalise onload');
- uroLoadSettings();
- uroNewLookCheckDetailsRequest();
- if(uroGetCBChecked('_cbEnableDTE'))
- {
- if(dteControlsIdx != -1)
- {
- dteSetNewTabLength();
- }
- else
- {
- uroAddLog('ERROR - archive panel not found!');
- uroSetStyleDisplay(uroUserTabId,'');
- }
- }
- // filter markers as and when the map is moved
- W.map.events.register("moveend", null, uroFilterItems);
- W.map.events.register("mousemove", null, uroGetAMs);
- W.map.events.register("mousemove", null, uroNewLookHighlightedItemsCheck);
- W.map.events.registerPriority("mousedown", null, uroMouseDown);
- // trap mousedown on Streetview marker drag
- document.getElementsByClassName('street-view-control')[0].onmousedown = uroMouseDown;
- W.map.events.register("mouseup", null, uroMouseUp);
- W.map.events.register("mouseout", null, uroMouseOut);
- uroSetStyles(uroCtrlURs);
- uroSetStyles(uroCtrlMPs);
- uroSetStyles(uroCtrlPlaces);
- uroSetStyles(uroCtrlCameras);
- uroSetStyles(uroCtrlMisc);
- uroSetStyles(uroOWL);
- uroAddFeedFilterControls();
- uroShowURTab();
- uroUserID = W.loginManager.getLoggedInUser().id;
- uroFilterItems();
- uroShowDebugOutput = uroPersistentDebugOutput;
- var dbgMode = "none";
- if(uroShowDebugOutput)
- {
- dbgMode = "inline";
- }
- document.getElementById('_uroDebugMode').style.display = dbgMode;
- uroAddEventListener('_uroVersion',"click", uroToggleDebug, true);
- // add exclusiveCB click handlers to all checkboxes with a pairedWith attribute
- var cbList = document.getElementsByTagName('input');
- for (var optIdx=0;optIdx<cbList.length;optIdx++)
- {
- if((cbList[optIdx].id.indexOf('_cb') === 0) && (cbList[optIdx].attributes.pairedWith != null))
- {
- uroSetOnClick(cbList[optIdx].id,uroExclusiveCB);
- }
- }
- // manually call the layer-change handlers on startup, since there's a good chance WME will already have
- // completed its own startup layer changes before our handlers get registered, preventing the marker handlers
- // from being set up as expected on any markers which are visible in the startup map view before the user forces
- // a layer update by panning/zooming/etc...
- ////uroMCLayerChanged();
- ////uroPlaceLayerChanged();
- uroURLayerChanged();
- uroMPLayerChanged();
- uroPURLayerChanged();
- uroSetupListeners = false;
- uroInitialised = true;
- }
- function uroTSTPopupHandler()
- {
- if(document.getElementsByClassName('panel')[0] === undefined)
- {
- uroHidePopupOnPanelOpen = true;
- }
- if(uroPopupShown === true)
- {
- var hidePopup = false;
- if(document.getElementsByClassName('dropdown action open').length > 0.5)
- {
- hidePopup = true;
- }
- if(hidePopup === false)
- {
- if(document.getElementsByClassName('layer-switcher-container').length === 0)
- {
- if(document.getElementById('layer-switcher-list') !== null)
- {
- hidePopup = (window.getComputedStyle(document.getElementById('layer-switcher-list').parentNode).getPropertyValue('opacity') > 0.5);
- }
- else if(document.getElementsByClassName('layer-switcher').length !== 0)
- {
- hidePopup = (window.getComputedStyle(document.getElementsByClassName('layer-switcher')[0].getElementsByClassName('content')[0]).getPropertyValue('visibility') == 'visible');
- }
- }
- }
- if(hidePopup === false)
- {
- hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-drawing')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
- }
- if(hidePopup === false)
- {
- hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-venues')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
- }
- if(hidePopup === false)
- {
- hidePopup = (window.getComputedStyle(document.getElementsByClassName('toolbar-group-map-comments')[0].childNodes[0]).getPropertyValue('opacity') > 0.5);
- }
- if(document.getElementsByClassName('panel')[0] != null)
- {
- if(uroHidePopupOnPanelOpen === true)
- {
- hidePopup = true;
- uroHidePopupOnPanelOpen = false;
- }
- }
- if(hidePopup === true)
- {
- uroHidePopup();
- }
- }
- if((uroAreaNameHoverObj !== null) && (uroAreaNameHoverTime != -1) && (uroAreaNameOverlayShown === false))
- {
- if(++uroAreaNameHoverTime > 5)
- {
- uroAreaNameOverlaySetup();
- }
- }
- uroReplaceAreaNames(false);
- if(uroPopupTimer > 0)
- {
- if(uroMouseInPopup === false)
- {
- uroPopupTimer--;
- }
- }
- if(uroPopupTimer === 0)
- {
- uroHidePopup();
- }
- if(uroPopupDwellTimer > 0)
- {
- uroPopupDwellTimer--;
- if(uroPopupDwellTimer === 0)
- {
- uroNewLookHighlightedItemsCheck('dwellTimeout');
- }
- }
- }
- function uroTSTDTEHandler()
- {
- if(document.getElementsByClassName("archive-panel")[0] === undefined)
- {
- if(dteClearHighlightsOnPanelClose)
- {
- dteClearListHighlight();
- dteClearHighlightsOnPanelClose = false;
- }
- }
- else
- {
- if(dteArmClearHighlightsOnPanelClose)
- {
- dteArmClearHighlightsOnPanelClose = false;
- dteClearHighlightsOnPanelClose = true;
- }
- }
- }
- function uroTSTNextBtnHandler()
- {
- // replace the "next xxx" button on UR, MP and PUR editing UIs
- if(W.map.panelRegion.hasView() === true)
- {
- var nurButton = W.map.panelRegion.$el[0].getElementsByClassName('btn btn-block')[0];
- if(nurButton != null)
- {
- var doneString = I18n.lookup('problems.panel.done');
- var nextURString = (nurButton.innerHTML.indexOf(I18n.lookup('update_requests.panel.next')) !== -1);
- var nextMPString = (nurButton.innerHTML.indexOf(I18n.lookup('problems.panel.next')) !== -1);
- var nextPURString = (nurButton.innerHTML.indexOf(I18n.lookup('venues.update_requests.panel.next_venue')) !== -1);
- var nextIssueString = (nurButton.innerHTML.indexOf(I18n.lookup('feed.issues.next')) !== -1);
- var updateButton = false;
- var panelClass = W.map.panelRegion.$el[0].childNodes[0].childNodes[0].className;
- var isURorMPPanel = (panelClass.indexOf('problem-edit') !== -1);
- var isPURPanel = (panelClass.indexOf('place-update') !== -1);
- // "next" button class used for UR and MP edit panel
- if(isURorMPPanel === true)
- {
- // user has enabled UR button mod?
- if(uroGetCBChecked('_cbInhibitNURButton') === true)
- {
- // mod the button if this is a UR/MP panel rather than a PUR panel, and if the "Next update request" or "Next issue"
- // text is currently being used on the button - WME uses the former text when a UR is selected directly from the map
- // pin, and the latter text when a UR is selected from the feed. However, it *also* uses the latter text for PURs
- // selected from the feed, hence the need to test the panel type here as well - having to work around odd
- // inconsistencies in WME behaviour, whatever next...
- updateButton = updateButton || ((nextURString === true) || (nextIssueString === true));
- }
- // user has enabled MP button mod?
- if(uroGetCBChecked('_cbInhibitNMPButton') === true)
- {
- // although there's no easy way to determine whether the panel is opened for a UR or MP, since the feed doesn't yet seem
- // to provide a means of accessing MPs then we don't yet have to worry about finding the "Next issue" text in a MP panel,
- // which makes life slightly easier here...
- updateButton = updateButton || (nextMPString === true);
- }
- }
- else if(isPURPanel === true)
- {
- // "next-venue" class only used for PUR edit panel
- if(uroGetCBChecked('_cbInhibitNPURButton') === true)
- {
- // as noted above, PURs opened from the feed may also use the "Next issue" text, so we need to test for that as well,
- // knowing that in order to get this far we've already determined that the user really does want to mod the PUR
- // next button *and* that the currently open panel is a PUR panel...
- updateButton = updateButton || ((nextPURString === true) || (nextIssueString === true));
- }
- }
- if(updateButton === true)
- {
- // if we need to change the button label back to "Done", do it here...
- nurButton.innerHTML = doneString;
- uroAddLog('inhibit Next UR/MP/PUR button');
- }
- // if updateButton isn't already set here, it suggests the panel is using the native "Done" button...
- if(updateButton === false)
- {
- nurButton = W.map.panelRegion.$el[0].getElementsByClassName('btn btn-block done')[0];
- if(nurButton != null)
- {
- updateButton = true;
- }
- }
- if(updateButton === true)
- {
- // Add a new click handler to override the native one - this acts both to prevent the normal action of the "Next UR/MP/PUR" button in
- // moving to the next UR/MP/PUR, and also allows us to warn about closing the UR panel if there's an unsent comment...
- nurButton.addEventListener("click", uroInhibitNextUpdateRequestButton, false);
- }
- }
- }
- }
- function uroTSTCommentAddedHandler()
- {
- // test for the opening or closing of the UR editing dialog so we can detect when a new comment is added
- var URDialogIsOpen = false;
- var panelOpen = (document.getElementById('panel-container').firstChild !== null);
- if(panelOpen)
- {
- if(document.getElementById('panel-container').firstChild.firstChild !== null)
- {
- var panelClass = document.getElementById('panel-container').firstChild.firstChild.className;
- if(panelClass === 'problem-edit severity-low')
- {
- URDialogIsOpen = true;
- }
- }
- }
- if(URDialogIsOpen)
- {
- var thisSelectedURID = document.getElementsByClassName('permalink')[0].href.split('&mapUpdateRequest=');
- if(thisSelectedURID.length > 1)
- {
- thisSelectedURID = thisSelectedURID[1].split('&')[0];
- }
- else
- {
- thisSelectedURID = null;
- }
- if(thisSelectedURID != uroSelectedURID)
- {
- // if the user selects a new UR whilst the editing dialog is still open, treat it in the
- // same way as if the user had selected that UR with the dialog closed
- uroURDialogIsOpen = false;
- }
- if(uroURDialogIsOpen === false)
- {
- // user is editing a new UR
- uroSelectedURID = thisSelectedURID;
- // add our own click event handler to the Send button, so we can do stuff whenever a new comment is added
- document.getElementsByClassName('new-comment-form')[0].getElementsByClassName('btn')[0].addEventListener("click", uroAddedComment, false);
- uroAddLog('user is editing UR '+uroSelectedURID);
- uroExpectedCommentCount = W.model.updateRequestSessions.objects[uroSelectedURID].comments.length;
- ////if(uroShowDebugOutput === true)
- {
- if((uroHoveredURID !== null) && (uroSelectedURID !== null) && (parseInt(uroHoveredURID) !== parseInt(uroSelectedURID)))
- {
- if(uroURReclickAttempts === 0)
- {
- uroAddLog('DANGER, WILL ROBINSON! You clicked on UR ID '+uroHoveredURID+' but WME has loaded the details for UR ID '+uroSelectedURID+' instead, attempting to fix...');
- }
- if(++uroURReclickAttempts < 3)
- {
- //uroRestackMarkers();
- W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.x = W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.realX;
- W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.y = W.map.updateRequestLayer.markers[uroHoveredURID].model.attributes.geometry.realY;
- W.map.updateRequestLayer.markers[uroHoveredURID].icon.$div.click();
- return;
- }
- else
- {
- uroAddLog('Woe is me, attempting to open UR ID '+uroHoveredURID+' has failed...');
- uroShowAlertBox('fa-warning', 'URO+ Warning', 'WME may have opened the details panel for a different UR to the one you selected, proceed with caution', false, "OK", "", null, null);
- }
- }
- uroURReclickAttempts = 0;
- }
- }
- }
- else if(uroURDialogIsOpen === true)
- {
- // dialog was open and has now been closed
- uroSelectedURID = null;
- }
- uroURDialogIsOpen = URDialogIsOpen;
- if(((uroPendingCommentDataRefresh === true) || (uroWaitingCommentDataRefresh === true)) && (uroSelectedURID !== null))
- {
- uroAddLog('check completion of comment data refresh for UR '+uroSelectedURID+' ('+uroPendingCommentDataRefresh+','+uroWaitingCommentDataRefresh+')');
- uroGetSelectedURCommentCount();
- }
- }
- function uroTSTOWLHandler()
- {
- /*
- var selectedTotal = W.selectionManager.selectedItems.length;
- if((selectedTotal > 0) && (document.getElementById('_uroDivOWLBtns') === null))
- {
- var selectedClass = W.selectionManager.selectedItems[0].model.CLASS_NAME;
- var displayAddToOWLBtn = false;
- var displayUpdateOWLBtn = false;
- var displayRemoveFromOWLBtn = false;
- var selectedSegments = false;
- var selectedLandmarks = false;
- var fid;
- var loop;
- // WME only seems to allow multi-object selections for segments, so testing the class of the first object in the
- // selection list tells us the class of any other objects in the list too...
- if(selectedClass == "Waze.Feature.Vector.Segment")
- {
- selectedSegments = true;
- for(loop=0; loop<selectedTotal; loop++)
- {
- fid = W.selectionManager.selectedItems[loop].model.attributes.id;
- var segIdx = uroIsSegOnWatchList(fid);
- if(segIdx == -1)
- {
- displayAddToOWLBtn = true;
- }
- else
- {
- if(uroSegDataChanged(segIdx))
- {
- displayUpdateOWLBtn = true;
- }
- displayRemoveFromOWLBtn = true;
- }
- }
- }
- else if(selectedClass == "Waze.Feature.Vector.Landmark")
- {
- selectedLandmarks = true;
- for(loop=0; loop<selectedTotal; loop++)
- {
- fid = W.selectionManager.selectedItems[loop].model.attributes.id;
- var placeIdx = uroIsPlaceOnWatchList(fid);
- if(placeIdx == -1)
- {
- displayAddToOWLBtn = true;
- }
- else
- {
- if(uroPlaceDataChanged(placeIdx))
- {
- displayUpdateOWLBtn = true;
- }
- displayRemoveFromOWLBtn = true;
- }
- }
- }
- var btnHTML = '<div id="_uroDivOWLBtns">';
- if((displayAddToOWLBtn === true) && (displayUpdateOWLBtn === false))
- {
- btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to OWL</button>';
- }
- else if((displayUpdateOWLBtn === true) && (displayAddToOWLBtn === false))
- {
- btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Update OWL</button>';
- }
- else if((displayAddToOWLBtn === true) && (displayUpdateOWLBtn === true))
- {
- btnHTML += '<button class="btn btn-default" id="_btnAddUpdateOWL">Add to & Update OWL</button>';
- }
- if(displayRemoveFromOWLBtn === true)
- {
- btnHTML += '<button class="btn btn-default" id="_btnRemoveOWL">Remove from OWL</button>';
- }
- btnHTML += '</div>';
- // note to self... altering the inner HTML of the segment-edit-general panel when the selected
- // segment is part of a roundabout always used to disable the onclick handler for the select
- // roundabout button. will need to see how this behaves in the current WME given the changes in
- // panel arrangement and the introduction of the native select roundabout button
- if(selectedSegments === true)
- {
- document.getElementById("segment-edit-general").innerHTML += btnHTML;
- }
- else if(selectedLandmarks === true)
- {
- document.getElementById("landmark-edit-general").innerHTML += btnHTML;
- }
- if((displayAddToOWLBtn === true)||(displayUpdateOWLBtn === true))
- {
- if(selectedSegments === true)
- {
- uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdateSegWatchList, true);
- }
- else
- {
- uroAddEventListener('_btnAddUpdateOWL','click', uroAddUpdatePlaceWatchList, true);
- }
- }
- if(displayRemoveFromOWLBtn === true)
- {
- if(selectedSegments === true)
- {
- uroAddEventListener('_btnRemoveOWL','click', uroRemoveSegFromWatchList, true);
- }
- else
- {
- uroAddEventListener('_btnRemoveOWL','click', uroRemovePlaceFromWatchList, true);
- }
- }
- }
- */
- }
- function uroTSTClosureCloningHandler()
- {
- // closure cloning support...
- //
- // has the closures tab been generated?
- if(document.getElementById('segment-edit-closures') !== null)
- {
- // and is it active?
- if(document.getElementById('segment-edit-closures').className === 'tab-pane active')
- {
- // and are there any closures defined for all of the selected segment(s)...
- if(document.getElementsByClassName('full-closures').length > 0)
- {
- var nClosures = document.getElementsByClassName('full-closures')[0].childNodes.length;
- if(nClosures > 0)
- {
- // and last but by no means least, have we already added the clone icon to this closure?
- for(var cLoop = 0; cLoop < nClosures; cLoop++)
- {
- var btnElm = document.getElementsByClassName('full-closures')[0].childNodes[cLoop].children[0].children[0];
- if(btnElm.innerHTML.indexOf('_uroCloneClosure-') == -1)
- {
- var newAnchor = document.createElement('a');
- var anchorID = '_uroCloneClosure-'+cLoop;
- newAnchor.href="#";
- newAnchor.innerHTML = "<i class='fa fa-copy'></i>";
- newAnchor.id = anchorID;
- btnElm.appendChild(newAnchor);
- uroAddEventListener(anchorID,"click",uroCloneClosure,false);
- }
- }
- }
- }
- // if there's more than one closure (full or partial) listed, also add the delete all button if not already present...
- if(document.getElementsByClassName('closure-item').length > 1)
- {
- if(document.getElementById('_btnDeleteAllClosures') === null)
- {
- var daDiv = document.createElement('div');
- daDiv.className = 'delete-all-button btn btn-primary';
- daDiv.id = '_btnDeleteAllClosures';
- daDiv.innerHTML = '<i class="fa fa-trash"></i> '+I18n.lookup("closures.delete_confirm_no_reason")+' ('+I18n.lookup("closures.apply_to_all")+')';
- daDiv.style.width = '100%';
- daDiv.style.marginBottom = '10px';
- var acBtn = document.getElementsByClassName('add-closure-button')[0];
- acBtn.parentNode.insertBefore(daDiv, acBtn.nextSibling);
- uroAddEventListener('_btnDeleteAllClosures',"click", uroDeleteAllClosures, false);
- }
- }
- }
- }
- }
- function uroMiscUITweaksHandler()
- {
- if(uroFilterPreamble())
- {
- // give user the option of setting their own background colour...
- {
- var mapviewport = document.getElementsByClassName("olMapViewport")[0];
- if((uroGetCBChecked('_cbWhiteBackground') === true) && (uroGetCBChecked('_cbMasterEnable') === true))
- {
- var customColour = '#' + uroToHex(uroGetElmValue('_inputCustomBackgroundRed'),2);
- customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundGreen'),2);
- customColour += uroToHex(uroGetElmValue('_inputCustomBackgroundBlue'),2);
- mapviewport.style.backgroundColor = customColour;
- }
- else
- {
- mapviewport.style.backgroundColor = "#C2C2C2";
- }
- }
- // allows user to hide the area managers layer without switching off the layer completely...
- {
- // ...if this sounds like a weird option - why not just switch off the layer from the layers menu? - then
- // remember that in order for URO+ to be able to display in its own tab the list of AMs under the current
- // mouse pointer location, which is somewhat more useful than the list given in the topbar, it needs the
- // AM layer to be activated so that the AM areas data is loaded into WME. It doesn't however need the layer
- // to then be visible, and since having a bunch of purple polygons covering the map can make for a rather
- // difficult editing experience, being able to hide the polys whilst retaining the area information is
- // of real benefit...
- if((uroGetCBChecked('_cbHideAMLayer')) && (uroGetCBChecked('_cbMasterEnable')))
- {
- W.map.managedAreasLayer.setOpacity(0);
- }
- else
- {
- W.map.managedAreasLayer.setOpacity(1);
- }
- }
- // gives user the option of minimising the size of the sidebar tabs to save space
- {
- if(!uroGetCBChecked('_cbDisableTabStyling'))
- {
- // The nav-tabs class is now also used for the General/Closures tabs on the segment edit panel, so we have
- // to restrict the scope of this code to just those nav-tab classed elements within the user-tabs element.
- var navTabs = document.getElementById('user-tabs').getElementsByClassName("nav-tabs")[0].children;
- for(var loop = 0; loop<navTabs.length; loop++)
- {
- navTabs[loop].children[0].style.padding = "4px";
- }
- }
- }
- // gives user the option of hiding the somewhat unnecessary editor info panel at the top of the sidebar
- {
- var panelDisplay = '';
- if(uroGetCBChecked('_cbHideEditorInfo'))
- {
- panelDisplay = "none";
- }
- document.getElementById("user-details").style.display = panelDisplay;
- }
- }
- }
- function uroTenthSecondTick()
- {
- if(uroMTEMode) return;
- if(uroSetupListeners)
- {
- if(uroFinalisingListenerSetup === false)
- {
- if(W.loginManager.isLoggedIn())
- {
- uroFinalizeListenerSetup();
- }
- }
- }
- else
- {
- uroTSTPopupHandler();
- uroTSTDTEHandler();
- uroTSTNextBtnHandler();
- uroTSTCommentAddedHandler();
- uroTSTOWLHandler();
- uroTSTClosureCloningHandler();
- uroTSTFeedFilter();
- uroMiscUITweaksHandler();
- uroTempFixMTEDropDown();
- }
- }
- function uroActiveTab(_id)
- {
- var e = document.getElementById(_id);
- e.style.backgroundColor = "aliceblue";
- e.style.borderTop = "1px solid";
- e.style.borderLeft = "1px solid";
- e.style.borderRight = "1px solid";
- e.style.borderBottom = "0px solid";
- }
- function uroInactiveTab(_id)
- {
- var e = document.getElementById(_id);
- e.style.backgroundColor = "white";
- e.style.borderTop = "0px solid";
- e.style.borderLeft = "0px solid";
- e.style.borderRight = "0px solid";
- e.style.borderBottom = "1px solid";
- }
- function uroInactiveAllTabs()
- {
- uroInactiveTab("_tabSelectCameras");
- uroInactiveTab("_tabSelectMapProblems");
- uroInactiveTab("_tabSelectMisc");
- uroInactiveTab("_tabSelectUserRequests");
- uroInactiveTab("_tabSelectCWL");
- uroInactiveTab("_tabSelectPlaces");
- if(!uroCtrlsHidden)
- {
- uroSetStyleDisplay('uroCtrlURs','none');
- uroSetStyleDisplay('uroCtrlMPs','none');
- uroSetStyleDisplay('uroCtrlCameras','none');
- uroSetStyleDisplay('uroCtrlMisc','none');
- uroSetStyleDisplay('uroOWL','none');
- uroSetStyleDisplay('uroCtrlPlaces','none');
- }
- }
- function uroShowURTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectUserRequests");
- uroCurrentTab = 1;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlURs','block');
- return false;
- }
- function uroShowMPTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectMapProblems");
- uroCurrentTab = 2;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMPs','block');
- return false;
- }
- function uroShowPlacesTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectPlaces");
- uroCurrentTab = 3;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlPlaces','block');
- for(var idx=0;idx<uroPlacesGroupsCollapsed.length;idx++)
- {
- uroPlacesGroupCEHandler(idx);
- }
- return false;
- }
- function uroShowCameraTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectCameras");
- uroCurrentTab = 4;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlCameras','block');
- return false;
- }
- function uroShowOWLTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectCWL");
- uroCurrentTab = 5;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroOWL','block');
- uroOWLUpdateHTML();
- return false;
- }
- function uroShowMiscTab()
- {
- uroInactiveAllTabs();
- uroActiveTab("_tabSelectMisc");
- uroCurrentTab = 6;
- if(!uroCtrlsHidden) uroSetStyleDisplay('uroCtrlMisc','block');
- return false;
- }
- function uroNewLookCheckDetailsRequest()
- {
- var thisurl = document.location.href;
- var doRetry = true;
- var urID;
- var endmarkerpos = thisurl.indexOf('&endshow');
- var showmarkerpos = thisurl.indexOf('&showturn=');
- if((endmarkerpos != -1) && (showmarkerpos != -1))
- {
- showmarkerpos += 10;
- uroAddLog('showturn tab opened');
- urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
- uroAddLog(' turn problem ID = '+urID);
- try
- {
- W.map.problemLayer.markers[urID].icon.imageDiv.click();
- doRetry = false;
- }
- catch(err)
- {
- uroAddLog('problems not fully loaded, retrying...');
- }
- if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
- }
- else
- {
- showmarkerpos = thisurl.indexOf('&showpur=');
- if((endmarkerpos != -1) && (showmarkerpos != -1))
- {
- showmarkerpos += 9;
- uroAddLog('showPUR tab opened');
- urID = thisurl.substr(showmarkerpos,endmarkerpos-showmarkerpos);
- uroAddLog(' PUR ID = '+urID);
- try
- {
- W.map.placeUpdatesLayer.markers[urID].icon.imageDiv.click();
- doRetry = false;
- }
- catch(err)
- {
- uroAddLog('PURs not fully loaded, retrying...');
- }
- if(doRetry) setTimeout(uroNewLookCheckDetailsRequest,500);
- }
- }
- }
- function uroUpdateVenueEditorList()
- {
- if(Object.keys(W.model.venues.objects).length === 0) return;
- var selector = document.getElementById('_selectPlacesUserID');
- var selectedUser = null;
- if(selector.selectedOptions[0] != null)
- {
- selectedUser = parseInt(selector.selectedOptions[0].value);
- }
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- var selectedIdx = null;
- var listedIDs = [];
- var idx;
- for(idx in W.model.venues.objects)
- {
- if(W.model.venues.objects.hasOwnProperty(idx))
- {
- var obj = W.model.venues.objects[idx].attributes;
- var cbID = obj.createdBy;
- var ubID = obj.updatedBy;
- if((cbID !== null) && (listedIDs.indexOf(cbID) == -1))
- {
- listedIDs.push(cbID);
- }
- if((ubID !== null) && (ubID !== cbID) && (listedIDs.indexOf(ubID) == -1))
- {
- listedIDs.push(ubID);
- }
- }
- }
- selector.options.add(new Option('<select a user>', null));
- if(listedIDs.length > 0)
- {
- var users = W.model.users.getByIds(listedIDs);
- var selectorEntry = '';
- for(idx=0; idx<users.length; idx++)
- {
- if(users[idx].userName === undefined)
- {
- selectorEntry = users[idx].id;
- }
- else
- {
- selectorEntry = users[idx].userName;
- }
- selector.options.add(new Option(selectorEntry, users[idx].id));
- if(users[idx].id == selectedUser)
- {
- selectedIdx = idx+1;
- }
- }
- }
- if(selectedIdx !== null)
- {
- selector.selectedIndex = selectedIdx;
- }
- }
- function uroPlacesEditorSelected()
- {
- var selector = document.getElementById('_selectPlacesUserID');
- if(selector.selectedIndex > 0)
- {
- document.getElementById('_textPlacesEditor').value = document.getElementById('_selectPlacesUserID').selectedOptions[0].innerHTML;
- }
- }
- function uroUpdateMPSolverList()
- {
- if(Object.keys(W.model.problems.objects).length === 0)
- {
- return;
- }
- var resolverList = [];
- var selector = document.getElementById('_selectMPUserID');
- var selectedUser = null;
- if(selector.selectedOptions[0] != null)
- {
- selectedUser = parseInt(selector.selectedOptions[0].value);
- }
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- var selectedIdx = 0;
- var idx = 0;
- for (var mpobj in W.model.problems.objects)
- {
- if(W.model.problems.objects.hasOwnProperty(mpobj))
- {
- var prob = W.model.problems.objects[mpobj];
- if(prob.attributes.resolvedBy !== null)
- {
- var userID = prob.attributes.resolvedBy;
- var userName = W.model.users.objects[userID].userName;
- if(resolverList.indexOf(userName) == -1)
- {
- resolverList.push(userName);
- selector.options.add(new Option(userName, userID));
- if(userID == selectedUser)
- {
- selectedIdx = idx;
- }
- idx++;
- }
- }
- }
- }
- if(selectedIdx !== null)
- {
- selector.selectedIndex = selectedIdx;
- }
- }
- function uroUpdateResolverList()
- {
- if(Object.keys(W.model.mapUpdateRequests.objects).length === 0)
- {
- return;
- }
- var resolverList = [];
- var selector = document.getElementById('_selectURResolverID');
- var selectedUser = null;
- if(selector.selectedOptions[0] != null)
- {
- selectedUser = parseInt(selector.selectedOptions[0].value);
- }
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- var selectedIdx = 0;
- var idx = 0;
- for (var urobj in W.model.mapUpdateRequests.objects)
- {
- if(W.model.mapUpdateRequests.objects.hasOwnProperty(urobj))
- {
- var ureq = W.model.mapUpdateRequests.objects[urobj];
- if(ureq.attributes.resolvedBy !== null)
- {
- var userID = ureq.attributes.resolvedBy;
- var userName = W.model.users.objects[userID].userName;
- if(resolverList.indexOf(userName) == -1)
- {
- resolverList.push(userName);
- selector.options.add(new Option(userName, userID));
- if(userID == selectedUser)
- {
- selectedIdx = idx;
- }
- idx++;
- }
- }
- }
- }
- if(selectedIdx !== null)
- {
- selector.selectedIndex = selectedIdx;
- }
- }
- function uroUpdateUserList()
- {
- if(Object.keys(W.model.updateRequestSessions.objects).length === 0) return;
- var selector = document.getElementById('_selectURUserID');
- var selectedUser = null;
- if(selector.selectedOptions[0] != null)
- {
- selectedUser = parseInt(selector.selectedOptions[0].value);
- }
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- var selectedIdx = null;
- var listedIDs = [];
- for(var ursIdx in W.model.updateRequestSessions.objects)
- {
- if(W.model.updateRequestSessions.objects.hasOwnProperty(ursIdx))
- {
- var ursObj = W.model.updateRequestSessions.objects[ursIdx];
- if(ursObj.comments.length > 0)
- {
- for(var cidx=0; cidx < ursObj.comments.length; cidx++)
- {
- var userID = ursObj.comments[cidx].userID;
- if((listedIDs.indexOf(userID) == -1) && (userID != -1))
- {
- listedIDs.push(userID);
- }
- }
- }
- }
- }
- if(listedIDs.length > 0)
- {
- var users = W.model.users.getByIds(listedIDs);
- for(var idx=0; idx<listedIDs.length; idx++)
- {
- selector.options.add(new Option(users[idx].userName, listedIDs[idx]));
- if(listedIDs[idx] == selectedUser)
- {
- selectedIdx = idx;
- }
- }
- }
- if(selectedIdx !== null)
- {
- selector.selectedIndex = selectedIdx;
- }
- }
- function uroUpdateCamEditorList()
- {
- if(Object.keys(W.model.cameras.objects).length === 0) return;
- var selector = document.getElementById('_selectCameraUserID');
- var selectedUser = null;
- if(selector.selectedOptions[0] != null)
- {
- selectedUser = parseInt(selector.selectedOptions[0].value);
- }
- while(selector.options.length > 0)
- {
- selector.options.remove(0);
- }
- var selectedIdx = null;
- var listedIDs = [];
- for(var camIdx in W.model.cameras.objects)
- {
- if(W.model.cameras.objects.hasOwnProperty(camIdx))
- {
- var camObj = W.model.cameras.objects[camIdx].attributes;
- var cbID = camObj.createdBy;
- var ubID = camObj.updatedBy;
- if((cbID !== null) && (listedIDs.indexOf(cbID) == -1))
- {
- listedIDs.push(cbID);
- }
- if((ubID !== null) && (ubID !== cbID) && (listedIDs.indexOf(ubID) == -1))
- {
- listedIDs.push(ubID);
- }
- }
- }
- selector.options.add(new Option('<select a user>', null));
- if(listedIDs.length > 0)
- {
- var users = W.model.users.getByIds(listedIDs);
- var selectorEntry = '';
- for(var idx=0; idx<users.length; idx++)
- {
- if(users[idx].userName === undefined)
- {
- selectorEntry = users[idx].id;
- }
- else
- {
- selectorEntry = users[idx].userName;
- }
- selector.options.add(new Option(selectorEntry, users[idx].id));
- if(users[idx].id == selectedUser)
- {
- selectedIdx = idx+1;
- }
- }
- }
- if(selectedIdx !== null)
- {
- selector.selectedIndex = selectedIdx;
- }
- }
- function uroCamEditorSelected()
- {
- var selector = document.getElementById('_selectCameraUserID');
- if(selector.selectedIndex > 0)
- {
- document.getElementById('_textCameraEditor').value = document.getElementById('_selectCameraUserID').selectedOptions[0].innerHTML;
- }
- }
- function uroSetStyles(obj)
- {
- obj.style.fontSize = '12px';
- obj.style.lineHeight = '100%';
- obj.style.overflow = 'auto';
- obj.style.height = (window.innerHeight * 0.55) + 'px';
- }
- function uroPlacesGroupCEHandler(groupidx)
- {
- if(uroPlacesGroupsCollapsed[groupidx] === false)
- {
- document.getElementById('_uroPlacesGroup-'+groupidx).style.display = "block";
- document.getElementById('_uroPlacesGroupState-'+groupidx).className = "fa fa-minus-square-o";
- }
- else
- {
- document.getElementById('_uroPlacesGroup-'+groupidx).style.display = "none";
- document.getElementById('_uroPlacesGroupState-'+groupidx).className = "fa fa-plus-square-o";
- }
- }
- function uroPlacesGroupCollapseExpand()
- {
- var groupidx = this.id.substr(21);
- if(uroPlacesGroupsCollapsed[groupidx] === true) uroPlacesGroupsCollapsed[groupidx] = false;
- else uroPlacesGroupsCollapsed[groupidx] = true;
- uroPlacesGroupCEHandler(groupidx);
- return false;
- }
- function uroPopulateProblemsTab()
- {
- var tHTML = '';
- tHTML += '<input type="checkbox" id="_cbMPFilterOutsideArea">Hide MPs outside my editable area</input><br><br>';
- tHTML += '<b>Filter MPs by type:</b><br>';
- var i;
- for(i=0; i<uroKnownProblemTypeNames.length; i++)
- {
- tHTML += '<input type="checkbox" id="_cbMPFilter_T'+uroKnownProblemTypeIDs[i]+'">'+uroKnownProblemTypeNames[i]+'</input><br>';
- }
- tHTML += '<br><input type="checkbox" id="_cbMPFilterUnknownProblem">Unknown problem type</input><br><br>';
- tHTML += ' <i>Specially tagged types</i><br>';
- tHTML += ' <input type="checkbox" id="_cbFilterElgin">[Elgin]</input><br>';
- tHTML += ' <input type="checkbox" id="_cbFilterTrafficCast">[TrafficCast]</input><br>';
- tHTML += ' <input type="checkbox" id="_cbFilterTrafficMaster">[TM]</input><br>';
- tHTML += ' <input type="checkbox" id="_cbFilterCaltrans">[Caltrans]</input><br>';
- tHTML += ' <input type="checkbox" id="_cbFilterTFL">TfL</input><br>';
- tHTML += '<input type="checkbox" id="_cbMPFilterReopenedProblem">Reopened Problems</input><br><br>';
- tHTML += '<input type="checkbox" id="_cbInvertMPFilter">Invert operation of type filters?</input><br>';
- tHTML += '<br><b>Hide closed/solved/unidentified Problems:</b><br>';
- tHTML += '<input type="checkbox" id="_cbMPFilterClosed">Closed</input><br>';
- tHTML += '<input type="checkbox" id="_cbMPFilterSolved">Solved</input><br>';
- tHTML += '<input type="checkbox" id="_cbMPFilterUnidentified">Not identified</input><br><br>';
- tHTML += '<input type="checkbox" id="_cbMPClosedUserIDFilter" pairedWith="_cbMPNotClosedUserIDFilter">Closed</input> or ';
- tHTML += '<input type="checkbox" id="_cbMPNotClosedUserIDFilter" pairedWith="_cbMPClosedUserIDFilter">Not Closed</input> by user';
- tHTML += '<select id="_selectMPUserID" style="width:80%; height:22px;"></select><br>';
- tHTML += '<br><b>Hide problems (not turn) by severity:</b><br>';
- tHTML += '<input type="checkbox" id="_cbMPFilterLowSeverity">Low</input> ';
- tHTML += '<input type="checkbox" id="_cbMPFilterMediumSeverity">Medium</input> ';
- tHTML += '<input type="checkbox" id="_cbMPFilterHighSeverity">High</input><br>';
- uroCtrlMPs.innerHTML = tHTML;
- }
- function uroPopulatePlacesTab()
- {
- var tHTML = '';
- tHTML += '<b>Filter PURs by category/status:</b><br>';
- tHTML += '<input type="checkbox" id="_cbFilterUneditablePlaceUpdates">Ones I can\'t edit</input><br>';
- tHTML += '<input type="checkbox" id="_cbFilterLockRankedPlaceUpdates">Ones with non-zero lockRanks</input><br>';
- tHTML += '<input type="checkbox" id="_cbFilterNewPlacePUR">Ones for new places</input><br>';
- tHTML += '<input type="checkbox" id="_cbFilterUpdatedDetailsPUR">Ones for updated place details</input><br>';
- tHTML += '<input type="checkbox" id="_cbFilterNewPhotoPUR">Ones for new photos</input><br>';
- tHTML += '<input type="checkbox" id="_cbFilterFlaggedPUR">Ones flagged for attention</input><br>';
- tHTML += '<br><input type="checkbox" id="_cbLeavePURGeos">Don\'t hide place polygons/points</input><br>';
- tHTML += '<br><input type="checkbox" id="_cbInvertPURFilters">Invert PUR filters</input><br>';
- tHTML += '<br><b>Filter PURs by severity:</b><br>';
- tHTML += '<input type="checkbox" id="_cbPURFilterLowSeverity">Low</input> ';
- tHTML += '<input type="checkbox" id="_cbPURFilterMediumSeverity">Medium</input> ';
- tHTML += '<input type="checkbox" id="_cbPURFilterHighSeverity">High</input>';
- tHTML += '<br><b>Filter PURs by age of submission:</b><br>';
- tHTML += '<input type="checkbox" id="_cbEnablePURMinAgeFilter">Hide PURs less than </input>';
- tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMinDays"> days old<br>';
- tHTML += '<input type="checkbox" id="_cbEnablePURMaxAgeFilter">Hide PURs more than </input>';
- tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPURFilterMaxDays"> days old<br>';
- tHTML += '<hr>';
- tHTML += '<br><b>Filter Places by state:</b><br>';
- tHTML += 'Hide if last edited<br>';
- tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedLessThan"> less than </input>';
- tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMinDays"> days ago<br>';
- tHTML += '<input type="checkbox" id="_cbPlaceFilterEditedMoreThan"> more than </input>';
- tHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterPlaceEditMaxDays"> days ago<br>';
- tHTML += '<br>Hide if locked at level:<br>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL0">1</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL1">2</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL2">3</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL3">4</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL4">5</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesL5">6</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePlacesStaff">Staff</input>';
- tHTML += '<br> <input type="checkbox" id="_cbHidePlacesAdLocked">AdLocked</input><br>';
- tHTML += '<br>Hide by geometry:<br>';
- tHTML += ' <input type="checkbox" id="_cbHideAreaPlaces">Areas</input>';
- tHTML += ' <input type="checkbox" id="_cbHidePointPlaces">Points</input>';
- tHTML += '<br><br><input type="checkbox" id="_cbHidePhotoPlaces" pairedWith="_cbHideNoPhotoPlaces">Hide or </input>';
- tHTML += '<input type="checkbox" id="_cbHideNoPhotoPlaces" pairedWith="_cbHidePhotoPlaces">show ones with photos</input><br>';
- tHTML += '<input type="checkbox" id="_cbHideLinkedPlaces" pairedWith="_cbHideNoLinkedPlaces">Hide or </input>';
- tHTML += '<input type="checkbox" id="_cbHideNoLinkedPlaces" pairedWith="_cbHideLinkedPlaces">show ones with external links</input><br>';
- tHTML += '<input type="checkbox" id="_cbHideKeywordPlaces" pairedWith="_cbHideNoKeywordPlaces">Hide or </input>';
- tHTML += '<input type="checkbox" id="_cbHideNoKeywordPlaces" pairedWith="_cbHideKeywordPlaces">show ones with a name including</input><br>';
- tHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPlace"><br>';
- tHTML += '<br><b>Show Places touched by a specific editor:</b><br>';
- tHTML += '<input type="checkbox" id="_cbShowOnlyPlacesCreatedBy">Created by</input> / ';
- tHTML += '<input type="checkbox" id="_cbShowOnlyPlacesEditedBy">edited by</input><br>';
- tHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textPlacesEditor"><br>';
- tHTML += '<select id="_selectPlacesUserID" style="width:80%; height:22px;"></select><br>';
- tHTML += '<br><br><b>Filter Places by category:</b><br>';
- var nCategories = W.Config.venues.categories.length;
- var i;
- if(uroPlacesGroupsCollapsed.length != nCategories)
- {
- for(i=0; i<nCategories; i++)
- {
- uroPlacesGroupsCollapsed.push(false);
- }
- }
- for(i=0; i<nCategories; i++)
- {
- var parentCategory = W.Config.venues.categories[i];
- var localisedName = I18n.lookup("venues.categories." + parentCategory);
- if(uroPlacesGroupsCollapsed[i] === true)
- {
- tHTML += '<i class="fa fa-plus-square-o" style="cursor:pointer;font-size:14px;" id="_uroPlacesGroupState-'+i+'"></i>';
- }
- else
- {
- tHTML += '<i class="fa fa-minus-square-o" style="cursor:pointer;font-size:14px;" id="_uroPlacesGroupState-'+i+'"></i>';
- }
- tHTML += ' <input type="checkbox" id="_cbPlacesFilter-'+parentCategory+'"><b>'+localisedName+'</b></input><br>';
- tHTML += '<div id="_uroPlacesGroup-'+i+'" style="padding:3px;border-width:2px;border-style:solid;border-color:#FFFFFF">';
- for(var ii=0; ii<W.Config.venues.subcategories[parentCategory].length; ii++)
- {
- var subCategory = W.Config.venues.subcategories[parentCategory][ii];
- localisedName = I18n.lookup("venues.categories." + subCategory);
- tHTML += ' <input type="checkbox" id="_cbPlacesFilter-'+subCategory+'">'+localisedName+'</input><br>';
- }
- tHTML += '</div>';
- }
- tHTML += '<input type="checkbox" id="_cbFilterPrivatePlaces"><b>Residential Places</b></input><br>';
- tHTML += '<br><input type="checkbox" id="_cbInvertPlacesFilter">Invert Place filters?</input>';
- uroCtrlPlaces.innerHTML = tHTML;
- }
- function uroWazeBits()
- {
- // "fake" uroWazeBits() function which only performs layer scan, to stop the uroWazeBits() call in WMETB from
- // messing around with other stuff in the actual uroWazeBits() function (now renamed uroRealWazeBits...) that
- // really only ought to be called once.
- var i;
- for(i=0;i<W.map.layers.length;i++)
- {
- if(W.map.layers[i].CLASS_NAME == 'OpenLayers.Layer.Vector.RootContainer') uroRootContainer = W.map.layers[i].div.id;
- if(W.map.layers[i].name == 'Node Connections') uroTurnsLayerIdx = i;
- if(W.map.layers[i].name == 'Map comments') uroMCLayerIdx = i;
- }
- uroPlacesRoot = W.map.landmarkLayer.id + '_vroot';
- for(i=0;i<W.map.controls.length;i++)
- {
- if(W.map.controls[i].CLASS_NAME == 'Waze.View.ArchivePanel') dteControlsIdx = i;
- else if(W.map.controls[i].CLASS_NAME == 'Waze.Control.Archive') dteControlsIdx = i;
- if(W.map.controls[i].id !== null)
- {
- if(W.map.controls[i].id.indexOf('UpdateRequests') != -1) uroURControlsIdx = i;
- if(W.map.controls[i].id.indexOf('MapProblems') != -1) uroProblemControlsIdx = i;
- }
- }
- uroAddLog('Turns layer at idx '+uroTurnsLayerIdx);
- uroAddLog('MC layer at idx '+uroMCLayerIdx);
- uroAddLog('uroRootContainer = '+uroRootContainer);
- uroAddLog('Places root layer = '+uroPlacesRoot);
- }
- function uroRealWazeBits()
- {
- if(document.getElementsByClassName("sandbox").length > 0)
- {
- uroAddLog('WME practice mode detected, script is disabled...');
- return;
- }
- if(document.location.href.indexOf('user') !== -1)
- {
- uroAddLog('User profile page detected, script is disabled...');
- return;
- }
- uroAddLog('adding WazeBits...'+uroToHex(uroWazeBitsPresent,4));
- if((uroWazeBitsPresent & 0x0001) === 0)
- {
- if(typeof W != "undefined")
- {
- if(typeof W.map != "undefined")
- {
- uroAddLog(' W.map OK');
- uroWazeBitsPresent |= 0x0001;
- }
- }
- }
- if((uroWazeBitsPresent & 0x0002) === 0)
- {
- if(typeof W != "undefined")
- {
- if(typeof W.model != "undefined")
- {
- uroAddLog(' W.model OK');
- uroWazeBitsPresent |= 0x0002;
- }
- }
- }
- if((uroWazeBitsPresent & 0x0004) === 0)
- {
- if(typeof W != "undefined")
- {
- if(typeof W.loginManager != "undefined")
- {
- uroAddLog(' loginManager OK');
- uroWazeBitsPresent |= 0x0004;
- }
- }
- }
- if((uroWazeBitsPresent & 0x0008) === 0)
- {
- if(typeof W != "undefined")
- {
- if(typeof W.selectionManager != "undefined")
- {
- uroAddLog(' selectionManager OK');
- uroWazeBitsPresent |= 0x0008;
- }
- }
- }
- if((uroWazeBitsPresent & 0x0010) === 0)
- {
- if(typeof OpenLayers != "undefined")
- {
- uroAddLog(' OpenLayers OK');
- uroWazeBitsPresent |= 0x0010;
- }
- }
- if((uroWazeBitsPresent & 0x0020) === 0)
- {
- if(typeof Waze != "undefined")
- {
- uroAddLog(' Waze OK');
- uroWazeBitsPresent |= 0x0020;
- }
- }
- if((uroWazeBitsPresent & 0x0040) === 0)
- {
- if(document.getElementById('user-tabs') !== null)
- {
- uroUserTabId = 'user-tabs';
- uroAddLog(' user-tabs OK');
- uroWazeBitsPresent |= 0x0040;
- }
- }
- if((uroWazeBitsPresent & 0x0080) === 0)
- {
- if(document.getElementById('sidepanel-drives') !== null)
- {
- uroAddLog(' sidepanel-drives OK');
- uroWazeBitsPresent |= 0x0080;
- }
- }
- if((uroWazeBitsPresent & 0x0100) === 0)
- {
- if(typeof I18n != "undefined")
- {
- uroAddLog(' I18n OK');
- uroWazeBitsPresent |= 0x0100;
- }
- }
- if(uroWazeBitsPresent !== 0x01FF)
- {
- setTimeout(uroRealWazeBits,250);
- }
- else if(W.loginManager.isLoggedIn() === false)
- {
- uroAddLog('Waiting for user log-in...');
- setTimeout(uroRealWazeBits,1000);
- }
- else
- {
- uroAddLog('All WazeBits present and correct...');
- W.app.modeController.model.bind("change:mode",uroInitialise);
- if(W.app.modeController.mode.mteModeState !== undefined)
- {
- uroMTEMode = true;
- uroSetupListeners = true;
- uroFinalisingListenerSetup = false;
- uroHidePopup();
- uroAddLog('MTE mode, sleeping until normal service is resumed...');
- return;
- }
- uroMTEMode = false;
- uroSetupUI();
- uroDOMHasTurnProblems = (W.model.turnProblems != null);
- uroGetProblemTypes();
- uroPopulateProblemsTab();
- uroPopulatePlacesTab();
- uroControls.appendChild(uroCtrlURs);
- uroControls.appendChild(uroCtrlMPs);
- uroControls.appendChild(uroCtrlPlaces);
- uroControls.appendChild(uroCtrlCameras);
- uroControls.appendChild(uroOWL);
- uroControls.appendChild(uroCtrlMisc);
- uroControls.appendChild(uroCtrlHides);
- uroControls.appendChild(uroAMList);
- uroCtrlURs.onclick = uroFilterItems_URTabClick;
- uroCtrlMPs.onclick = uroFilterItems_MPTabClick;
- uroCtrlPlaces.onclick = uroFilterItems_PlacesTabClick;
- uroCtrlCameras.onclick = uroFilterItems_CamerasTabClick;
- uroCtrlMisc.onclick = uroFilterItems_MiscTabClick;
- uroWazeBits();
- uroDiv.addEventListener("mouseover", uroEnterPopup, false);
- uroDiv.addEventListener("mouseout", uroExitPopup, false);
- if(sessionStorage.UROverview_FID_IgnoreList === undefined) sessionStorage.UROverview_FID_IgnoreList = '';
- if(sessionStorage.UROverview_FID_WatchList === undefined) sessionStorage.UROverview_FID_WatchList = '';
- if(uroConfirmIntercepted === false) uroAddInterceptor();
- setInterval(uroTenthSecondTick,100);
- }
- }
- function uroAddInterceptor()
- {
- uroAddLog('Adding interceptor function...');
- // add interceptor function for confirm(), so that we can auto-select the "OK" option when solving URs
- // which have pending question...
- var _confirm = window.confirm;
- window.confirm = function(msg)
- {
- var cm_delete_confirm = I18n.lookup("closures.delete_confirm").split('"')[0].trimRight(1);
- if((I18n.lookup("update_requests.panel.confirm") == msg) && (uroGetCBChecked('_cbDisablePendingQuestions') === true))
- {
- uroAddLog('Intercepted pending comments confirmation...');
- return true;
- }
- else if(msg.indexOf(cm_delete_confirm) != -1)
- {
- uroAddLog('intercepted closure delete confirmation...');
- if(uroConfirmClosureDelete)
- {
- return _confirm(msg);
- }
- else
- {
- return true;
- }
- }
- else if(typeof(msg) == 'undefined')
- {
- uroAddLog('Intercepted blank confirmation...');
- return true;
- }
- else
- {
- return _confirm(msg);
- }
- };
- uroConfirmIntercepted = true;
- }
- function uroEnterPopup()
- {
- uroMouseInPopup = true;
- }
- function uroExitPopup()
- {
- uroMouseInPopup = false;
- }
- function uroToggleDebug()
- {
- uroShowDebugOutput = !uroShowDebugOutput;
- var dbgMode = "none";
- if(uroShowDebugOutput)
- {
- dbgMode = "inline";
- }
- document.getElementById('_uroDebugMode').style.display = dbgMode;
- }
- function uroInitialise()
- {
- uroInitialised = false;
- if(document.URL.indexOf('beta') != -1) uroBetaEditor = true;
- var urlBits = document.URL.split("&mapUpdateRequest=");
- if(urlBits.length == 2)
- {
- uroURIDInURL = parseInt(urlBits[1].split('&')[0]);
- uroAddLog('found UR ID '+uroURIDInURL+' in URL');
- }
- uroRealWazeBits();
- }
- function uroSetupUI()
- {
- // create a new div to display the UR details floaty-box
- uroDiv = document.createElement('div');
- uroDiv.id = "uroDiv";
- uroDiv.style.position = 'absolute';
- uroDiv.style.visibility = 'hidden';
- uroDiv.style.top = '0';
- uroDiv.style.left = '0';
- uroDiv.style.zIndex = 100;
- uroDiv.style.backgroundColor = 'aliceblue';
- uroDiv.style.borderWidth = '3px';
- uroDiv.style.borderStyle = 'solid';
- uroDiv.style.borderRadius = '10px';
- uroDiv.style.boxShadow = '5px 5px 10px Silver';
- uroDiv.style.padding = '4px';
- document.body.appendChild(uroDiv);
- // create a new div to display script alerts
- uroAlerts = document.createElement('div');
- uroAlerts.id = "uroAlerts";
- uroAlerts.style.position = 'fixed';
- uroAlerts.style.visibility = 'hidden';
- uroAlerts.style.top = '50%';
- uroAlerts.style.left = '50%';
- uroAlerts.style.zIndex = 100;
- uroAlerts.style.backgroundColor = 'aliceblue';
- uroAlerts.style.borderWidth = '3px';
- uroAlerts.style.borderStyle = 'solid';
- uroAlerts.style.borderRadius = '10px';
- uroAlerts.style.boxShadow = '5px 5px 10px Silver';
- uroAlerts.style.padding = '4px';
- uroAlerts.style.webkitTransform = "translate(-50%, -50%)";
- uroAlerts.style.transform = "translate(-50%, -50%)";
- var alertsHTML = '<div id="header" style="padding: 4px; background-color:LightGreen; font-weight: bold;">Alert title goes here...</div>';
- alertsHTML += '<div id="content" style="padding: 4px; background-color:White">Alert content goes here...</div>';
- alertsHTML += '<div id="controls" style="padding: 4px;">';
- alertsHTML += '<span id="uroAlertTickBtn" style="cursor:pointer;font-size:14px;border:thin outset black;padding:2px;">';
- alertsHTML += '<i class="fa fa-check"> </i>';
- alertsHTML += '<span id="uroAlertTickBtnCaption" style="font-weight: bold;"></span>';
- alertsHTML += '</span>';
- alertsHTML += ' ';
- alertsHTML += '<span id="uroAlertCrossBtn" style="cursor:pointer;font-size:14px;border:thin outset black;padding:2px;">';
- alertsHTML += '<i class="fa fa-times"> </i>';
- alertsHTML += '<span id="uroAlertCrossBtnCaption" style="font-weight: bold;"></span>';
- alertsHTML += '</span>';
- alertsHTML += '</div>';
- uroAlerts.innerHTML = alertsHTML;
- document.body.appendChild(uroAlerts);
- uroControls = document.createElement('section');
- uroControls.style.fontSize = '12px';
- uroControls.id = 'uroControls';
- var updateURL;
- if(navigator.userAgent.indexOf('Chrome') == -1)
- {
- updateURL = 'https://greasyfork.org/scripts/1952-uroverview-plus-uro';
- }
- else
- {
- updateURL = 'https://chrome.google.com/webstore/detail/uroverview/amdamgkgchnbaopmphhjapmjcdghdphi';
- }
- var tabbyHTML = '<b><a href="'+updateURL+'" target="_blank">UROverview Plus</a></b> <label id="_uroVersion">'+uroVersion+'</label>';
- tabbyHTML += '<label id="_uroDebugMode">(dbg)</label>';
- tabbyHTML += ' <input type="checkbox" id="_cbMasterEnable" checked>Enabled</input>';
- tabbyHTML += '<p><table border=0 width="100%"><tr>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectUserRequests"><a href="#" id="_linkSelectUserRequests" style="text-decoration:none;font-size:12px">URs</a></td>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectMapProblems"><a href="#" id="_linkSelectMapProblems" style="text-decoration:none;font-size:12px">MPs</a></td>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectPlaces"><a href="#" id="_linkSelectPlaces" style="text-decoration:none;font-size:12px">Places</a></td>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectCameras"><a href="#" id="_linkSelectCameras" style="text-decoration:none;font-size:12px">Cams</a></td>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectCWL"><a href="#" id="_linkSelectOWL" style="text-decoration:none;font-size:12px">OWL</a></td>';
- tabbyHTML += '<td valign="center" align="center" id="_tabSelectMisc"><a href="#" id="_linkSelectMisc" style="text-decoration:none;font-size:12px">Misc</a></td>';
- tabbyHTML += '</tr></table>';
- uroControls.innerHTML = tabbyHTML;
- uroCtrlURs = document.createElement('p');
- uroCtrlMPs = document.createElement('p');
- uroCtrlCameras = document.createElement('p');
- uroOWL = document.createElement('p');
- uroCtrlMisc = document.createElement('p');
- uroAMList = document.createElement('div');
- uroCtrlHides = document.createElement('div');
- uroCtrlPlaces = document.createElement('p');
- // UR controls tab
- uroCtrlURs.id = "uroCtrlURs";
- uroCtrlURs.innerHTML = '<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURFilterOutsideArea">Hide URs outside my editable area</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbNoFilterForURInURL">Don\'t filter UR in URL</input><br><br>';
- uroCtrlURs.innerHTML += '<b>Filter by type:</b><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWazeAuto">Waze Automatic</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectTurn">Incorrect turn</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectAddress">Incorrect address</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectRoute">Incorrect route</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoundabout">Missing roundabout</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterGeneralError">General error</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterTurnNotAllowed">Turn not allowed</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterIncorrectJunction">Incorrect junction</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingBridgeOverpass">Missing bridge overpass</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterWrongDrivingDirection">Wrong driving direction</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingExit">Missing exit</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingRoad">Missing road</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterBlockedRoad">Blocked road</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterMissingLandmark">Missing Landmark</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSpeedLimits">Missing or Invalid Speed limit</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUndefined">Undefined</input><br>';
- uroCtrlURs.innerHTML += ' <i>Specially tagged types</i><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterRoadworks">[ROADWORKS]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterConstruction">[CONSTRUCTION]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterClosure">[CLOSURE]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterEvent">[EVENT]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterNote">[NOTE]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterBOG">[BOG]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterDifficult">[DIFFICULT]</input><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbFilterWSLM">[WSLM]</input><br><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbInvertURFilter">Invert operation of type filters?</input><br>';
- uroCtrlURs.innerHTML += '<hr>';
- uroCtrlURs.innerHTML += '<br><b>Hide by state:</b><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterOpenUR">Open</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterClosedUR">Closed</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterSolved">Solved</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbFilterUnidentified">Not identified</input><br><br>';
- uroCtrlURs.innerHTML += '<br><b>Filter by age of submission:</b><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinAgeFilter">Hide URs less than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinDays"> days old<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxAgeFilter">Hide URs more than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxDays"> days old<br>';
- uroCtrlURs.innerHTML += '<br><b>Filter by description/comments/following:</b><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyFollowed" pairedWith="_cbHideMyUnfollowed">Ones I am or </input>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyUnfollowed" pairedWith="_cbHideMyFollowed">am not following</input><br><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBePresent" pairedWith="_cbURDescriptionMustBeAbsent">Hide</input> or ';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURDescriptionMustBeAbsent" pairedWith="_cbURDescriptionMustBePresent">show</input> URs with no description<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBePresent">Hide URs not including </input>';
- uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordPresent"><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableKeywordMustBeAbsent">Hide URs including </input>';
- uroCtrlURs.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textKeywordAbsent"><br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbCaseInsensitive"><i>Case-insensitive matches?</i></input><br><br>';
- uroCtrlURs.innerHTML += 'With comments from me?<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideMyComments" pairedWith="_cbHideAnyComments">Yes </input>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideAnyComments" pairedWith="_cbHideMyComments">No</input><br>';
- uroCtrlURs.innerHTML += 'If last comment made by me?<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfLastCommenter" pairedWith="_cbHideIfNotLastCommenter">Yes </input>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfNotLastCommenter" pairedWith="_cbHideIfLastCommenter">No </input><br>';
- uroCtrlURs.innerHTML += 'If last comment made by UR reporter?<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterLastCommenter" pairedWith="_cbHideIfReporterNotLastCommenter">Yes </input>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbHideIfReporterNotLastCommenter" pairedWith="_cbHideIfReporterLastCommenter">No</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMinCommentsFilter">With less than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMinComments"> comments<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableMaxCommentsFilter">With more than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="0" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterMaxComments"> comments<br><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter2">Last comment less than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays2"> days ago<br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbEnableCommentAgeFilter">Last comment more than </input>';
- uroCtrlURs.innerHTML += '<input type="number" min="1" size="3" style="width:50px;line-height:14px;height:22px;margin-bottom:4px;" id="_inputFilterCommentDays"> days ago<br>';
- uroCtrlURs.innerHTML += ' <input type="checkbox" id="_cbIgnoreOtherEditorComments"><i>Ignore other editor comments?</i></input><br><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURUserIDFilter">Without comments from user</input>';
- uroCtrlURs.innerHTML += '<select id="_selectURUserID" style="width:80%; height:22px;"></select><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbURResolverIDFilter">Not resolved by user</input>';
- uroCtrlURs.innerHTML += '<select id="_selectURResolverID" style="width:80%; height:22px;"></select>';
- uroCtrlURs.innerHTML += '<br><br><input type="checkbox" id="_cbInvertURStateFilter">Invert operation of state/age filters?</input><br>';
- uroCtrlURs.innerHTML += '<input type="checkbox" id="_cbNoFilterForTaggedURs">Don\'t apply state/age filters to tagged URs</input><br>';
- // Map problems controls tab
- uroCtrlMPs.id = "uroCtrlMPs";
- uroCtrlMPs.innerHTML = 'MP filter list being populated, please wait...';
- // Places filtering tab
- uroCtrlPlaces.id = "uroCtrlPlaces";
- uroCtrlPlaces.innerHTML = 'Places filter list being populated, please wait...';
- // Camera controls tab
- uroCtrlCameras.id = "uroCtrlCameras";
- uroCtrlCameras.innerHTML = '<br><b>Show Cameras created by:</b><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowWorldCams" checked>world_* users</input><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowUSACams" checked>usa_* users</input><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonWorldCams" checked>other users</input><br>';
- uroCtrlCameras.innerHTML += '<br><b>Show Cameras touched by a specific editor:</b><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowOnlyCamsCreatedBy">Created by</input> / ';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowOnlyCamsEditedBy">edited by</input><br>';
- uroCtrlCameras.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textCameraEditor"><br>';
- uroCtrlCameras.innerHTML += '<select id="_selectCameraUserID" style="width:80%; height:22px;"></select><br>';
- uroCtrlCameras.innerHTML += '<br><input type="checkbox" id="_cbShowOnlyMyCams">Show ONLY cameras created/edited by me</input><br>';
- uroCtrlCameras.innerHTML += '<br><b>Show Cameras by approval status:</b><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowApprovedCams" checked>approved</input><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowNonApprovedCams" checked>non-approved</input><br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowOlderCreatedNonApproved"> if created more than </input>';
- uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinCreatedDays"> days ago<br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowOlderUpdatedNonApproved"> if updated more than </input>';
- uroCtrlCameras.innerHTML += '<input type="number" min="1" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCameraMinUpdatedDays"> days ago<br>';
- uroCtrlCameras.innerHTML += '<br><b>Show Cameras by type:</b><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowSpeedCams" checked>Speed</input><br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowIfSpeedSet" checked> with speed data</input><br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbShowIfNoSpeedSet" checked> with no speed data</input><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowRedLightCams" checked>Red Light</input><br>';
- uroCtrlCameras.innerHTML += '<input type="checkbox" id="_cbShowDummyCams" checked>Dummy</input><br>';
- uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by creator:</b><br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByMe">me</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank0">L1</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank1">L2</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank2">L3</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank3">L4</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank4">L5</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideCreatedByRank5">L6</input>';
- uroCtrlCameras.innerHTML += '<br><b>Hide Cameras by updater:</b><br>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByMe">me</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank0">L1</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank1">L2</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank2">L3</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank3">L4</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank4">L5</input>';
- uroCtrlCameras.innerHTML += ' <input type="checkbox" id="_cbHideUpdatedByRank5">L6</input>';
- uroCtrlCameras.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideCWLCams">Hide cameras on watchlist</input></b><br>';
- // Object watchlist tab
- uroOWL.id = "uroOWL";
- uroCWLGroups = [];
- uroOWLUpdateHTML();
- // Misc controls tab
- uroCtrlMisc.id = "uroCtrlMisc";
- uroCtrlMisc.innerHTML = '<br><b>Use default conversation markers:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeConvoMarkers" checked />in public WME<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbNativeBetaConvoMarkers" checked />in beta WME<br>';
- uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbCommentCount" />Show comment count on UR markers</b><br>';
- uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbURBackfill" />Backfill UR data</b><br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Marker Unstacking:</b><br>';
- uroCtrlMisc.innerHTML += 'Distance threshold: <input type="number" min="1" max="30" value="15" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackSensitivity" /><br>';
- uroCtrlMisc.innerHTML += 'Disable below zoom: <input type="number" min="0" max="10" value="3" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputUnstackZoomLevel" /><br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for URs tagged as:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomRoadworksMarkers" />[ROADWORKS]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomConstructionMarkers" />[CONSTRUCTION]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomClosuresMarkers" />[CLOSURE]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomEventsMarkers" />[EVENT]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNotesMarkers" />[NOTE]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomBOGMarkers" />[BOG]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomDifficultMarkers" />[DIFFICULT]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomWSLMMarkers" />[WSLM]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomNativeSLMarkers" />Native speed limit reports<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomKeywordMarkers" />';
- uroCtrlMisc.innerHTML += '<input type="text" style="font-size:14px; line-height:16px; height:22px; margin-bottom:4px;" id="_textCustomKeyword" /><br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Use custom marker for MPs tagged as:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomElginMarkers" />[Elgin]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTrafficMasterMarkers" />[TM]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTrafficCastMarkers" />[TrafficCast]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomCaltransMarkers" />[Caltrans]<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbCustomTFLMarkers" />[TfL Open Data]<br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Popup mouse behaviour:</b><br>';
- uroCtrlMisc.innerHTML += 'Mouse idle <input type="number" min="1" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPopupDwellTimeout" /> *100ms<br>';
- uroCtrlMisc.innerHTML += 'Mouse over <input type="number" min="1" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputPopupEntryTimeout" /> *100ms<br>';
- uroCtrlMisc.innerHTML += 'Distance <input type="number" min="0" max="10" value="2" size="2" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputMaxJitter" /> pixels<br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Disable popup for:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitURPopup" />URs<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMPPopup" />MPs<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitCamPopup" />Cameras<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitSegPopup" />Segments<br>';
- uroCtrlMisc.innerHTML += ' <input type="checkbox" id="_cbInhibitSegGenericPopup" />Speed limit info<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitTurnsPopup" />Restricted Turns<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitLandmarkPopup" />Places<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitPUPopup" />Place Updates<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitMapCommentPopup" />Map Comments<br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Date/Time formatting for popups:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtDDMMYY" pairedWith="_cbDateFmtMMDDYY,_cbDateFmtYYMMDD" checked />day/month/year<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtMMDDYY" pairedWith="_cbDateFmtDDMMYY,_cbDateFmtYYMMDD" />month/day/year<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbDateFmtYYMMDD" pairedWith="_cbDateFmtMMDDYY,_cbDateFmtDDMMYY" />year/month/day<br><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbTimeFmt24H" pairedWith="_cbTimeFmt12H" checked />24 hour<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbTimeFmt12H" pairedWith="_cbTimeFmt24H" />12 hour<br><br>';
- uroCtrlMisc.innerHTML += '<i>Unticked uses browser default setting</i>';
- uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbWhiteBackground" />Use custom background colour</b><br>';
- uroCtrlMisc.innerHTML += 'R:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundRed" />';
- uroCtrlMisc.innerHTML += 'G:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundGreen" />';
- uroCtrlMisc.innerHTML += 'B:<input type="number" min="0" max="255" value="255" size="3" style="width:50px;;line-height:14px;height:22px;margin-bottom:4px;" id="_inputCustomBackgroundBlue" /><br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Replace "Next ..." button with "Done" for:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNURButton" />URs<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNMPButton" />MPs<br>';
- uroCtrlMisc.innerHTML += '<input type="checkbox" id="_cbInhibitNPURButton" />PURs<br>';
- uroCtrlMisc.innerHTML += '<br><br><b><input type="checkbox" id="_cbHideAMLayer" />Hide Area Manager polygons</b><br>';
- uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisablePlacesFiltering" />Disable Places filtering</b><br>';
- ////uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisablePendingQuestions">Disable UR Pending Questions confirmation</input></b><br>';
- uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbDisableTabStyling" />Use default tab styling</b><br>';
- uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbHideEditorInfo" />Hide sidebar editor info</b><br>';
- uroCtrlMisc.innerHTML += '<b><input type="checkbox" id="_cbEnableDTE" />Drive Tab Enhancement (DTE)</b><br>';
- uroCtrlMisc.innerHTML += '<br><br><b>Settings backup/restore/reset:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="button" id="_btnSettingsToText" value="Backup" /> ';
- uroCtrlMisc.innerHTML += '<input type="button" id="_btnTextToSettings" value="Restore" /> | ';
- uroCtrlMisc.innerHTML += '<input type="button" id="_btnResetSettings" value="Reset" /><br><br>';
- uroCtrlMisc.innerHTML += '<textarea id="_txtSettings" value="" /><br>';
- uroCtrlMisc.innerHTML += '<input type="button" id="_btnClearSettingsText" value="Clear" /><br>';
- /*
- uroCtrlMisc.innerHTML += '<br><br><b>Debug:</b><br>';
- uroCtrlMisc.innerHTML += '<input type="button" id="_btnDebugToScreen" value="Show debug data" />';
- */
- // footer for tabs container
- uroCtrlHides.id = 'uroCtrlHides';
- uroCtrlHides.innerHTML = '<input type="button" id="_btnUndoLastHide" value="Undo last hide" /> ';
- uroCtrlHides.innerHTML += '<input type="button" id="_btnClearSessionHides" value="Undo all hides" /><p>';
- // footer for AM list
- uroAMList.id = 'uroAMList';
- window.addEventListener("beforeunload", uroSaveSettings, false);
- //uroRealWazeBits();
- }
- function dteAddHeader()
- {
- if(uroMTEMode) return;
- if(!uroInitialised) return;
- var rlcObj = document.getElementsByClassName("result-list-container");
- if(typeof rlcObj == "undefined") return;
- if(typeof rlcObj[0].children[0] == "undefined") return;
- if(typeof rlcObj[0].children[0].innerHTML == "undefined") return;
- var thtml = rlcObj[0].children[0].innerHTML;
- if(thtml.indexOf('Full drive history') == -1)
- {
- thtml += '<br><br><i><small>Full drive history goes back to '+dteOldestFullDrive.toDateString()+'</small></i>';
- rlcObj[0].children[0].innerHTML = thtml;
- }
- }
- function dteGetData()
- {
- var loc = 'https://'+window.location.hostname+Waze.Config.api_base+'/Archive/MyList?minDistance=1000';
- loc += '&offset='+dteOffset+'&count=5';
- var dteReq = new XMLHttpRequest();
- dteReq.onreadystatechange = function()
- {
- var foundMissingDrive = false;
- if(dteReq.readyState == 4)
- {
- uroAddLog('drive data request, response '+dteReq.status+' received');
- if(dteReq.status == 200)
- {
- if(dteReq.responseText !== "")
- {
- var drives = JSON.parse(dteReq.responseText);
- var loadedDrives = drives.archives.objects.length;
- uroAddLog('received '+loadedDrives+' drives');
- if(loadedDrives != 5) foundMissingDrive = true;
- for(var loop=0; loop < loadedDrives; loop++)
- {
- if(drives.archives.objects[loop].hasFullSession === false)
- {
- foundMissingDrive = true;
- }
- else
- {
- dteOffset++;
- dteOldestFullDrive = new Date(drives.archives.objects[loop].startTime);
- }
- }
- }
- else
- {
- foundMissingDrive = true;
- }
- }
- if(foundMissingDrive === false)
- {
- dteGetData();
- }
- else
- {
- uroAddLog(dteOffset+' full drives in history');
- uroAddLog('oldest drives are on '+dteOldestFullDrive.toDateString());
- if(dteOffset < 5)
- {
- dteOffset = 5;
- uroAddLog('insufficient full drives, using standard drives tab');
- }
- else if(dteOffset > 50)
- {
- var nPages = Math.ceil(dteOffset / 50);
- uroAddLog('too many full drives for a single tab page, splitting over '+nPages+' pages...');
- dteOffset = Math.ceil(dteOffset/nPages);
- }
- if((dteOldestFullDrive - dteEpoch) > 0)
- {
- var totalDrives = 0;
- if(W.model.archives.additionalInfo !== null)
- {
- totalDrives = W.model.archives.additionalInfo.totalSessions;
- }
- if(totalDrives !== null)
- {
- uroAddLog('updating drives tab...');
- W.map.controls[dteControlsIdx].sidePanelView.ResultsPerPage = dteOffset;
- uroAddLog(totalDrives+' drives in history');
- W.map.controls[dteControlsIdx].sidePanelView.setSessions(totalDrives);
- W.map.controls[dteControlsIdx].loadSessions(0);
- }
- setInterval(dteAddHeader,250);
- setInterval(dteCheckDriveListChanges,250);
- }
- }
- }
- };
- dteReq.open('GET',loc,true);
- dteReq.send();
- }
- function dteSetNewTabLength()
- {
- uroAddLog('altering ResultsPerPage parameter...');
- var t = document.getElementById('sidepanel-drives');
- t.style.overflow = 'auto';
- t.style.height = (window.innerHeight * 0.6) + 'px';
- dteOffset = 0;
- dteGetData();
- }
- function dteListClick()
- {
- dteClearListHighlight();
- this.style.backgroundColor = "lightgreen";
- dteArmClearHighlightsOnPanelClose = true;
- }
- function dteClearListHighlight()
- {
- var drivesShown = document.getElementById('sidepanel-drives').getElementsByClassName('result session').length;
- if(drivesShown > 0)
- {
- for(var loop = 0;loop < drivesShown; loop++)
- {
- var listEntry = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[loop];
- listEntry.style.backgroundColor = "";
- }
- }
- }
- function dteCheckDriveListChanges()
- {
- if(uroMTEMode) return;
- if(!uroInitialised) return;
- var drivesShown = document.getElementById('sidepanel-drives').getElementsByClassName('result session').length;
- if(drivesShown > 0)
- {
- var topID = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[0].getAttribute('data-id');
- if(topID != dteTopID)
- {
- dteTopID = topID;
- for(var loop = 0;loop < drivesShown; loop++)
- {
- var listEntry = document.getElementById('sidepanel-drives').getElementsByClassName('result session')[loop];
- var driveID = listEntry.getAttribute('data-id');
- var driveObj = W.model.archives.objects[driveID];
- var driveSecs = Math.floor((driveObj.endTime - driveObj.startTime) / 1000);
- var driveHours = Math.floor(driveSecs / 3600);
- driveSecs -= (driveHours * 3600);
- var driveMins = Math.floor(driveSecs / 60);
- driveSecs -= (driveMins * 60);
- var trueTime = (driveHours+':'+("0"+driveMins).slice(-2)+'.'+("0"+driveSecs).slice(-2));
- listEntry.getElementsByTagName('span')[1].innerHTML = trueTime;
- listEntry.addEventListener("click", dteListClick, false);
- }
- }
- }
- }
- uroInitialise();