// ==UserScript==
// @name WME FixingMap Plugin
// @description Find errors in the map
// @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
// @namespace https://www.waze.com/ar/editor
// @version 2.0.1
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAH+SURBVGhD1Ze9TQQxEIX3rgKEhAgQIqICEqqADkhpgCIIiEkogBSoAiE6IEIcAQlQAQdv8Zx29/zzbM/6vJ+0ugku+N54vGvPLpudZVOA88WNqdLY2js1VZ+5+a0alzwoEiCn+z55MOoIjTU2XdQD5EoLjDxQC6AlDlh5kB1AUxzEyH+/36cF0JYWYuRBdIBaxAHkARVgLHGQIw+CARj5n+MLU/mZP16Z6p9ceeAMwHadle+y/fZiKp6huGANoNl1FzEhXPJg7ShRQh587h+ayo9PHvQClJIXQiFC8mAVoLS8YAsBcUYetAHYDctwcrDbe2JhxYXZ1+KO+pCFuh+SfXj9MJUdbOpYeVDkPsCQIg9UAjCjkjJOPp6ub9unmhWIAeLC5AJ05cGkAgzlgUqA0BsGMP/xYZMHk1gBlzxQ+w4Iw7cN2/nhURv4xAUqgJzb2QNYLKnyIDhCKZeOHCDOygPvCtjktVdBuh8j3cUZwNd5rRCQTxUXrAGYsckN8Xx2ZKo81vYAO/Mp91pBSx70ViBmw3ZPj+wrVlNcWAVIlWfInXMfbYCx5McUF6ICsPIlxIXZ8g9Te6lRHlCHuVrlAbUCoQCbEBeCK1CzPPAGqF0eUHvARg3ywBmA3bibxhpgCqMjRI9QTfJgLcBURkfoBZiaPLBeaFzUNj5N0zS/umsXLLJwKl8AAAAASUVORK5CYII=
// @match https://www.waze.com/ar/editor/*
// @match https://www.waze.com/ar/editor
// @match https://www.waze.com/editor/*
// @match https://www.waze.com/editor
// @grant none
// @author Sultan Alrefaei
// @copyright 2018 - 2019 Sultan Alrefaei <@sultan_alrefaei>
// ==/UserScript==
//Styles
var btn_rn = "width: 50px;"
+"height: 30px;"
+"border: none;"
+"background-color: #9E9E9E;"
+"color: white;";
var input = "padding: 5px;"
+"padding-left: 10px;"
+"border: 1px solid #ddd;"
+"border-radius: 3px;"
+"margin-top: 15px;"
+"margin-bottom: 10px;"
+"font-weight: bold;"
+"font-size: 15px;"
+"display: block;";
var stateNode = false;
var stateRoad = false;
var stateLevel = false;
//Setup objects
const nodes = W.model.nodes.objects;
const segments = W.model.segments.objects;
const cameras = W.model.cameras.objects;
const users = W.model.users.objects;
window.onload = e =>{
createTapUI();
window.W.map.events.register("move", null, e =>{
setTimeout(manager, 500);
});
}
const manager = e =>{
if (W.map.zoom >= 3){
if (stateNode){
checkNIC();
}
}
if (W.map.zoom >= 5){
if (stateRoad){
checkIRS();
}
if (stateLevel){
checkLevel();
}
}else{
defaultROR();
}
}
const checkIRS = e =>{
var segs = [];
for (seg in segments){
if (getElement("#" + segments[seg].attributes.geometry.id) != null){
segs.push(segments[seg]);
}
}
setTimeout(checkIROR(segs), 10);
}
const defaultROR = e =>{
for (seg in segments){
if (getElement("#" + segments[seg].attributes.geometry.id) != null){
getElement("#" + segments[seg].attributes.geometry.id).setAttribute("stroke", "");
getElement("#" + segments[seg].attributes.geometry.id).setAttribute("stroke-opacity", 0);
}
}
}
const checkIROR = segs =>{
for (var s1 = 0; s1 < segs.length; s1++){
for (var s2 = 0; s2 < segs.length; s2++){
if (segs[s1].attributes.id != segs[s2].attributes.id && segs[s1].attributes.fromNodeID == segs[s2].attributes.fromNodeID && segs[s1].attributes.toNodeID == segs[s2].attributes.toNodeID){
if (getElement("#" + segs[s1].attributes.geometry.id) != null){
getElement("#" + segs[s1].attributes.geometry.id).setAttribute("stroke", "red");
getElement("#" + segs[s1].attributes.geometry.id).setAttribute("stroke-opacity", 1);
}
if (getElement("#" + segs[s2].attributes.geometry.id) != null){
getElement("#" + segs[s2].attributes.geometry.id).setAttribute("stroke", "red");
getElement("#" + segs[s2].attributes.geometry.id).setAttribute("stroke-opacity", 1);
}
}
}
}
}
const checkNIC = e =>{
for (node in nodes){
if (nodes[node].attributes.segIDs.length == 1){
if (getElement("#" + nodes[node].attributes.geometry.id) != null){
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("fill", "#525252");
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("fill-opacity", 1);
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("stroke", "red");
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("stroke-opacity", 1);
}
}
}
}
const defaultNode = e =>{
for (node in nodes){
if (getElement("#" + nodes[node].attributes.geometry.id) != null){
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("fill", "");
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("fill-opacity", 0);
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("stroke", "");
getElement("#" + nodes[node].attributes.geometry.id).setAttribute("stroke-opacity", 0);
}
}
}
const checkLevel = e =>{
var level = getElement("#input-level") || 1;
for ( lvl in segments){
if (getElement("#" + segments[lvl].attributes.geometry.id) != null){
var useridCreated = segments[lvl].attributes.createdBy;
var useridUpdated = segments[lvl].attributes.updatedBy;
userUpdated(useridUpdated, level);
}
}
}
const userCreated = (useridCreated, level) =>{
var usersArray = [];
if (users[useridCreated].normalizedLevel == parseInt(level.value) && checkDateSig(segments[lvl].attributes.id)){
if (usersArray.length == 0){
usersArray.push(users[useridCreated].userName);
}else{
for (var i = 0; i < users.length; i++){
if (usersArray[i] == users[useridCreated].userName){
continue;
}else{
usersArray.push(users[useridCreated].userName);
}
}
}
getElement("#" + segments[lvl].attributes.geometry.id).setAttribute("stroke", "green");
getElement("#" + segments[lvl].attributes.geometry.id).setAttribute("stroke-opacity", 1);
}
getElement("#users-content").innerText = usersArray;
}
const userUpdated = (useridUpdated, level) =>{
var usersArray = [];
if (users[useridUpdated].normalizedLevel == parseInt(level.value) && checkDateSig(segments[lvl].attributes.id)){
if (usersArray.length == 0){
usersArray.push(users[useridUpdated].userName);
}else{
for (var i = 0; i < users.length; i++){
if (usersArray[i] == users[useridUpdated].userName){
continue;
}else{
usersArray.push(users[useridUpdated].userName);
}
}
}
getElement("#" + segments[lvl].attributes.geometry.id).setAttribute("stroke", "green");
getElement("#" + segments[lvl].attributes.geometry.id).setAttribute("stroke-opacity", 1);
}
getElement("#users-content").innerText = usersArray;
}
const camerasOBJ = e =>{
for (cam in cameras){
if (cameras[cam].attributes.geometry.id != null){
if (cameras[cam].attributes.speed == 100)
getElement("#" + cameras[cam].attributes.geometry.id).setAttribute("xlink:href", "https://www.dropbox.com/s/oiydd8av9111xwq/download_cr.png?dl=1");
}
}
}
const createTapUI = e =>{
const taps = getElement(".nav nav-tabs")[0];
const tap = document.createElement("li");
tap.innerHTML = '<a data-toggle="tab" href="#sidepanel-rn">WME {FM}</a>';
taps.insertBefore(tap, taps.children[3].nextSibling);
createWindowUI();
}
const createWindowUI = e =>{
const wins = getElement(".tab-content")[0];
const win = document.createElement("div");
win.setAttribute("class", "tab-pane");
win.setAttribute("id", "sidepanel-rn");
win.setAttribute("style", "text-align: left;");
//Title
const title = document.createElement("h2");
title.setAttribute("style", "margin-bottom: 15px; border-bottom: 1px solid;");
title.innerHTML = "WME FixingMap Plugin <sup style='font-size: 15px; padding: 1.5px; background-color: #FFEB3B;'>{FM}</sup>";
win.appendChild(title);
wins.insertBefore(win, wins.children[0]);
NodeController();
RoadController();
LevelController();
const footer = document.createElement("div");
footer.setAttribute("style", "margin-top: 20px; border-top: 1px solid; padding: 10px; text-align: center; color: #888888;");
footer.innerHTML = "©2018-2019 <a href='https://www.waze.com/ar/user/editor/sultan_alrefaei'>Sultan Alrefaei</a><br>Saudi Arabia";
win.appendChild(footer);
}
const NodeController = element =>{
//Title
const title = document.createElement("h3");
title.setAttribute("style", "margin-top: 10px; margin-bottom: 5px;");
title.innerHTML = "Check If <span style='padding: 1.5px; background-color: #FFEB3B;'>C.N</span>";
getElement("#sidepanel-rn").appendChild(title);
//Button Off
const btnOff = document.createElement("button");
btnOff.setAttribute("style", btn_rn);
btnOff.setAttribute("id", "btnNodeOff");
btnOff.style.backgroundColor = "#e91e63";
btnOff.addEventListener("click", e =>{
e.target.style.backgroundColor = "#e91e63";
getElement("#btnNodeOn").style.backgroundColor = "#9E9E9E";
stateNode = false;
defaultNode();
});
btnOff.innerHTML = "Off";
getElement("#sidepanel-rn").appendChild(btnOff);
//Button On
const btnOn = document.createElement("button");
btnOn.setAttribute("style", btn_rn);
btnOn.setAttribute("id", "btnNodeOn");
btnOn.addEventListener("click", e =>{
e.target.style.backgroundColor = "#4caf50";
getElement("#btnNodeOff").style.backgroundColor = "#9E9E9E";
stateNode = true;
checkNIC();
});
btnOn.innerHTML = "On";
getElement("#sidepanel-rn").appendChild(btnOn);
}
const RoadController = element =>{
//Title
const title = document.createElement("h3");
title.setAttribute("style", "margin-top: 10px; margin-bottom: 5px;");
title.innerHTML = "Check If <span style='padding: 1.5px; background-color: #FFEB3B;'>R.O.R</span>";
getElement("#sidepanel-rn").appendChild(title);
//Button Off
const btnOff = document.createElement("button");
btnOff.setAttribute("style", btn_rn);
btnOff.setAttribute("id", "btnRoadOff");
btnOff.style.backgroundColor = "#e91e63";
btnOff.addEventListener("click", e =>{
e.target.style.backgroundColor = "#e91e63";
getElement("#btnRoadOn").style.backgroundColor = "#9E9E9E";
stateRoad = false;
defaultROR();
});
btnOff.innerHTML = "Off";
getElement("#sidepanel-rn").appendChild(btnOff);
//Button On
const btnOn = document.createElement("button");
btnOn.setAttribute("style", btn_rn);
btnOn.setAttribute("id", "btnRoadOn");
btnOn.addEventListener("click", e =>{
e.target.style.backgroundColor = "#4caf50";
getElement("#btnRoadOff").style.backgroundColor = "#9E9E9E";
stateRoad = true;
checkIRS();
});
btnOn.innerHTML = "On";
getElement("#sidepanel-rn").appendChild(btnOn);
}
const LevelController = element =>{
//Title
const title = document.createElement("h3");
title.setAttribute("style", "margin-top: 10px; margin-bottom: 5px;");
title.innerHTML = "Check User <span style='padding: 1.5px; background-color: #FFEB3B;'>I.T</span>";
getElement("#sidepanel-rn").appendChild(title);
//Input for level
const inputLevel = document.createElement("input");
inputLevel.setAttribute("type", "number");
inputLevel.setAttribute("id", "input-level");
inputLevel.setAttribute("placeholder", "Enter the level");
inputLevel.setAttribute("value", "1");
inputLevel.setAttribute("style", input);
getElement("#sidepanel-rn").appendChild(inputLevel);
//Button Off
const btnOff = document.createElement("button");
btnOff.setAttribute("style", btn_rn);
btnOff.setAttribute("id", "btnLevelOff");
btnOff.style.backgroundColor = "#e91e63";
btnOff.addEventListener("click", e =>{
e.target.style.backgroundColor = "#e91e63";
getElement("#btnLevelOn").style.backgroundColor = "#9E9E9E";
stateLevel = false;
defaultROR();
});
btnOff.innerHTML = "Off";
getElement("#sidepanel-rn").appendChild(btnOff);
//Button On
const btnOn = document.createElement("button");
btnOn.setAttribute("style", btn_rn);
btnOn.setAttribute("id", "btnLevelOn");
btnOn.addEventListener("click", e =>{
e.target.style.backgroundColor = "#4caf50";
getElement("#btnLevelOff").style.backgroundColor = "#9E9E9E";
stateLevel = true;
checkLevel();
});
btnOn.innerHTML = "On";
getElement("#sidepanel-rn").appendChild(btnOn);
const content = document.createElement("h4");
content.setAttribute("id", "users-content");
content.setAttribute("style", "margin-top: 10px; margin-bottom: 10px; color: #03A9F4; border-left: 5px solid #757575; padding-left: 5px;");
getElement("#sidepanel-rn").appendChild(content);
}
const checkDateSig = id =>{
var timestampCreated = W.model.segments.objects[id].attributes.createdOn;
var timestampUpdated = W.model.segments.objects[id].attributes.updatedOn;
var createdOn = new Date(timestampCreated);
var fullDateCreated = createdOn.getMonth() + "/" + createdOn.getFullYear();
var updatedOn = new Date(timestampUpdated);
var fullDateUpdated = updatedOn.getMonth() + "/" + updatedOn.getFullYear();
var dateNow = new Date();
var fullDateNow = dateNow.getMonth() + "/" + dateNow.getFullYear();
var isSameYearCreated = fullDateNow == fullDateCreated ? true : false;
var isSameYearUpdated = fullDateNow == fullDateUpdated ? true : false;
var daysLimit = dateNow.getDay() - createdOn.getDay();
if (isSameYearCreated || isSameYearUpdated){
return daysLimit <= 7 ? true : false;
}else{
return false;
}
};
const getElement = element =>{
if (element.charAt(0) == "#"){
element = element.replace("#", "");
return document.getElementById(element) != null ? document.getElementById(element) : null;
}else if (element.charAt(0) == "."){
element = element.replace(".", "");
return document.getElementsByClassName(element) != null ? document.getElementsByClassName(element) : null;
}else{
return null;
}
}